Linux EXT4 FS development
 help / color / mirror / Atom feed
* [PATCH v2 2/8] ext4: introduce EXPORT_SYMBOL_FOR_EXT4_TEST() helper
From: Ye Bin @ 2026-03-12 13:12 UTC (permalink / raw)
  To: tytso, adilger.kernel, linux-ext4; +Cc: jack
In-Reply-To: <20260312131253.366296-1-yebin@huaweicloud.com>

From: Ye Bin <yebin10@huawei.com>

Introduce EXPORT_SYMBOL_FOR_EXT4_TEST() helper for kuint test.

Signed-off-by: Ye Bin <yebin10@huawei.com>
---
 fs/ext4/ext4.h    | 5 +++++
 fs/ext4/mballoc.c | 3 ---
 2 files changed, 5 insertions(+), 3 deletions(-)

diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h
index 4cb2345339ba..8bf2a2ac4787 100644
--- a/fs/ext4/ext4.h
+++ b/fs/ext4/ext4.h
@@ -3945,6 +3945,11 @@ static inline bool ext4_inode_can_atomic_write(struct inode *inode)
 extern int ext4_block_write_begin(handle_t *handle, struct folio *folio,
 				  loff_t pos, unsigned len,
 				  get_block_t *get_block);
+
+#if IS_ENABLED(CONFIG_EXT4_KUNIT_TESTS)
+#define EXPORT_SYMBOL_FOR_EXT4_TEST(sym) \
+	EXPORT_SYMBOL_FOR_MODULES(sym, "ext4-test")
+#endif
 #endif	/* __KERNEL__ */
 
 #endif	/* _EXT4_H */
diff --git a/fs/ext4/mballoc.c b/fs/ext4/mballoc.c
index 842a604ae5db..97b3f0e4c80b 100644
--- a/fs/ext4/mballoc.c
+++ b/fs/ext4/mballoc.c
@@ -7193,9 +7193,6 @@ ext4_mballoc_query_range(
 }
 
 #if IS_ENABLED(CONFIG_EXT4_KUNIT_TESTS)
-#define EXPORT_SYMBOL_FOR_EXT4_TEST(sym) \
-	EXPORT_SYMBOL_FOR_MODULES(sym, "ext4-test")
-
 void mb_clear_bits_test(void *bm, int cur, int len)
 {
 	 mb_clear_bits(bm, cur, len);
-- 
2.34.1


^ permalink raw reply related

* [PATCH v2 5/8] ext4: fix miss free super_block in extents_kunit_exit()
From: Ye Bin @ 2026-03-12 13:12 UTC (permalink / raw)
  To: tytso, adilger.kernel, linux-ext4; +Cc: jack
In-Reply-To: <20260312131253.366296-1-yebin@huaweicloud.com>

From: Ye Bin <yebin10@huawei.com>

There's issue as follows:
ODEBUG: free active (active state 0) object: ffff88812f2d68a0 object type: percpu_counter hint: 0x0
 <TASK>
 debug_check_no_obj_freed+0x3d9/0x4d0
 kfree+0x2bb/0x6c0
 extents_kunit_exit+0x65/0x90 [ext4_test]
 kunit_try_run_case_cleanup+0xbc/0x100 [kunit]
 kunit_generic_run_threadfn_adapter+0x89/0x100 [kunit]
 kthread+0x408/0x540
 ret_from_fork+0xa76/0xdf0
 ret_from_fork_asm+0x1a/0x30

The above issue was caused because the super_block cleanup process
was not properly performed.
Therefore, deactivate_super() is called in extents_kunit_exit() to
cleanup the super_block.

Fixes: cb1e0c1d1fad ("ext4: kunit tests for extent splitting and conversion")
Signed-off-by: Ye Bin <yebin10@huawei.com>
---
 fs/ext4/extents-test.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/fs/ext4/extents-test.c b/fs/ext4/extents-test.c
index 5a5016ea1ecc..70d84c0a18e2 100644
--- a/fs/ext4/extents-test.c
+++ b/fs/ext4/extents-test.c
@@ -144,7 +144,7 @@ static void extents_kunit_exit(struct kunit *test)
 {
 	struct ext4_sb_info *sbi = k_ctx.k_ei->vfs_inode.i_sb->s_fs_info;
 
-	kfree(sbi);
+	deactivate_super(sbi->s_sb);
 	kfree(k_ctx.k_ei);
 	kfree(k_ctx.k_data);
 }
-- 
2.34.1


^ permalink raw reply related

* [PATCH v2 4/8] ext4: fix miss unlock 'sb->s_umount' in extents_kunit_init()
From: Ye Bin @ 2026-03-12 13:12 UTC (permalink / raw)
  To: tytso, adilger.kernel, linux-ext4; +Cc: jack
In-Reply-To: <20260312131253.366296-1-yebin@huaweicloud.com>

From: Ye Bin <yebin10@huawei.com>

There's warning as follows when do ext4 kunit test:
WARNING: kunit_try_catch/15923 still has locks held!
7.0.0-rc3-next-20260309-00028-g73f965a1bbb1-dirty #281 Tainted: G            E    N
1 lock held by kunit_try_catch/15923:
 #0: ffff888139f860e0 (&type->s_umount_key#70/1){+.+.}-{4:4}, at: alloc_super.constprop.0+0x172/0xa90
Call Trace:
 <TASK>
 dump_stack_lvl+0x180/0x1b0
 debug_check_no_locks_held+0xc8/0xd0
 do_exit+0x1502/0x2b20
 kthread+0x3a9/0x540
 ret_from_fork+0xa76/0xdf0
 ret_from_fork_asm+0x1a/0x30

As sget() will return 'sb' which holds 's->s_umount' lock. However,
"extents-test" miss unlock this lock.
So unlock 's->s_umount' in the end of extents_kunit_init().

Fixes: cb1e0c1d1fad ("ext4: kunit tests for extent splitting and conversion")
Signed-off-by: Ye Bin <yebin10@huawei.com>
---
 fs/ext4/extents-test.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/fs/ext4/extents-test.c b/fs/ext4/extents-test.c
index 9e055f399167..5a5016ea1ecc 100644
--- a/fs/ext4/extents-test.c
+++ b/fs/ext4/extents-test.c
@@ -307,6 +307,8 @@ static int extents_kunit_init(struct kunit *test)
 	kunit_activate_static_stub(test, ext4_ext_zeroout, ext4_ext_zeroout_stub);
 	kunit_activate_static_stub(test, ext4_issue_zeroout,
 				   ext4_issue_zeroout_stub);
+	up_write(&sb->s_umount);
+
 	return 0;
 }
 
-- 
2.34.1


^ permalink raw reply related

* Re: [PATCH v4 19/25] xfs: remove unwritten extents after preallocations in fsverity metadata
From: Andrey Albershteyn @ 2026-03-12 13:50 UTC (permalink / raw)
  To: Darrick J. Wong
  Cc: Andrey Albershteyn, linux-xfs, fsverity, linux-fsdevel, ebiggers,
	hch, linux-ext4, linux-f2fs-devel, linux-btrfs
In-Reply-To: <20260310012914.GG1105363@frogsfrogsfrogs>

On 2026-03-09 18:29:14, Darrick J. Wong wrote:
> > XFS preallocates spaces during writes. In normal I/O this space, if
> > unused, is removed by truncate. For files with fsverity, XFS does not
> > use truncate as fsverity metadata is stored past EOF.
> > 
> > After we're done with writing fsverity metadata iterate over extents in
> > that region and remove any unwritten ones. These would be preallocation
> > leftovers in the merkle tree holes and past fsverity descriptor.
> > 
> > Signed-off-by: Andrey Albershteyn <aalbersh@kernel.org>
> > ---

> There's an upper limit on the number of blocks you can unmap/free in a
> single transaction.  Maybe move the xfs_trans_{alloc,commit} into the
> loop body?
> 
> Oh wait, you skip the written extents.  Ok, so maybe just roll it after
> you've done a bunmapi.

I see, I will add a rolling transaction. Btw, why skipping the
written extents let's us use rolling here?

> 
> Do you need to purge the cow fork too?

hmm, what case are you thinking about here? The fsverity is written
in past EOF region, I don't see how COW extent could be left there.
Can they somehow be left mapped for blocks past i_size?

-- 
- Andrey


^ permalink raw reply

* Re: [RFC PATCH] ext4: handle wraparound when searching for blocks for indirect mapped blocks
From: Theodore Tso @ 2026-03-12 14:23 UTC (permalink / raw)
  To: Baokun Li; +Cc: Jan Kara, Ext4 Developers List
In-Reply-To: <5ce9dfe2-721e-4d20-9bd9-3560aa76888d@linux.alibaba.com>

On Wed, Mar 11, 2026 at 10:38:20AM +0800, Baokun Li wrote:
> 
> Good spotting! ext4_find_goal() ensures that the goal block obtained for
> indirect-block-based files will not exceed EXT4_MAX_BLOCK_FILE_PHYS.
> However, on an ext4 filesystem where the two file formats are mixed,
> it is indeed possible to get an excessively large goal group via stream
> allocation.

Well, I didn't spot it; an LLM AI noticed.  :-) Arguably I should have
noticed it when doing my review, but I didn't.

> Since the mixed-format case is quite rare, I think we can simply validate
> start in ext4_mb_scan_groups() and reset it to 0 when it exceeds the limit,
> like this:

No, I don't think that's enough.  It's not just that we could have an
excessively large goal group.  The goal group could also just be, say,
2**32 - 5.  If the next 5 groups are full, then when we do an
optimized scan, we will end up beyond the 2**32 limit.  That's why we
need to add some kidn of wraparound logic to *any* caller to
ext4_get_allocation_groups_count().

							- Ted

^ permalink raw reply

* Re: [PATCH v4 19/25] xfs: remove unwritten extents after preallocations in fsverity metadata
From: Darrick J. Wong @ 2026-03-12 14:52 UTC (permalink / raw)
  To: Andrey Albershteyn
  Cc: Andrey Albershteyn, linux-xfs, fsverity, linux-fsdevel, ebiggers,
	hch, linux-ext4, linux-f2fs-devel, linux-btrfs
In-Reply-To: <ymisdrze3ohdnxa4inqfwp4riaz4qk5nmtil33adn5ukhngq7v@f3tcv3hbzobz>

On Thu, Mar 12, 2026 at 02:50:57PM +0100, Andrey Albershteyn wrote:
> On 2026-03-09 18:29:14, Darrick J. Wong wrote:
> > > XFS preallocates spaces during writes. In normal I/O this space, if
> > > unused, is removed by truncate. For files with fsverity, XFS does not
> > > use truncate as fsverity metadata is stored past EOF.
> > > 
> > > After we're done with writing fsverity metadata iterate over extents in
> > > that region and remove any unwritten ones. These would be preallocation
> > > leftovers in the merkle tree holes and past fsverity descriptor.
> > > 
> > > Signed-off-by: Andrey Albershteyn <aalbersh@kernel.org>
> > > ---
> 
> > There's an upper limit on the number of blocks you can unmap/free in a
> > single transaction.  Maybe move the xfs_trans_{alloc,commit} into the
> > loop body?
> > 
> > Oh wait, you skip the written extents.  Ok, so maybe just roll it after
> > you've done a bunmapi.
> 
> I see, I will add a rolling transaction. Btw, why skipping the
> written extents let's us use rolling here?

Hrmm.  At first I thought: why can't xfs_fsverity_cancel_unwritten
allocate (and commit) the transaction inside the loop body?  Then I
thought "well, it's only conditionally unmapping things, and it's sort
of a pain to allocate a transaction only then to find out if you
actually want to run one".

OTOH there could be billions of extents in the data fork, so holding the
ILOCK for that many transactions isn't a good thing because tr_write
only preallocates space for a certain number of transaction rolls.
fsverity already holds IOLOCK_EXCL so there can't be any other programs
using the file.

So now I arrive back at "The transaction allocation and commit/cancel
should be inside the loop body, since crashing midway through wouldn't
result in user-visible changes to the file data".

> > Do you need to purge the cow fork too?
> 
> hmm, what case are you thinking about here? The fsverity is written
> in past EOF region, I don't see how COW extent could be left there.
> Can they somehow be left mapped for blocks past i_size?

I was talking about speculative cow fork preallocations below i_size.
They'll eventually get purged by blockgc, but you could give the space
back once you've committed enabling the fsverity file flag.

--D

^ permalink raw reply

* Re: [PATCH 00/61] treewide: Use IS_ERR_OR_NULL over manual NULL check - refactor
From: James Bottomley @ 2026-03-12 15:32 UTC (permalink / raw)
  To: Jason Gunthorpe, Kuan-Wei Chiu
  Cc: Philipp Hahn, amd-gfx, apparmor, bpf, ceph-devel, cocci, dm-devel,
	dri-devel, gfs2, intel-gfx, intel-wired-lan, iommu, kvm,
	linux-arm-kernel, linux-block, linux-bluetooth, linux-btrfs,
	linux-cifs, linux-clk, linux-erofs, linux-ext4, linux-fsdevel,
	linux-gpio, linux-hyperv, linux-input, linux-kernel, linux-leds,
	linux-media, linux-mips, linux-mm, linux-modules, linux-mtd,
	linux-nfs, linux-omap, linux-phy, linux-pm, linux-rockchip,
	linux-s390, linux-scsi, linux-sctp, linux-security-module,
	linux-sh, linux-sound, linux-stm32, linux-trace-kernel, linux-usb,
	linux-wireless, netdev, ntfs3, samba-technical, sched-ext,
	target-devel, tipc-discussion, v9fs
In-Reply-To: <20260312125730.GI1469476@ziepe.ca>

On Thu, 2026-03-12 at 09:57 -0300, Jason Gunthorpe wrote:
> On Wed, Mar 11, 2026 at 02:40:36AM +0800, Kuan-Wei Chiu wrote:
> 
> > IMHO, the necessity of IS_ERR_OR_NULL() often highlights a
> > confusing or flawed API design. It usually implies that the caller
> > is unsure whether a failure results in an error pointer or a NULL
> > pointer. 
> 
> +1
> 
> IS_ERR_OR_NULL() should always be looked on with suspicion. Very
> little should be returning some tri-state 'ERR' 'NULL' 'SUCCESS'
> pointer. What does the middle condition even mean? IS_ERR_OR_NULL()
> implies ERR and NULL are semanticly the same, so fix the things to
> always use ERR.

Not in any way supporting the original patch.  However, the pattern
ERR, NULL, PTR is used extensively in the dentry code of filesystems. 
See the try_lookup..() set of functions in fs/namei.c

The meaning is

PTR - I found it
NULL - It definitely doesn't exist
ERR - something went wrong during the lookup.

So I don't think you can blanket say this pattern is wrong.

Regards,

James


^ permalink raw reply

* Re: linux-next: build failure after merge of the tip tree
From: Ritesh Harjani @ 2026-03-12 15:43 UTC (permalink / raw)
  To: Mark Brown, Peter Zijlstra
  Cc: Ojaswin Mujoo, Thomas Gleixner, Ingo Molnar, H. Peter Anvin,
	Linux Kernel Mailing List, Linux Next Mailing List, willy,
	yi.zhang, jack, tytso, linux-ext4
In-Reply-To: <0d21783c-5299-4488-9708-def0b1a4dcbe@sirena.org.uk>

Mark Brown <broonie@kernel.org> writes:

> On Wed, Mar 11, 2026 at 05:09:04PM +0100, Peter Zijlstra wrote:
>> On Wed, Mar 11, 2026 at 08:03:50PM +0530, Ojaswin Mujoo wrote:
>> > On Wed, Mar 11, 2026 at 11:37:43AM +0100, Peter Zijlstra wrote:
>
>> > I believe this issue is resolved with [1]. However, I think this might
>> > not be the same as the issue reported originally as we the original
>> > issue seems to be in mballoc-tests rather than extent-tests. I'll try to
>> > look into it a bit more.
>
>> > [1] https://lore.kernel.org/linux-ext4/5bb9041471dab8ce870c191c19cbe4df57473be8.1772381213.git.ritesh.list@gmail.com/
>
>> I can confirm that solves the KASAN splat; it also cures the defconfig
>> hang that was initially mis-attributed to the mutex patch, but turned
>> out to be memory corruption due to that issue KASAN found.
>
>> FWIW:
>
>> Tested-by: Peter Zijlstra (Intel) <peterz@infradead.org> 
>
> Yes, that seems to work for me too - looks like tip just triggers it
> more aggressively for some reason:
>
> Tested-by: Mark Brown <broonie@kernel.org>

Thanks Mark, Peter & Ojaswin for testing.

++linux-ext4 so that if someone observes the same issue in ext4 kunit
tests, they could find this discussion on linux-ext4.

-ritesh

^ permalink raw reply

* Re: [PATCH] ext4: kunit: extents-test: Fix percpu_counters list corruption
From: Mark Brown @ 2026-03-12 15:57 UTC (permalink / raw)
  To: Ritesh Harjani (IBM); +Cc: linux-ext4, Ojaswin Mujoo
In-Reply-To: <5bb9041471dab8ce870c191c19cbe4df57473be8.1772381213.git.ritesh.list@gmail.com>

[-- Attachment #1: Type: text/plain, Size: 523 bytes --]

On Sun, Mar 01, 2026 at 09:44:26PM +0530, Ritesh Harjani (IBM) wrote:
> commit 82f80e2e3b23 ("ext4: add extent status cache support to kunit tests"),
> added ext4_es_register_shrinker() in extents_kunit_init() function but
> failed to add the unregister shrinker routine in extents_kunit_exit().

This is breaking KUnit in -next which is causing problems for other
trees, can we please get it merged promptly?  Discussion here:

   https://lore.kernel.org/r/abJe1PAf4JbwGGRI@li-dc0c254c-257c-11b2-a85c-98b6c1322444.ibm.com

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 488 bytes --]

^ permalink raw reply

* Re: [PATCH 38/61] net: Prefer IS_ERR_OR_NULL over manual NULL check
From: Przemek Kitszel @ 2026-03-12 16:11 UTC (permalink / raw)
  To: Philipp Hahn
  Cc: amd-gfx, apparmor, bpf, ceph-devel, cocci, dm-devel, dri-devel,
	gfs2, intel-gfx, intel-wired-lan, iommu, kvm, linux-arm-kernel,
	linux-block, linux-bluetooth, linux-btrfs, linux-cifs, linux-clk,
	linux-erofs, linux-ext4, linux-fsdevel, linux-gpio, linux-hyperv,
	linux-input, linux-kernel, linux-leds, linux-media, linux-mips,
	linux-mm, linux-modules, linux-mtd, linux-nfs, linux-omap,
	linux-phy, linux-pm, linux-rockchip, linux-s390, linux-scsi,
	linux-sctp, linux-security-module, linux-sh, linux-sound,
	linux-stm32, linux-trace-kernel, linux-usb, linux-wireless,
	netdev, ntfs3, samba-technical, sched-ext, target-devel,
	tipc-discussion, v9fs, Igor Russkikh, Andrew Lunn,
	David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
	Pavan Chebbi, Michael Chan, Potnuri Bharat Teja, Tony Nguyen,
	Taras Chornyi, Maxime Coquelin, Alexandre Torgue,
	Iyappan Subramanian, Keyur Chudgar, Quan Nguyen, Heiner Kallweit,
	Russell King
In-Reply-To: <20260310-b4-is_err_or_null-v1-38-bd63b656022d@avm.de>

On 3/10/26 12:49, Philipp Hahn wrote:
> Prefer using IS_ERR_OR_NULL() over using IS_ERR() and a manual NULL
> check.
> 
> Change generated with coccinelle.
> 
> To: Igor Russkikh <irusskikh@marvell.com>
> To: Andrew Lunn <andrew+netdev@lunn.ch>
> To: "David S. Miller" <davem@davemloft.net>
> To: Eric Dumazet <edumazet@google.com>
> To: Jakub Kicinski <kuba@kernel.org>
> To: Paolo Abeni <pabeni@redhat.com>
> To: Pavan Chebbi <pavan.chebbi@broadcom.com>
> To: Michael Chan <mchan@broadcom.com>
> To: Potnuri Bharat Teja <bharat@chelsio.com>
> To: Tony Nguyen <anthony.l.nguyen@intel.com>
> To: Przemek Kitszel <przemyslaw.kitszel@intel.com>
> To: Taras Chornyi <taras.chornyi@plvision.eu>
> To: Maxime Coquelin <mcoquelin.stm32@gmail.com>
> To: Alexandre Torgue <alexandre.torgue@foss.st.com>
> To: Iyappan Subramanian <iyappan@os.amperecomputing.com>
> To: Keyur Chudgar <keyur@os.amperecomputing.com>
> To: Quan Nguyen <quan@os.amperecomputing.com>
> To: Heiner Kallweit <hkallweit1@gmail.com>
> To: Russell King <linux@armlinux.org.uk>
> Cc: netdev@vger.kernel.org
> Cc: linux-kernel@vger.kernel.org
> Cc: intel-wired-lan@lists.osuosl.org
> Cc: linux-stm32@st-md-mailman.stormreply.com
> Cc: linux-arm-kernel@lists.infradead.org
> Cc: linux-usb@vger.kernel.org
> Signed-off-by: Philipp Hahn <phahn-oss@avm.de>

this is too trivial change, especially when combined like that
https://docs.kernel.org/process/maintainer-netdev.html#clean-up-patches

> ---
>   drivers/net/ethernet/aquantia/atlantic/aq_ring.c        | 2 +-
>   drivers/net/ethernet/broadcom/tg3.c                     | 2 +-
>   drivers/net/ethernet/chelsio/cxgb4/cxgb4_tc_flower.c    | 3 +--
>   drivers/net/ethernet/intel/ice/devlink/devlink.c        | 2 +-
>   drivers/net/ethernet/marvell/prestera/prestera_router.c | 2 +-
>   drivers/net/ethernet/stmicro/stmmac/stmmac_main.c       | 2 +-
>   drivers/net/mdio/mdio-xgene.c                           | 2 +-
>   drivers/net/usb/r8152.c                                 | 2 +-
>   8 files changed, 8 insertions(+), 9 deletions(-)
> 
> diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_ring.c b/drivers/net/ethernet/aquantia/atlantic/aq_ring.c
> index e270327e47fd804cc8ee5cfd53ed1b993c955c41..43edef35c4b1ff606b2f1519a07fad4c9a990ad4 100644
> --- a/drivers/net/ethernet/aquantia/atlantic/aq_ring.c
> +++ b/drivers/net/ethernet/aquantia/atlantic/aq_ring.c
> @@ -810,7 +810,7 @@ static int __aq_ring_xdp_clean(struct aq_ring_s *rx_ring,
>   		}
>   
>   		skb = aq_xdp_run_prog(aq_nic, &xdp, rx_ring, buff);
> -		if (IS_ERR(skb) || !skb)
> +		if (IS_ERR_OR_NULL(skb))
>   			continue;
>   
>   		if (ptp_hwtstamp_len > 0)
> diff --git a/drivers/net/ethernet/broadcom/tg3.c b/drivers/net/ethernet/broadcom/tg3.c
> index 2328fce336447eb4a796f9300ccc0ab536ff0a35..8ed79f34f03d81184dcc12e6eaff009cb8f7756e 100644
> --- a/drivers/net/ethernet/broadcom/tg3.c
> +++ b/drivers/net/ethernet/broadcom/tg3.c
> @@ -7943,7 +7943,7 @@ static int tg3_tso_bug(struct tg3 *tp, struct tg3_napi *tnapi,
>   
>   	segs = skb_gso_segment(skb, tp->dev->features &
>   				    ~(NETIF_F_TSO | NETIF_F_TSO6));
> -	if (IS_ERR(segs) || !segs) {
> +	if (IS_ERR_OR_NULL(segs)) {
>   		tnapi->tx_dropped++;
>   		goto tg3_tso_bug_end;
>   	}
> diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_tc_flower.c b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_tc_flower.c
> index 3307e50426819087ad985178c4a5383f16b8e7b4..1c8a6445d4b2e3535d8f1b7908dd02d8dd2f23fa 100644
> --- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_tc_flower.c
> +++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_tc_flower.c
> @@ -1032,8 +1032,7 @@ static void ch_flower_stats_handler(struct work_struct *work)
>   	do {
>   		rhashtable_walk_start(&iter);
>   
> -		while ((flower_entry = rhashtable_walk_next(&iter)) &&
> -		       !IS_ERR(flower_entry)) {
> +		while (!IS_ERR_OR_NULL((flower_entry = rhashtable_walk_next(&iter)))) {
>   			ret = cxgb4_get_filter_counters(adap->port[0],
>   							flower_entry->filter_id,
>   							&packets, &bytes,
> diff --git a/drivers/net/ethernet/intel/ice/devlink/devlink.c b/drivers/net/ethernet/intel/ice/devlink/devlink.c
> index 6c72bd15db6d75a1d4fa04ef8fefbd26fb6e84bd..3d08b9187fd76ca3198af28111b6f1c1765ea01e 100644
> --- a/drivers/net/ethernet/intel/ice/devlink/devlink.c
> +++ b/drivers/net/ethernet/intel/ice/devlink/devlink.c
> @@ -791,7 +791,7 @@ static void ice_traverse_tx_tree(struct devlink *devlink, struct ice_sched_node
>   						  node->parent->rate_node);
>   	}
>   
> -	if (rate_node && !IS_ERR(rate_node))
> +	if (!IS_ERR_OR_NULL(rate_node))
>   		node->rate_node = rate_node;
>   
>   traverse_children:
> diff --git a/drivers/net/ethernet/marvell/prestera/prestera_router.c b/drivers/net/ethernet/marvell/prestera/prestera_router.c
> index b036b173a308b5f994ad8538eb010fa27196988c..4492938e8a3da91d32efe8d45ccbe2eb437c0e49 100644
> --- a/drivers/net/ethernet/marvell/prestera/prestera_router.c
> +++ b/drivers/net/ethernet/marvell/prestera/prestera_router.c
> @@ -1061,7 +1061,7 @@ static void __prestera_k_arb_hw_state_upd(struct prestera_switch *sw,
>   		n = NULL;
>   	}
>   
> -	if (!IS_ERR(n) && n) {
> +	if (!IS_ERR_OR_NULL(n)) {
>   		neigh_event_send(n, NULL);
>   		neigh_release(n);
>   	} else {
> diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
> index 6827c99bde8c22db42b363d2d36ad6f26075ed50..356a4e9ce04b1fcf8786d7274d31ace404be2cf6 100644
> --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
> +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
> @@ -1275,7 +1275,7 @@ static int stmmac_init_phy(struct net_device *dev)
>   	/* Some DT bindings do not set-up the PHY handle. Let's try to
>   	 * manually parse it
>   	 */
> -	if (!phy_fwnode || IS_ERR(phy_fwnode)) {
> +	if (IS_ERR_OR_NULL(phy_fwnode)) {
>   		int addr = priv->plat->phy_addr;
>   		struct phy_device *phydev;
>   
> diff --git a/drivers/net/mdio/mdio-xgene.c b/drivers/net/mdio/mdio-xgene.c
> index a8f91a4b7fed0927ee14e408000cd3a2bfb9b09a..09b30b563295c6085dc1358ac361301e5cf6b2a8 100644
> --- a/drivers/net/mdio/mdio-xgene.c
> +++ b/drivers/net/mdio/mdio-xgene.c
> @@ -265,7 +265,7 @@ struct phy_device *xgene_enet_phy_register(struct mii_bus *bus, int phy_addr)
>   	struct phy_device *phy_dev;
>   
>   	phy_dev = get_phy_device(bus, phy_addr, false);
> -	if (!phy_dev || IS_ERR(phy_dev))
> +	if (IS_ERR_OR_NULL(phy_dev))
>   		return NULL;
>   
>   	if (phy_device_register(phy_dev))
> diff --git a/drivers/net/usb/r8152.c b/drivers/net/usb/r8152.c
> index 0c83bbbea2e7c322ee6339893e281237663bd3ae..73f17ebd7d40007eec5004f887a46249defd28ab 100644
> --- a/drivers/net/usb/r8152.c
> +++ b/drivers/net/usb/r8152.c
> @@ -2218,7 +2218,7 @@ static void r8152_csum_workaround(struct r8152 *tp, struct sk_buff *skb,
>   
>   		features &= ~(NETIF_F_SG | NETIF_F_IPV6_CSUM | NETIF_F_TSO6);
>   		segs = skb_gso_segment(skb, features);
> -		if (IS_ERR(segs) || !segs)
> +		if (IS_ERR_OR_NULL(segs))
>   			goto drop;
>   
>   		__skb_queue_head_init(&seg_list);
> 


^ permalink raw reply

* Re: [PATCH 00/61] treewide: Use IS_ERR_OR_NULL over manual NULL check - refactor
From: Jason Gunthorpe @ 2026-03-12 16:54 UTC (permalink / raw)
  To: James Bottomley
  Cc: Kuan-Wei Chiu, Philipp Hahn, amd-gfx, apparmor, bpf, ceph-devel,
	cocci, dm-devel, dri-devel, gfs2, intel-gfx, intel-wired-lan,
	iommu, kvm, linux-arm-kernel, linux-block, linux-bluetooth,
	linux-btrfs, linux-cifs, linux-clk, linux-erofs, linux-ext4,
	linux-fsdevel, linux-gpio, linux-hyperv, linux-input,
	linux-kernel, linux-leds, linux-media, linux-mips, linux-mm,
	linux-modules, linux-mtd, linux-nfs, linux-omap, linux-phy,
	linux-pm, linux-rockchip, linux-s390, linux-scsi, linux-sctp,
	linux-security-module, linux-sh, linux-sound, linux-stm32,
	linux-trace-kernel, linux-usb, linux-wireless, netdev, ntfs3,
	samba-technical, sched-ext, target-devel, tipc-discussion, v9fs
In-Reply-To: <f5688b895eaebabae6545a0d9baf8f1404e8454e.camel@HansenPartnership.com>

On Thu, Mar 12, 2026 at 11:32:37AM -0400, James Bottomley wrote:
> On Thu, 2026-03-12 at 09:57 -0300, Jason Gunthorpe wrote:
> > On Wed, Mar 11, 2026 at 02:40:36AM +0800, Kuan-Wei Chiu wrote:
> > 
> > > IMHO, the necessity of IS_ERR_OR_NULL() often highlights a
> > > confusing or flawed API design. It usually implies that the caller
> > > is unsure whether a failure results in an error pointer or a NULL
> > > pointer. 
> > 
> > +1
> > 
> > IS_ERR_OR_NULL() should always be looked on with suspicion. Very
> > little should be returning some tri-state 'ERR' 'NULL' 'SUCCESS'
> > pointer. What does the middle condition even mean? IS_ERR_OR_NULL()
> > implies ERR and NULL are semanticly the same, so fix the things to
> > always use ERR.
> 
> Not in any way supporting the original patch.  However, the pattern
> ERR, NULL, PTR is used extensively in the dentry code of filesystems. 
> See the try_lookup..() set of functions in fs/namei.c
> 
> The meaning is
> 
> PTR - I found it
> NULL - It definitely doesn't exist
> ERR - something went wrong during the lookup.
> 
> So I don't think you can blanket say this pattern is wrong.

Lots of places also would return ENOENT, I'd argue that is easier to
use..

But yes, I did use the word "suspicion" not blanket wrong :)

Jason

^ permalink raw reply

* Re: [syzbot] [ext4?] kernel BUG in ext4_es_cache_extent (4)
From: Ojaswin Mujoo @ 2026-03-12 17:45 UTC (permalink / raw)
  To: syzbot; +Cc: adilger.kernel, linux-ext4, linux-kernel, syzkaller-bugs, tytso
In-Reply-To: <69a73447.a70a0220.b118c.0012.GAE@google.com>

[-- Attachment #1: Type: text/plain, Size: 1292 bytes --]

On Tue, Mar 03, 2026 at 11:19:35AM -0800, syzbot wrote:
> syzbot has found a reproducer for the following issue on:
> 
> HEAD commit:    af4e9ef3d784 uaccess: Fix scoped_user_read_access() for 'p..
> git tree:       upstream
> console output: https://syzkaller.appspot.com/x/log.txt?x=13811b5a580000
> kernel config:  https://syzkaller.appspot.com/x/.config?x=779072223d02a312
> dashboard link: https://syzkaller.appspot.com/bug?extid=ccf1421545dbe5caa20c
> compiler:       Debian clang version 21.1.8 (++20251221033036+2078da43e25a-1~exp1~20251221153213.50), Debian LLD 21.1.8
> syz repro:      https://syzkaller.appspot.com/x/repro.syz?x=1620e552580000
> C reproducer:   https://syzkaller.appspot.com/x/repro.c?x=13810a02580000
> 
> Downloadable assets:
> disk image: https://storage.googleapis.com/syzbot-assets/f6b75c8f432f/disk-af4e9ef3.raw.xz
> vmlinux: https://storage.googleapis.com/syzbot-assets/4513ad566789/vmlinux-af4e9ef3.xz
> kernel image: https://storage.googleapis.com/syzbot-assets/f7eea878db42/bzImage-af4e9ef3.xz
> mounted in repro: https://storage.googleapis.com/syzbot-assets/8d81a7f0b7b8/mount_0.gz
>   fsck result: failed (log: https://syzkaller.appspot.com/x/fsck.log?x=1351b006580000)
> 

#syz test: https://git.kernel.org/pub/scm/linux/kernel/git/tytso/ext4.git dev

[-- Attachment #2: 2-0001-ext4-add-logging-to-debug-issue.patch --]
[-- Type: text/plain, Size: 6594 bytes --]

From 7086e36d23ddbee429c3f0ca271f7e188f81bd61 Mon Sep 17 00:00:00 2001
From: Ojaswin Mujoo <ojaswin@linux.ibm.com>
Date: Tue, 10 Feb 2026 17:59:17 +0530
Subject: [PATCH] ext4: add logging to debug issue

---
 fs/ext4/extents.c        | 28 ++++++++++++++++++++++++++++
 fs/ext4/extents_status.c | 20 ++++++++++++++++++++
 fs/ext4/mballoc.c        | 27 +++++++++++++++++++++++++++
 3 files changed, 75 insertions(+)

diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c
index 3630b27e4fd7..89a681f6e5ca 100644
--- a/fs/ext4/extents.c
+++ b/fs/ext4/extents.c
@@ -529,6 +529,7 @@ static void ext4_cache_extents(struct inode *inode,
 	int i;
 
 	KUNIT_STATIC_STUB_REDIRECT(ext4_cache_extents, inode, eh);
+	ext4_warning_inode(inode, "%s: caching extents\n", __func__);
 
 	for (i = le16_to_cpu(eh->eh_entries); i > 0; i--, ex++) {
 		unsigned int status = EXTENT_STATUS_WRITTEN;
@@ -2006,6 +2007,22 @@ ext4_ext_insert_extent(handle_t *handle, struct inode *inode,
 		goto errout;
 	}
 
+	ext4_warning_inode(
+		inode,
+		"%s: add newext [%u, %u, %llu, unwrit:%d] to extent tree.\n",
+		__func__, le32_to_cpu(newext->ee_block),
+		ext4_ext_get_actual_len(newext), ext4_ext_pblock(newext),
+		ext4_ext_is_unwritten(newext));
+
+	if (ex) {
+		ext4_warning_inode(
+			inode,
+			"%s: ext at current path: [%u, %u, %llu, unwrit:%d]\n",
+			__func__, le32_to_cpu(ex->ee_block),
+			ext4_ext_get_actual_len(ex), ext4_ext_pblock(ex),
+			ext4_ext_is_unwritten(ex));
+	}
+
 	/* try to insert block into found extent and return */
 	if (ex && !(gb_flags & EXT4_GET_BLOCKS_SPLIT_NOMERGE)) {
 
@@ -2832,6 +2849,11 @@ int ext4_ext_remove_space(struct inode *inode, ext4_lblk_t start,
 	int i = 0, err = 0;
 	int flags = EXT4_EX_NOCACHE | EXT4_EX_NOFAIL;
 
+	ext4_warning_inode(
+		inode,
+		"%s: remove range [%u, %u] from extent tree\n",
+		__func__, start, end);
+
 	partial.pclu = 0;
 	partial.lblk = 0;
 	partial.state = initial;
@@ -4456,6 +4478,12 @@ int ext4_ext_map_blocks(handle_t *handle, struct inode *inode,
 		map->m_flags |= EXT4_MAP_UNWRITTEN;
 	}
 
+	ext4_warning_inode(
+		inode,
+		"%s: add newext [%u, %u, %llu, unwrit:%d] to extent tree.\n",
+		__func__, le32_to_cpu(newex.ee_block),
+		ext4_ext_get_actual_len(&newex), ext4_ext_pblock(&newex),
+		ext4_ext_is_unwritten(&newex));
 	path = ext4_ext_insert_extent(handle, inode, path, &newex, flags);
 	if (IS_ERR(path)) {
 		err = PTR_ERR(path);
diff --git a/fs/ext4/extents_status.c b/fs/ext4/extents_status.c
index a1538bac51c6..009c22108a7f 100644
--- a/fs/ext4/extents_status.c
+++ b/fs/ext4/extents_status.c
@@ -847,6 +847,10 @@ static int __es_insert_extent(struct inode *inode, struct extent_status *newes,
 	struct rb_node *parent = NULL;
 	struct extent_status *es;
 
+	ext4_warning_inode(inode, "%s: add lblk:%u len:%u pblk:%llu status:0x%x]\n", __func__,
+			   newes->es_lblk, newes->es_len, ext4_es_pblock(newes),
+			   ext4_es_status(newes));
+
 	while (*p) {
 		parent = *p;
 		es = rb_entry(parent, struct extent_status, rb_node);
@@ -921,6 +925,10 @@ void ext4_es_insert_extent(struct inode *inode, ext4_lblk_t lblk,
 
 	es_debug("add [%u/%u) %llu %x %d to extent status tree of inode %lu\n",
 		 lblk, len, pblk, status, delalloc_reserve_used, inode->i_ino);
+	ext4_warning_inode(
+		inode,
+		"%s: add lblk:%u len:%u pblk:%llu 0x%x to es\n",
+		__func__, lblk, len, pblk, status);
 
 	if (!len)
 		return;
@@ -1031,6 +1039,11 @@ void ext4_es_cache_extent(struct inode *inode, ext4_lblk_t lblk,
 	bool conflict = false;
 	int err;
 
+	ext4_warning_inode(
+		inode,
+		"%s: cache extent lblk:%u len:%u pblk:%llu status:0x%x\n",
+		__func__, lblk, len, pblk, status);
+
 	if (EXT4_SB(inode->i_sb)->s_mount_state & EXT4_FC_REPLAY)
 		return;
 
@@ -1493,6 +1506,11 @@ static int __es_remove_extent(struct inode *inode, ext4_lblk_t lblk,
 	bool count_reserved = true;
 	struct rsvd_count rc;
 
+	ext4_warning_inode(
+		inode,
+		"%s: remove [%u,%u] range from extent status tree of inode %lu\n",
+		__func__, lblk, end, inode->i_ino);
+
 	if (reserved == NULL || !test_opt(inode->i_sb, DELALLOC))
 		count_reserved = false;
 	if (status == 0)
@@ -1633,6 +1651,8 @@ void ext4_es_remove_extent(struct inode *inode, ext4_lblk_t lblk,
 
 	es_debug("remove [%u/%u) from extent status tree of inode %lu\n",
 		 lblk, len, inode->i_ino);
+	ext4_warning_inode(inode, "%s: remove lblk:%u len:%u from es\n",
+			   __func__, lblk, len);
 
 	if (!len)
 		return;
diff --git a/fs/ext4/mballoc.c b/fs/ext4/mballoc.c
index dbc82b65f810..a37d6e3e004d 100644
--- a/fs/ext4/mballoc.c
+++ b/fs/ext4/mballoc.c
@@ -2004,6 +2004,18 @@ static void mb_free_blocks(struct inode *inode, struct ext4_buddy *e4b,
 	int last = first + count - 1;
 	struct super_block *sb = e4b->bd_sb;
 
+	ext4_fsblk_t pblk =
+		ext4_group_first_block_no(e4b->bd_sb, e4b->bd_group) +
+		(first << EXT4_SB(e4b->bd_sb)->s_cluster_bits);
+
+	if (inode)
+		ext4_warning_inode(inode, "%s: trying to free pblk:%llu count:%d\n",
+				__func__, pblk, count);
+	else
+		ext4_warning(sb, "%s: trying to free pblk:%llu count:%d\n",
+				__func__, pblk, count);
+
+
 	if (WARN_ON(count == 0))
 		return;
 	BUG_ON(last >= (sb->s_blocksize << 3));
@@ -3101,6 +3113,12 @@ ext4_mb_regular_allocator(struct ext4_allocation_context *ac)
 	if (!err && ac->ac_status != AC_STATUS_FOUND && ac->ac_first_err)
 		err = ac->ac_first_err;
 
+	ext4_warning_inode(
+		ac->ac_inode,
+		"%s: Best len %d, origin len %d, ac_status %u, ac_flags 0x%x, cr %d ret %d\n",
+		__func__, ac->ac_b_ex.fe_len, ac->ac_o_ex.fe_len, ac->ac_status,
+		ac->ac_flags, ac->ac_criteria, err);
+
 	mb_debug(sb, "Best len %d, origin len %d, ac_status %u, ac_flags 0x%x, cr %d ret %d\n",
 		 ac->ac_b_ex.fe_len, ac->ac_o_ex.fe_len, ac->ac_status,
 		 ac->ac_flags, ac->ac_criteria, err);
@@ -6251,6 +6269,10 @@ ext4_fsblk_t ext4_mb_new_blocks(handle_t *handle,
 	sb = ar->inode->i_sb;
 	sbi = EXT4_SB(sb);
 
+	ext4_warning_inode(ar->inode,
+			   "%s: Allocation requested for: lblk:%u len:%d\n",
+			   __func__, ar->logical, ar->len);
+
 	trace_ext4_request_blocks(ar);
 	if (sbi->s_mount_state & EXT4_FC_REPLAY)
 		return ext4_mb_new_blocks_simple(ar, errp);
@@ -6334,6 +6356,11 @@ ext4_fsblk_t ext4_mb_new_blocks(handle_t *handle,
 			ext4_mb_pa_put_free(ac);
 	}
 	if (likely(ac->ac_status == AC_STATUS_FOUND)) {
+		ext4_warning_inode(
+			ar->inode,
+			"%s: Allocation found: lblk:%u, len:%d, pblk:%llu\n",
+			__func__, ar->logical, ac->ac_b_ex.fe_len,
+			ext4_grp_offs_to_block(sb, &ac->ac_b_ex));
 		*errp = ext4_mb_mark_diskspace_used(ac, handle);
 		if (*errp) {
 			ext4_discard_allocated_blocks(ac);
-- 
2.52.0


^ permalink raw reply related

* Re: [syzbot] [ext4?] kernel BUG in ext4_es_cache_extent (4)
From: syzbot @ 2026-03-12 18:05 UTC (permalink / raw)
  To: adilger.kernel, linux-ext4, linux-kernel, ojaswin, syzkaller-bugs,
	tytso
In-Reply-To: <abL7zFZvQv9yddtu@li-dc0c254c-257c-11b2-a85c-98b6c1322444.ibm.com>

Hello,

syzbot has tested the proposed patch but the reproducer is still triggering an issue:
kernel BUG in ext4_es_cache_extent

EXT4-fs warning (device loop0): ext4_mb_new_blocks:6274: inode #15: comm syz.0.55: ext4_mb_new_blocks: Allocation requested for: lblk:0 len:1
EXT4-fs warning (device loop0): ext4_mb_regular_allocator:3120: inode #15: comm syz.0.55: ext4_mb_regular_allocator: Best len 1, origin len 1, ac_status 2, ac_flags 0xa0, cr 5 ret 0
------------[ cut here ]------------
kernel BUG at fs/ext4/extents_status.c:1057!
Oops: invalid opcode: 0000 [#1] SMP KASAN NOPTI
CPU: 1 UID: 0 PID: 6693 Comm: syz.0.55 Not tainted syzkaller #0 PREEMPT(full) 
Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 02/27/2026
RIP: 0010:ext4_es_cache_extent+0x8eb/0xa10 fs/ext4/extents_status.c:1057
Code: e1 07 80 c1 03 38 c1 0f 8c 51 fe ff ff 48 8b 7c 24 18 e8 f8 54 af ff e9 42 fe ff ff e8 ee 19 47 ff 90 0f 0b e8 e6 19 47 ff 90 <0f> 0b 65 8b 1d 70 7b 6e 10 bf 07 00 00 00 89 de e8 10 1e 47 ff 83
RSP: 0018:ffffc900041aec20 EFLAGS: 00010293
RAX: ffffffff827d24ba RBX: 0000000000000060 RCX: ffff88802d9f3d00
RDX: 0000000000000000 RSI: 0000000000000064 RDI: 0000000000000060
RBP: ffffc900041aed80 R08: ffff88807eaeca47 R09: 1ffff1100fd5d948
R10: dffffc0000000000 R11: ffffed100fd5d949 R12: 0000000000000008
R13: dffffc0000000000 R14: 000000000000000f R15: 0000000000000064
FS:  00007fca40bd36c0(0000) GS:ffff888125866000(0000) knlGS:0000000000000000
CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
CR2: 0000200000011000 CR3: 000000007715a000 CR4: 0000000000350ef0
Call Trace:
 <TASK>
 ext4_cache_extents+0x143/0x2f0 fs/ext4/extents.c:540
 __read_extent_tree_block+0x3b8/0x580 fs/ext4/extents.c:587
 ext4_find_extent+0x5bb/0xa20 fs/ext4/extents.c:942
 ext4_ext_map_blocks+0x27a/0x5730 fs/ext4/extents.c:4285
 ext4_map_query_blocks+0x13b/0xa00 fs/ext4/inode.c:553
 ext4_map_blocks+0x444/0x11d0 fs/ext4/inode.c:771
 _ext4_get_block+0x1e3/0x470 fs/ext4/inode.c:909
 ext4_get_block_unwritten+0x2e/0x100 fs/ext4/inode.c:942
 ext4_block_write_begin+0xb14/0x1950 fs/ext4/inode.c:1196
 ext4_write_begin+0xb40/0x1870 fs/ext4/ext4_jbd2.h:-1
 ext4_da_write_begin+0x355/0xd30 fs/ext4/inode.c:3123
 generic_perform_write+0x2e2/0x8f0 mm/filemap.c:4314
 ext4_buffered_write_iter+0xce/0x3a0 fs/ext4/file.c:299
 ext4_file_write_iter+0x298/0x1bf0 fs/ext4/file.c:-1
 new_sync_write fs/read_write.c:593 [inline]
 vfs_write+0x61d/0xb90 fs/read_write.c:686
 ksys_pwrite64 fs/read_write.c:793 [inline]
 __do_sys_pwrite64 fs/read_write.c:801 [inline]
 __se_sys_pwrite64 fs/read_write.c:798 [inline]
 __x64_sys_pwrite64+0x199/0x230 fs/read_write.c:798
 do_syscall_x64 arch/x86/entry/syscall_64.c:63 [inline]
 do_syscall_64+0xe2/0xf80 arch/x86/entry/syscall_64.c:94
 entry_SYSCALL_64_after_hwframe+0x77/0x7f
RIP: 0033:0x7fca3fd9c799
Code: ff c3 66 2e 0f 1f 84 00 00 00 00 00 0f 1f 44 00 00 48 89 f8 48 89 f7 48 89 d6 48 89 ca 4d 89 c2 4d 89 c8 4c 8b 4c 24 08 0f 05 <48> 3d 01 f0 ff ff 73 01 c3 48 c7 c1 e8 ff ff ff f7 d8 64 89 01 48
RSP: 002b:00007fca40bd3028 EFLAGS: 00000246 ORIG_RAX: 0000000000000012
RAX: ffffffffffffffda RBX: 00007fca40016090 RCX: 00007fca3fd9c799
RDX: 00000000200000c1 RSI: 00002000000000c0 RDI: 0000000000000006
RBP: 00007fca3fe32bd9 R08: 0000000000000000 R09: 0000000000000000
R10: 0000000000009000 R11: 0000000000000246 R12: 0000000000000000
R13: 00007fca40016128 R14: 00007fca40016090 R15: 00007ffe8193e178
 </TASK>
Modules linked in:
---[ end trace 0000000000000000 ]---
RIP: 0010:ext4_es_cache_extent+0x8eb/0xa10 fs/ext4/extents_status.c:1057
Code: e1 07 80 c1 03 38 c1 0f 8c 51 fe ff ff 48 8b 7c 24 18 e8 f8 54 af ff e9 42 fe ff ff e8 ee 19 47 ff 90 0f 0b e8 e6 19 47 ff 90 <0f> 0b 65 8b 1d 70 7b 6e 10 bf 07 00 00 00 89 de e8 10 1e 47 ff 83
RSP: 0018:ffffc900041aec20 EFLAGS: 00010293
RAX: ffffffff827d24ba RBX: 0000000000000060 RCX: ffff88802d9f3d00
RDX: 0000000000000000 RSI: 0000000000000064 RDI: 0000000000000060
RBP: ffffc900041aed80 R08: ffff88807eaeca47 R09: 1ffff1100fd5d948
R10: dffffc0000000000 R11: ffffed100fd5d949 R12: 0000000000000008
R13: dffffc0000000000 R14: 000000000000000f R15: 0000000000000064
FS:  00007fca40bd36c0(0000) GS:ffff888125866000(0000) knlGS:0000000000000000
CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
CR2: 0000200000011000 CR3: 000000007715a000 CR4: 0000000000350ef0


Tested on:

commit:         4f5e8e6f et4: allow zeroout when doing written to unwr..
git tree:       https://git.kernel.org/pub/scm/linux/kernel/git/tytso/ext4.git dev
console output: https://syzkaller.appspot.com/x/log.txt?x=1236cd52580000
kernel config:  https://syzkaller.appspot.com/x/.config?x=a535ad5429f72a2
dashboard link: https://syzkaller.appspot.com/bug?extid=ccf1421545dbe5caa20c
compiler:       Debian clang version 21.1.8 (++20251221033036+2078da43e25a-1~exp1~20251221153213.50), Debian LLD 21.1.8
patch:          https://syzkaller.appspot.com/x/patch.diff?x=1696cd52580000


^ permalink raw reply

* Re: [PATCH 48/61] mtd: Prefer IS_ERR_OR_NULL over manual NULL check
From: Richard Weinberger @ 2026-03-12 19:33 UTC (permalink / raw)
  To: Philipp Hahn
  Cc: amd-gfx, apparmor, bpf, ceph-devel, cocci, dm-devel,
	DRI mailing list, gfs2, intel-gfx, intel-wired-lan, iommu, kvm,
	linux-arm-kernel, linux-block, linux-bluetooth, linux-btrfs,
	linux-cifs, linux-clk, linux-erofs, linux-ext4, linux-fsdevel,
	linux-gpio, linux-hyperv, linux-input, linux-kernel, linux-leds,
	linux-media, linux-mips, linux-mm, linux-modules, linux-mtd,
	linux-nfs, linux-omap, linux-phy, linux-pm, linux-rockchip,
	linux-s390, linux-scsi, linux-sctp, LSM, linux-sh, linux-sound,
	linux-stm32, linux-trace-kernel, linux-usb, linux-wireless,
	netdev, ntfs3, samba-technical, sched-ext, target-devel,
	tipc-discussion, v9fs, Miquel Raynal, Vignesh Raghavendra
In-Reply-To: <20260310-b4-is_err_or_null-v1-48-bd63b656022d@avm.de>

----- Ursprüngliche Mail -----
> Von: "Philipp Hahn" <phahn-oss@avm.de>
> -	if (gpiomtd->nwp && !IS_ERR(gpiomtd->nwp))
> +	if (!IS_ERR_OR_NULL(gpiomtd->nwp))

No, please don't.

This makes reading the code not easier.

Thanks,
//richard

^ permalink raw reply

* [PULLBOMB v2 1.48] fuse2fs: new features, new server
From: Darrick J. Wong @ 2026-03-12 20:57 UTC (permalink / raw)
  To: Theodore Ts'o; +Cc: linux-ext4, amir73il

Hi Ted,

As promised, this large patchbomb contains all the improvements that I'd
like to make to fuse2fs before integrating iomap.  Major new features
include:

 - Fix locking of the block device (or image file) to prevent multiple
   fuse2fs instances.
 - Initializing the htree index in a growing directory so that directory
   lookups aren't horrifyingly slow.
 - Implementing MMP for cluster support.
 - Use file handles to reduce directory path lookups.
 - Implement directory seeking, readdir plus (the fuse version), and
   dirsync.
 - Fix differences in nlink overflow handling vs the kernel.
 - Cache symlinks when possible.
 - Refactor startup and shutdown to reduce main() complexity.
 - Add tracing for file operations.
 - Add the shutdown ioctl for better recovery testing.
 - Drop fuse 2.xx support.

At the end of this series, I create a new fuse ext* server (fuse4fs)
which uses the lowlevel FUSE API instead of the high level one.  The
major advantage of using the lowlevel API is that all file operations
are performed in terms of inodes instead of paths.  As a result, fuse4fs
has MUCH less overhead than fuse2fs because we avoid the overhead of
having libfuse translate inode numbers to paths only to have fuse2fs
translate paths back into inode numbers.

Obviously, this stuff should go into e2fsprogs 1.48, not a 1.47.x stable
release.  This patchbomb hasn't changed much since its last posting on
6 Nov 2025.  The range-diff between then and now is appended below;
changes include:

 * Don't purge pagecache when opening a file

 * Cache dirents from readdir contents to speed up directory tree ops

 * Disable rw mode for bigalloc filesystems due to many bugs in the
   extent tree punch code for implied cluster deallocation

As we discussed in the ext4 call this morning, I'm sending you pull
requests to initiate review, instead of hammering the list with ~70
patches.

--D

 1:  bcc1485fc77acc !  1:  44ce8e421929b5 libext2fs: add POSIX advisory locking to the unix IO manager
    @@ lib/ext2fs/ext2_io.h: extern errcode_t io_channel_zeroout(io_channel channel,
      #ifdef _WIN32
      /* windows_io.c */
      extern io_manager windows_io_manager;
      #define default_io_manager windows_io_manager
      #else
     
    - ## debian/libext2fs2.symbols ##
    -@@ debian/libext2fs2.symbols: libext2fs.so.2 libext2fs2 #MINVER#
    + ## debian/libext2fs2t64.symbols ##
    +@@ debian/libext2fs2t64.symbols: libext2fs.so.2 libext2fs2t64 #MINVER#
       initialize_ext2_error_table@Base 1.37
       initialize_ext2_error_table_r@Base 1.37
       inode_io_manager@Base 1.37
       io_channel_alloc_buf@Base 1.42.3
       io_channel_cache_readahead@Base 1.43
       io_channel_discard@Base 1.42
 2:  264facf1b0d183 =  2:  e9dad24e491754 fuse2fs: try to lock filesystem image files before using them
 3:  f0a723fa339d8b =  3:  82fd502239e8cc fuse2fs: quiet down write-protect warning
 4:  79bafc32b10284 =  4:  b22ae270a1016c fuse2fs: try to grab block device O_EXCL repeatedly
 5:  99d557bab152ca =  5:  f3c5e16bc36c9e libext2fs: initialize htree when expanding directory
 6:  7b80e2c803cb49 !  6:  875fe146da5295 libext2fs: create link count adjustment helpers for dir_nlink
    @@ lib/ext2fs/ext2fs.h: extern errcode_t ext2fs_get_pathname(ext2_filsys fs, ext2_i
      /* symlink.c */
      errcode_t ext2fs_symlink(ext2_filsys fs, ext2_ino_t parent, ext2_ino_t ino,
      			 const char *name, const char *target);
      int ext2fs_is_fast_symlink(struct ext2_inode *inode);
      
     
    - ## debian/libext2fs2.symbols ##
    -@@ debian/libext2fs2.symbols: libext2fs.so.2 libext2fs2 #MINVER#
    + ## debian/libext2fs2t64.symbols ##
    +@@ debian/libext2fs2t64.symbols: libext2fs.so.2 libext2fs2t64 #MINVER#
       ext2fs_dblist_get_last@Base 1.40.8
       ext2fs_dblist_iterate2@Base 1.42
       ext2fs_dblist_iterate3@Base 1.43
       ext2fs_dblist_iterate@Base 1.37
       ext2fs_dblist_sort2@Base 1.42
       ext2fs_dblist_sort@Base 1.37
    @@ debian/libext2fs2.symbols: libext2fs.so.2 libext2fs2 #MINVER#
       ext2fs_dirent_csum_verify@Base 1.43
       ext2fs_dirent_file_type@Base 1.43
       ext2fs_dirent_has_tail@Base 1.43
       ext2fs_dirent_name_len@Base 1.43
       ext2fs_dirent_set_file_type@Base 1.43
       ext2fs_dirent_set_name_len@Base 1.43
    -@@ debian/libext2fs2.symbols: libext2fs.so.2 libext2fs2 #MINVER#
    +@@ debian/libext2fs2t64.symbols: libext2fs.so.2 libext2fs2t64 #MINVER#
       ext2fs_image_bitmap_read@Base 1.37
       ext2fs_image_bitmap_write@Base 1.37
       ext2fs_image_inode_read@Base 1.37
       ext2fs_image_inode_write@Base 1.37
       ext2fs_image_super_read@Base 1.37
       ext2fs_image_super_write@Base 1.37
 7:  c7a7b06d18564f =  7:  7feaab70961cb8 libext2fs: fix ext2fs_mmp_update
 8:  d07d6905ab25a4 !  8:  f314bc313c42dd libext2fs: refactor aligned MMP buffer allocation
    @@ lib/ext2fs/ext2fs.h: errcode_t ext2fs_mmp_clear(ext2_filsys fs);
      /* read_bb.c */
      extern errcode_t ext2fs_read_bb_inode(ext2_filsys fs,
      				      ext2_badblocks_list *bb_list);
      
      /* read_bb_file.c */
     
    - ## debian/libext2fs2.symbols ##
    -@@ debian/libext2fs2.symbols: libext2fs.so.2 libext2fs2 #MINVER#
    + ## debian/libext2fs2t64.symbols ##
    +@@ debian/libext2fs2t64.symbols: libext2fs.so.2 libext2fs2t64 #MINVER#
       ext2fs_mem_is_zero@Base 1.42
       ext2fs_mkdir2@Base 1.47.3~rc1
       ext2fs_mkdir@Base 1.37
       ext2fs_mmp_clear@Base 1.42
       ext2fs_mmp_csum_set@Base 1.43
       ext2fs_mmp_csum_verify@Base 1.43
 9:  9195f58a6cdb5a =  9:  ee84dbe7a9514e libext2fs: always use ext2fs_mmp_get_mem to allocate fs->mmp_buf
 -:  -------------- > 10:  afa1dbf0d36c71 fuse2fs: disable write access when cluster size > block size
 -:  -------------- > 11:  c5aea20cdc9bcf fuse2fs: enable more caching
10:  5e53170f5006b9 = 12:  128e4060e8f7cb fuse2fs: check root directory while mounting
11:  6fb5993b8f8e67 = 13:  af6da8a2f69768 fuse2fs: read bitmaps asynchronously during initialization
12:  d4e650b532df8f = 14:  aed6d1da1fa27e fuse2fs: use file handles when possible
13:  e6f47498d1b230 = 15:  10ec1962b5cce3 fuse2fs: implement dir seeking
14:  9efce340aa14ce = 16:  bf5daa34c6e1dd fuse2fs: implement readdirplus
15:  96bea8a553ef1e = 17:  8e09e6bb49baf2 fuse2fs: implement dirsync mode
16:  a9db4be25ceeba = 18:  45651efd6db7da fuse2fs: only flush O_SYNC files on close
17:  85dd57210496bf = 19:  b725c9a9e5786e fuse2fs: improve want_extra_isize handling
18:  6ec67afffee30a = 20:  b0bd58062bbf64 fuse2fs: cache symlink targets in the kernel
19:  60c6cbeab89382 = 21:  d485cf2972ac6e fuse2fs: constrain worker thread count
20:  17deed32e9410c = 22:  3010930102a352 fuse2fs: improve error handling behaviors
21:  e6758bfae61f95 = 23:  ff0bc6e2385fd0 fuse2fs: fix link count overflows on dir_nlink filesystems
22:  9bf264d29e2c45 ! 24:  a381f38cac203d libsupport: add background thread manager
    @@ Commit message
     
      ## lib/support/bthread.h (new) ##
     @@
     +/*
     + * bthread.h - Background thread manager
     + *
    -+ * Copyright (C) 2025 Oracle.
    ++ * Copyright (C) 2025-2026 Oracle.
     + *
     + * %Begin-Header%
     + * This file may be redistributed under the terms of the GNU Public
     + * License.
     + * %End-Header%
     + */
    @@ lib/support/Makefile.in: $(OBJS):
     
      ## lib/support/bthread.c (new) ##
     @@
     +/*
     + * bthread.c - Background thread manager
     + *
    -+ * Copyright (C) 2025 Oracle.
    ++ * Copyright (C) 2025-2026 Oracle.
     + *
     + * %Begin-Header%
     + * This file may be redistributed under the terms of the GNU Public
     + * License.
     + * %End-Header%
     + */
23:  0227370767f5a0 = 25:  a4fc4817e3072c fuse2fs: implement MMP updates
24:  deb1ee6f9121cb = 26:  ff8cf11cc27f77 fuse2fs: rework FUSE2FS_CHECK_CONTEXT not to rely on global_fs
25:  245b3b30d8bbd9 = 27:  81e273f16cd965 fuse2fs: rework checking file handles
26:  364f8e7b9cf55c = 28:  6347b122e30a89 fuse2fs: rework fallocate file handle extraction
27:  d3d25033d3e0df = 29:  5eb98f914a0bc3 fuse2fs: consolidate file handle checking in op_ioctl
28:  0a7cd8ae2c3303 = 30:  88ee26a59290bb fuse2fs: move fs assignment closer to locking the bfl
29:  ac2c12db4635ea = 31:  620f236eaf0281 fuse2fs: clean up operation startup
30:  947debc109b8d2 = 32:  a95a1577d15074 fuse2fs: clean up operation completion
31:  1f6402ed4f8cc3 ! 33:  849857563a87d0 fuse2fs: clean up more boilerplate
    @@ misc/fuse2fs.c: static int __op_open(struct fuse2fs *ff, const char *path,
      	}
      
      	file->check_flags = check;
     -	fp->fh = (uintptr_t)file;
     +	fuse2fs_set_handle(fp, file);
      
    - out:
    - 	if (ret)
    + 	/* fuse 2.4: do not purge pagecache on open */
    + 	fp->keep_cache = 1;
    + #ifdef HAVE_FUSE_CACHE_READDIR
    + 	/* fuse 3.5: cache dirents from readdir contents */
    + 	fp->cache_readdir = 1;
    +@@ misc/fuse2fs.c: static int __op_open(struct fuse2fs *ff, const char *path,
      		ext2fs_free_mem(&file);
      	return ret;
      }
      
      static int op_open(const char *path, struct fuse_file_info *fp)
      {
32:  ddfbba8195c29f ! 34:  f5c46155c79ccc fuse2fs: collect runtime of various operations
    @@ Commit message
         Collect the run time of various operations so that we can do some simple
         profiling.
     
         Signed-off-by: "Darrick J. Wong" <djwong@kernel.org>
     
      ## configure.ac ##
    -@@ configure.ac: then
    - fi
    - if test -n "$FUSE_USE_VERSION"
    +@@ configure.ac: fi
    + if test -n "$have_fuse_cache_readdir"
      then
    - 	AC_DEFINE_UNQUOTED(FUSE_USE_VERSION, $FUSE_USE_VERSION,
    - 		[Define to the version of FUSE to use])
    + 	AC_DEFINE(HAVE_FUSE_CACHE_READDIR, 1,
    + 		  [Define to 1 if fuse supports cache_readdir])
      fi
    + 
     +dnl
     +dnl see if CLOCK_MONOTONIC exists
     +dnl
     +AC_MSG_CHECKING(for CLOCK_MONOTONIC)
     +AC_LINK_IFELSE(
     +[	AC_LANG_PROGRAM([[
    @@ configure.ac: then
      AC_MSG_CHECKING(for optreset)
      AC_CACHE_VAL(ac_cv_have_optreset,
      [AC_EGREP_HEADER(optreset, unistd.h,
     
      ## lib/config.h.in ##
     @@
    - /* Define to 1 if Apple Darwin libintl workaround is needed */
    - #undef _INTL_REDIRECT_MACROS
    + /* Number of bits in time_t, on hosts where this is settable. */
    + #undef _TIME_BITS
      
    - /* Define for large files, on AIX-style hosts. */
    - #undef _LARGE_FILES
    + /* Define to 1 on platforms where this makes time_t a 64-bit type. */
    + #undef __MINGW_USE_VC2005_COMPAT
      
     +/* Define to 1 if CLOCK_MONOTONIC is present */
     +#undef HAVE_CLOCK_MONOTONIC
     +
      #include <dirpaths.h>
     
33:  1315fa41329faf ! 35:  8a58d8b126d4e6 fuse2fs: get rid of the global_fs variable
    @@ misc/fuse2fs.c: int main(int argc, char *argv[])
      	 * we must force ro mode.
      	 */
     -	if (ext2fs_has_feature_shared_blocks(global_fs->super))
     +	if (ext2fs_has_feature_shared_blocks(fctx.fs->super))
      		fctx.ro = 1;
      
    + 	/*
    + 	 * libext2fs' extent tree modification code has severe problems with
    + 	 * implied cluster deallocation, so we must force ro mode.
    + 	 */
    +-	if (ext2fs_has_feature_bigalloc(global_fs->super) &&
    +-	    EXT2FS_CLUSTER_RATIO(global_fs) > 1) {
    ++	if (ext2fs_has_feature_bigalloc(fctx.fs->super) &&
    ++	    EXT2FS_CLUSTER_RATIO(fctx.fs) > 1) {
    + 		log_printf(&fctx, "%s\n",
    +  _("Mounting read-only because writes with large cluster sizes is not supported."));
    + 		fctx.ro = 1;
    + 	}
    + 
     -	if (ext2fs_has_feature_journal_needs_recovery(global_fs->super)) {
     +	if (ext2fs_has_feature_journal_needs_recovery(fctx.fs->super)) {
      		if (fctx.norecovery) {
      			log_printf(&fctx, "%s\n",
       _("Mounting read-only without recovering journal."));
      			fctx.ro = 1;
34:  ca07f54a419987 = 36:  179e4af57d7e85 fuse2fs: hoist lockfile code
35:  69f0801db74143 = 37:  5d3394ff8d6f2e fuse2fs: hoist unmount code from main
36:  3579eba15ddd98 ! 38:  a65babb03b3e37 fuse2fs: split filesystem mounting into helper functions
    @@ misc/fuse2fs.c: int main(int argc, char *argv[])
      
      	/*
      	 * ext4 can't do COW of shared blocks, so if the feature is enabled,
      	 * we must force ro mode.
      	 */
      	if (ext2fs_has_feature_shared_blocks(fctx.fs->super))
    +@@ misc/fuse2fs.c: int main(int argc, char *argv[])
    + 	    EXT2FS_CLUSTER_RATIO(fctx.fs) > 1) {
    + 		log_printf(&fctx, "%s\n",
    +  _("Mounting read-only because writes with large cluster sizes is not supported."));
      		fctx.ro = 1;
    + 	}
      
     -	if (ext2fs_has_feature_journal_needs_recovery(fctx.fs->super)) {
     -		if (fctx.norecovery) {
     -			log_printf(&fctx, "%s\n",
     - _("Mounting read-only without recovering journal."));
     -			fctx.ro = 1;
37:  e3a706d012a1c6 ! 39:  612e59bedd71c0 fuse2fs: register as an IO flusher thread
    @@ Commit message
         a round of filesystem memory reclaim, which could cause more writeout to
         get dumped on fuse2fs.
     
         Signed-off-by: "Darrick J. Wong" <djwong@kernel.org>
     
      ## configure.ac ##
    -@@ configure.ac: then
    - fi
    - if test -n "$FUSE_USE_VERSION"
    +@@ configure.ac: fi
    + if test -n "$have_fuse_cache_readdir"
      then
    - 	AC_DEFINE_UNQUOTED(FUSE_USE_VERSION, $FUSE_USE_VERSION,
    - 		[Define to the version of FUSE to use])
    + 	AC_DEFINE(HAVE_FUSE_CACHE_READDIR, 1,
    + 		  [Define to 1 if fuse supports cache_readdir])
      fi
    -+
    + 
     +dnl
     +dnl see if PR_SET_IO_FLUSHER exists
     +dnl
     +AC_MSG_CHECKING(for PR_SET_IO_FLUSHER)
     +AC_LINK_IFELSE(
     +[	AC_LANG_PROGRAM([[
    @@ misc/fuse2fs.c: static void fuse2fs_compute_libfuse_args(struct fuse2fs *ff,
      		fflush(stdout);
      	}
      }
      
     +/*
     + * Try to register as a filesystem I/O server process so that our memory
    -+ * allocations don't cause fs reclaim.
    ++ * allocations don't cause io reclaim.
     + */
     +static void try_set_io_flusher(struct fuse2fs *ff)
     +{
     +#ifdef HAVE_PR_SET_IO_FLUSHER
     +	int ret = prctl(PR_GET_IO_FLUSHER, 0, 0, 0, 0);
     +
38:  05b8b9046da861 = 40:  9476b1377d8878 fuse2fs: adjust OOM killer score if possible
39:  c383cd4fbc27bc = 41:  15a4aa0d4329b9 fuse2fs: hook library error message printing
40:  c21b7bb856d99d = 42:  5ee2df0fe9b5e0 fuse2fs: print the function name in error messages, not the file name
41:  1f5fc734e00b00 = 43:  d3151f36edf52b fuse2fs: improve tracing for file range operations
42:  1fe3afbc4dd4b8 = 44:  fe8281316fd371 fuse2fs: record thread id in debug trace data
43:  184741e8ec67fc = 45:  0fb191361aff22 fuse2fs: pass a struct fuse2fs to fs_writeable
44:  bb42690c6ab468 = 46:  144fdfd3fad4e0 fuse2fs: track our own writable state
45:  0bba0f4e19ebba = 47:  f066b2d71d6270 fuse2fs: enable the shutdown ioctl
46:  9055fe8b34276b = 48:  ee84bb825b0ba0 fuse2fs: bump library version
47:  d6c0188aeefa3e = 49:  7e7bb349a384f7 fuse2fs: wrap the fuse_set_feature_flag helper for older libfuse
48:  3378dd43db6f20 = 50:  631d3f8d14b613 fuse2fs: disable nfs exports
49:  7ee503ad6acb6b = 51:  96ca2a29cc7dcb fuse2fs: drop fuse 2.x support code
50:  31e3bba3857cc7 ! 52:  e048f198d7b598 fuse2fs: separate libfuse3 and fuse2fs detection in configure
    @@ configure.ac: fi
     -	AC_DEFINE_UNQUOTED(FUSE_USE_VERSION, $FUSE_USE_VERSION,
     -		[Define to the version of FUSE to use])
     -fi
     +AC_SUBST(FUSE2FS_CMT)
      
      dnl
    - dnl see if PR_SET_IO_FLUSHER exists
    + dnl Check if the FUSE cache_readdir flag is supported
      dnl
    - AC_MSG_CHECKING(for PR_SET_IO_FLUSHER)
    - AC_LINK_IFELSE(
    + have_fuse_cache_readdir=
    + if test -n "$FUSE_USE_VERSION"
     
      ## misc/Makefile.in ##
     @@ misc/Makefile.in: MKDIR_P = @MKDIR_P@
      @BLKID_CMT@BLKID_STATIC= blkid.static
      @BLKID_CMT@BLKID_MAN= blkid.8
      
51:  260e9383838bf6 ! 53:  3b02fa292dda7c fuse2fs: start porting fuse2fs to lowlevel libfuse API
    @@ configure.ac: AS_HELP_STRING([--disable-fuse2fs],[do not build fuse2fs]),
     +	fi
     +]
     +)
     +AC_SUBST(FUSE4FS_CMT)
     +
      dnl
    - dnl see if PR_SET_IO_FLUSHER exists
    + dnl Check if the FUSE cache_readdir flag is supported
      dnl
    - AC_MSG_CHECKING(for PR_SET_IO_FLUSHER)
    - AC_LINK_IFELSE(
    - [	AC_LANG_PROGRAM([[
    + have_fuse_cache_readdir=
    + if test -n "$FUSE_USE_VERSION"
    + then
     @@ configure.ac: for i in MCONFIG Makefile \
      	lib/ext2fs/Makefile lib/ext2fs/ext2_types.h \
      	$uuid_out_list $blkid_out_list lib/support/Makefile \
      	lib/ss/ss.pc lib/et/com_err.pc lib/e2p/e2p.pc lib/ext2fs/ext2fs.pc \
      	misc/Makefile ext2ed/Makefile e2fsck/Makefile \
      	debugfs/Makefile tests/Makefile tests/progs/Makefile \
    @@ fuse4fs/fuse4fs.1.in (new)
     
      ## fuse4fs/fuse4fs.c (new) ##
     @@
     +/*
     + * fuse4fs.c - FUSE low-level server for e2fsprogs.
     + *
    -+ * Copyright (C) 2014-2025 Oracle.
    ++ * Copyright (C) 2014-2026 Oracle.
     + *
     + * %Begin-Header%
     + * This file may be redistributed under the terms of the GNU Public
     + * License.
     + * %End-Header%
     + */
    @@ fuse4fs/fuse4fs.c (new)
     +			goto out;
     +	}
     +
     +	file->check_flags = check;
     +	fuse4fs_set_handle(fp, file);
     +
    ++	/* fuse 2.4: do not purge pagecache on open */
    ++	fp->keep_cache = 1;
    ++#ifdef HAVE_FUSE_CACHE_READDIR
    ++	/* fuse 3.5: cache dirents from readdir contents */
    ++	fp->cache_readdir = 1;
    ++#endif
    ++
     +out:
     +	if (ret)
     +		ext2fs_free_mem(&file);
     +	return ret;
     +}
     +
    @@ fuse4fs/fuse4fs.c (new)
     +		fflush(stdout);
     +	}
     +}
     +
     +/*
     + * Try to register as a filesystem I/O server process so that our memory
    -+ * allocations don't cause fs reclaim.
    ++ * allocations don't cause io reclaim.
     + */
     +static void try_set_io_flusher(struct fuse4fs *ff)
     +{
     +#ifdef HAVE_PR_SET_IO_FLUSHER
     +	int ret = prctl(PR_GET_IO_FLUSHER, 0, 0, 0, 0);
     +
    @@ fuse4fs/fuse4fs.c (new)
     +	 * ext4 can't do COW of shared blocks, so if the feature is enabled,
     +	 * we must force ro mode.
     +	 */
     +	if (ext2fs_has_feature_shared_blocks(fctx.fs->super))
     +		fctx.ro = 1;
     +
    ++	/*
    ++	 * libext2fs' extent tree modification code has severe problems with
    ++	 * implied cluster deallocation, so we must force ro mode.
    ++	 */
    ++	if (ext2fs_has_feature_bigalloc(fctx.fs->super) &&
    ++	    EXT2FS_CLUSTER_RATIO(fctx.fs) > 1) {
    ++		log_printf(&fctx, "%s\n",
    ++ _("Mounting read-only because writes with large cluster sizes is not supported."));
    ++		fctx.ro = 1;
    ++	}
    ++
     +	err = fuse4fs_mount(&fctx);
     +	if (err) {
     +		ret = 32;
     +		goto out;
     +	}
     +
52:  7ebb0d37daa7e0 ! 54:  480ffd57c3152f debian: create new package for fuse4fs
    @@ Commit message
      ## debian/control ##
     @@
      Source: e2fsprogs
      Section: admin
      Priority: important
      Maintainer: Theodore Y. Ts'o <tytso@mit.edu>
    --Build-Depends: dpkg-dev, gettext, texinfo, pkgconf, libarchive-dev <!nocheck>, libfuse3-dev [linux-any kfreebsd-any] <!pkg.e2fsprogs.no-fuse2fs>, debhelper-compat (= 12), dh-exec, libblkid-dev, uuid-dev, m4, udev [linux-any], systemd [linux-any], udev | systemd-dev [linux-any], cron [linux-any]
    -+Build-Depends: dpkg-dev, gettext, texinfo, pkgconf, libarchive-dev <!nocheck>, libfuse3-dev [linux-any kfreebsd-any] <!pkg.e2fsprogs.no-fuse2fs> <!pkg.e2fsprogs.no-fuse4fs>, debhelper-compat (= 12), dh-exec, libblkid-dev, uuid-dev, m4, udev [linux-any], systemd [linux-any], udev | systemd-dev [linux-any], cron [linux-any]
    +-Build-Depends: dpkg-dev (>= 1.22.5), gettext, texinfo, pkgconf, libarchive-dev <!nocheck>, libfuse3-dev [linux-any] <!pkg.e2fsprogs.no-fuse2fs>, debhelper-compat (= 12), dh-exec, libblkid-dev, uuid-dev, m4, udev [linux-any], systemd [linux-any], systemd-dev [linux-any], cron [linux-any], dh-sequence-movetousr
    ++Build-Depends: dpkg-dev (>= 1.22.5), gettext, texinfo, pkgconf, libarchive-dev <!nocheck>, libfuse3-dev [linux-any] <!pkg.e2fsprogs.no-fuse2fs> <!pkg.e2fsprogs.no-fuse4fs>, debhelper-compat (= 12), dh-exec, libblkid-dev, uuid-dev, m4, udev [linux-any], systemd [linux-any], systemd-dev [linux-any], cron [linux-any], dh-sequence-movetousr
      Rules-Requires-Root: no
      Standards-Version: 4.7.2
      Homepage: http://e2fsprogs.sourceforge.net
      Vcs-Browser: https://git.kernel.org/pub/scm/fs/ext2/e2fsprogs.git
      Vcs-Git: https://git.kernel.org/pub/scm/fs/ext2/e2fsprogs.git -b debian/master
      
     @@ debian/control: Replaces: fuseext2 (<< 1.47.1-2~)
    - Architecture: linux-any kfreebsd-any
    + Architecture: linux-any
      Description: ext2 / ext3 / ext4 file system driver for FUSE
       fuse2fs is a FUSE file system client that supports reading and
       writing from devices or image files containing ext2, ext3, and ext4
       file systems.
      
     +Package: fuse4fs
53:  4369876c2c94cb = 55:  eb97e1fefbf286 fuse4fs: namespace some helpers
54:  3d879e8b9af2f6 ! 56:  7a2e6084f203a4 fuse4fs: convert to low level API
    @@ Commit message
     
      ## fuse4fs/fuse4fs.c ##
     @@
      /*
       * fuse4fs.c - FUSE low-level server for e2fsprogs.
       *
    -  * Copyright (C) 2014-2025 Oracle.
    +  * Copyright (C) 2014-2026 Oracle.
     + * Copyright (C) 2025 CTERA Networks.
       *
       * %Begin-Header%
       * This file may be redistributed under the terms of the GNU Public
       * License.
       * %End-Header%
55:  e503449ebd35fa = 57:  8072dafea5ba54 libsupport: port the kernel list.h to libsupport
56:  5bf09d97df47be = 58:  df5e76db0018b3 libsupport: add a cache
57:  b0567861fb4c48 = 59:  f13414a72be32f cache: disable debugging
58:  d8d9a1d2c77497 = 60:  383f3dd0b56f64 cache: use modern list iterator macros
59:  d72a8bf319a337 = 61:  a9c0181ee15128 cache: embed struct cache in the owner
60:  12ae5b5676175b = 62:  31e5763e32dfc2 cache: pass cache pointer to callbacks
61:  ce739cf7e07770 = 63:  a5c773947bd56d cache: pass a private data pointer through cache_walk
62:  5f29a509ae6ff5 = 64:  4f017b4dc8920f cache: add a helper to grab a new refcount for a cache_node
63:  35f2f492357fdc = 65:  d1dea709493fdc cache: return results of a cache flush
64:  b83bb727f35e35 = 66:  e59f4eba2f22f8 cache: add a "get only if incore" flag to cache_node_get
65:  93ab9d85892539 = 67:  a999b4c74344cd cache: support gradual expansion
66:  34832daae14e22 = 68:  019aa0d8a8c87d cache: support updating maxcount and flags
67:  133ccdd2700d31 = 69:  0283835cbfa2db cache: support channging flags
68:  4e0e55db4c2825 = 70:  0f5c83c6c88c3f cache: implement automatic shrinking
69:  2987f5a8e19d4d ! 71:  26f78774c08acc fuse4fs: add cache to track open files
    @@ fuse4fs/fuse4fs.c: static int fuse4fs_open_file(struct fuse4fs *ff, const struct
     +	}
     +	file->fi->i_open_count++;
     +
      	file->check_flags = check;
      	fuse4fs_set_handle(fp, file);
      
    - out:
    - 	if (ret)
    - 		ext2fs_free_mem(&file);
    + 	/* fuse 2.4: do not purge pagecache on open */
    + 	fp->keep_cache = 1;
    + #ifdef HAVE_FUSE_CACHE_READDIR
     @@ fuse4fs/fuse4fs.c: static void op_release(fuse_req_t req, fuse_ino_t fino EXT2FS_ATTR((unused)),
      	    (fh->open_flags & EXT2_FILE_WRITE)) {
      		err = ext2fs_flush2(fs, EXT2_FLAG_FLUSH_NO_SYNC);
      		if (err)
      			ret = translate_error(fs, fh->ino, err);
      	}
70:  4e19c5a99fd721 ! 72:  d6a2e3be991671 fuse4fs: use the orphaned inode list
    @@ fuse4fs/fuse4fs.c: static int fuse4fs_open_file(struct fuse4fs *ff, const struct
      
      	file->check_flags = check;
      	fuse4fs_set_handle(fp, file);
     +	dbg_printf(ff, "%s: ino=%d fh=%p opencount=%d\n", __func__, ino, file,
     +		   file->fi->i_open_count);
      
    - out:
    - 	if (ret)
    - 		ext2fs_free_mem(&file);
    - 	return ret;
    - }
    + 	/* fuse 2.4: do not purge pagecache on open */
    + 	fp->keep_cache = 1;
    + #ifdef HAVE_FUSE_CACHE_READDIR
    + 	/* fuse 3.5: cache dirents from readdir contents */
    + 	fp->cache_readdir = 1;
     @@ fuse4fs/fuse4fs.c: static void op_open(fuse_req_t req, fuse_ino_t fino, struct fuse_file_info *fp)
      	struct fuse4fs *ff = fuse4fs_get(req);
      	ext2_ino_t ino;
      	int ret;
      
      	FUSE4FS_CHECK_CONTEXT(req);
71:  1ec06be479c7ce = 73:  2a4c9c2e579556 fuse4fs: implement FUSE_TMPFILE
72:  489d5de33dcf64 = 74:  38cd25631692e6 fuse4fs: create incore reverse orphan list

^ permalink raw reply

* [GIT PULL 1/9] fuse2fs: fix locking problems
From: Darrick J. Wong @ 2026-03-12 20:59 UTC (permalink / raw)
  To: tytso; +Cc: djwong, linux-ext4
In-Reply-To: <20260312205728.GA6004@frogsfrogsfrogs>

Hi Ted,

Please pull this branch with changes for ext4.

As usual, I did a test-merge with the main upstream branch as of a few
minutes ago, and didn't see any conflicts.  Please let me know if you
encounter any problems.

The following changes since commit 7ee1d505ef3b37831215f490411f346fe57e9053:

Update release notes, etc., for the 1.47.4 release (2026-03-06 12:17:36 -0500)

are available in the Git repository at:

https://git.kernel.org/pub/scm/linux/kernel/git/djwong/e2fsprogs.git tags/fuse2fs-locking_2026-03-12

for you to fetch changes up to b22ae270a1016c158a434c6bc601ba623e17a361:

fuse2fs: try to grab block device O_EXCL repeatedly (2026-03-08 19:14:02 -0700)

----------------------------------------------------------------
fuse2fs: fix locking problems [01/18]

Teach fuse2fs to flock the file(s) underlying the filesystem if the fs
is stored in a regular file, so that we don't have to create and
maintain separate lockfiles.

For block devices, fix a weird race between mount and unmount that is
causing testing failures by waiting a small amount of time to grab a
lock.

Signed-off-by: "Darrick J. Wong" <djwong@kernel.org>

----------------------------------------------------------------
Darrick J. Wong (4):
libext2fs: add POSIX advisory locking to the unix IO manager
fuse2fs: try to lock filesystem image files before using them
fuse2fs: quiet down write-protect warning
fuse2fs: try to grab block device O_EXCL repeatedly

lib/ext2fs/ext2_io.h         |  12 +++-
debian/libext2fs2t64.symbols |   2 +
lib/ext2fs/io_manager.c      |  16 +++++
lib/ext2fs/unix_io.c         |  71 +++++++++++++++++++++
misc/fuse2fs.c               | 144 +++++++++++++++++++++++++++++++++++++++----
5 files changed, 232 insertions(+), 13 deletions(-)


^ permalink raw reply

* [GIT PULL 2/9] fuse2fs: add some easy new features
From: Darrick J. Wong @ 2026-03-12 20:59 UTC (permalink / raw)
  To: tytso; +Cc: djwong, linux-ext4
In-Reply-To: <20260312205728.GA6004@frogsfrogsfrogs>

Hi Ted,

Please pull this branch with changes for ext4.

As usual, I did a test-merge with the main upstream branch as of a few
minutes ago, and didn't see any conflicts.  Please let me know if you
encounter any problems.

The following changes since commit b22ae270a1016c158a434c6bc601ba623e17a361:

fuse2fs: try to grab block device O_EXCL repeatedly (2026-03-08 19:14:02 -0700)

are available in the Git repository at:

https://git.kernel.org/pub/scm/linux/kernel/git/djwong/e2fsprogs.git tags/fuse2fs-new-features_2026-03-12

for you to fetch changes up to a4fc4817e3072cb19f481da24d4520671a174fff:

fuse2fs: implement MMP updates (2026-03-08 19:14:04 -0700)

----------------------------------------------------------------
fuse2fs: add some easy new features [02/18]

As of 2025, libfuse is a lot more capable than it was in 2013.
Implement some new features such as readdirplus and directory seeking
for better directory performance, and reduce the amount of filesystem
flushing so that it only happens when userspace explicitly asks for it.
Now we also can add htree indices to large directories, support MMP in
fuse2fs, and link count overflows are handled correctly.

Signed-off-by: "Darrick J. Wong" <djwong@kernel.org>

----------------------------------------------------------------
Darrick J. Wong (21):
libext2fs: initialize htree when expanding directory
libext2fs: create link count adjustment helpers for dir_nlink
libext2fs: fix ext2fs_mmp_update
libext2fs: refactor aligned MMP buffer allocation
libext2fs: always use ext2fs_mmp_get_mem to allocate fs->mmp_buf
fuse2fs: disable write access when cluster size > block size
fuse2fs: enable more caching
fuse2fs: check root directory while mounting
fuse2fs: read bitmaps asynchronously during initialization
fuse2fs: use file handles when possible
fuse2fs: implement dir seeking
fuse2fs: implement readdirplus
fuse2fs: implement dirsync mode
fuse2fs: only flush O_SYNC files on close
fuse2fs: improve want_extra_isize handling
fuse2fs: cache symlink targets in the kernel
fuse2fs: constrain worker thread count
fuse2fs: improve error handling behaviors
fuse2fs: fix link count overflows on dir_nlink filesystems
libsupport: add background thread manager
fuse2fs: implement MMP updates

lib/ext2fs/ext2fs.h          |   6 +
lib/support/bthread.h        |  27 ++
configure                    |  47 ++++
configure.ac                 |  29 ++
debian/libext2fs2t64.symbols |   6 +
e2fsck/unix.c                |   2 +-
lib/config.h.in              |   3 +
lib/ext2fs/dupfs.c           |   7 +-
lib/ext2fs/link.c            | 290 ++++++++++++++++++++
lib/ext2fs/mkdir.c           |   2 +-
lib/ext2fs/mmp.c             |  24 +-
lib/support/Makefile.in      |   6 +-
lib/support/bthread.c        | 201 ++++++++++++++
misc/dumpe2fs.c              |   2 +-
misc/fuse2fs.1.in            |   9 +
misc/fuse2fs.c               | 635 +++++++++++++++++++++++++++++++++++++------
16 files changed, 1191 insertions(+), 105 deletions(-)
create mode 100644 lib/support/bthread.h
create mode 100644 lib/support/bthread.c


^ permalink raw reply

* [GIT PULL 3/9] fuse2fs: clean up operation startup
From: Darrick J. Wong @ 2026-03-12 21:00 UTC (permalink / raw)
  To: tytso; +Cc: djwong, linux-ext4
In-Reply-To: <20260312205728.GA6004@frogsfrogsfrogs>

Hi Ted,

Please pull this branch with changes for ext4.

As usual, I did a test-merge with the main upstream branch as of a few
minutes ago, and didn't see any conflicts.  Please let me know if you
encounter any problems.

The following changes since commit a4fc4817e3072cb19f481da24d4520671a174fff:

fuse2fs: implement MMP updates (2026-03-08 19:14:04 -0700)

are available in the Git repository at:

https://git.kernel.org/pub/scm/linux/kernel/git/djwong/e2fsprogs.git tags/fuse2fs-refactor-operation-startup_2026-03-12

for you to fetch changes up to f5c46155c79cccd46e047d732063c7f21db35c8e:

fuse2fs: collect runtime of various operations (2026-03-08 19:14:05 -0700)

----------------------------------------------------------------
fuse2fs: clean up operation startup [03/18]

Reduce the amount of boilerplate in fuse2fs by creating helper functions
to start and finish a file operation instead of open-coding the logic
all over the place.  This also fixes a couple of theoretical races.

Signed-off-by: "Darrick J. Wong" <djwong@kernel.org>

----------------------------------------------------------------
Darrick J. Wong (9):
fuse2fs: rework FUSE2FS_CHECK_CONTEXT not to rely on global_fs
fuse2fs: rework checking file handles
fuse2fs: rework fallocate file handle extraction
fuse2fs: consolidate file handle checking in op_ioctl
fuse2fs: move fs assignment closer to locking the bfl
fuse2fs: clean up operation startup
fuse2fs: clean up operation completion
fuse2fs: clean up more boilerplate
fuse2fs: collect runtime of various operations

configure       |  38 +++++
configure.ac    |  19 +++
lib/config.h.in |   3 +
misc/fuse2fs.c  | 475 +++++++++++++++++++++++++++++---------------------------
4 files changed, 304 insertions(+), 231 deletions(-)


^ permalink raw reply

* [GIT PULL 4/9] fuse2fs: refactor unmount code
From: Darrick J. Wong @ 2026-03-12 21:00 UTC (permalink / raw)
  To: tytso; +Cc: djwong, linux-ext4
In-Reply-To: <20260312205728.GA6004@frogsfrogsfrogs>

Hi Ted,

Please pull this branch with changes for ext4.

As usual, I did a test-merge with the main upstream branch as of a few
minutes ago, and didn't see any conflicts.  Please let me know if you
encounter any problems.

The following changes since commit f5c46155c79cccd46e047d732063c7f21db35c8e:

fuse2fs: collect runtime of various operations (2026-03-08 19:14:05 -0700)

are available in the Git repository at:

https://git.kernel.org/pub/scm/linux/kernel/git/djwong/e2fsprogs.git tags/fuse2fs-refactor-unmounting_2026-03-12

for you to fetch changes up to 5d3394ff8d6f2e120be1343c1504831d9602a3b4:

fuse2fs: hoist unmount code from main (2026-03-08 19:14:05 -0700)

----------------------------------------------------------------
fuse2fs: refactor unmount code [04/18]

In this series, we refactor the code around ext2fs_close to get ready
for iomap mode.  The significant part of this series is moving the
unmount code to op_destroy, because we want to release the block device
as a part of the umount(2) process to maintain expected behavior of the
in-kernel local filesystem drivers.

Signed-off-by: "Darrick J. Wong" <djwong@kernel.org>

----------------------------------------------------------------
Darrick J. Wong (3):
fuse2fs: get rid of the global_fs variable
fuse2fs: hoist lockfile code
fuse2fs: hoist unmount code from main

misc/fuse2fs.c | 199 +++++++++++++++++++++++++++++++--------------------------
1 file changed, 108 insertions(+), 91 deletions(-)


^ permalink raw reply

* [GIT PULL 5/9] fuse2fs: refactor mount code
From: Darrick J. Wong @ 2026-03-12 21:00 UTC (permalink / raw)
  To: tytso; +Cc: djwong, linux-ext4
In-Reply-To: <20260312205728.GA6004@frogsfrogsfrogs>

Hi Ted,

Please pull this branch with changes for ext4.

As usual, I did a test-merge with the main upstream branch as of a few
minutes ago, and didn't see any conflicts.  Please let me know if you
encounter any problems.

The following changes since commit 5d3394ff8d6f2e120be1343c1504831d9602a3b4:

fuse2fs: hoist unmount code from main (2026-03-08 19:14:05 -0700)

are available in the Git repository at:

https://git.kernel.org/pub/scm/linux/kernel/git/djwong/e2fsprogs.git tags/fuse2fs-refactor-mounting_2026-03-12

for you to fetch changes up to 9476b1377d887872f96d7144a81d2107cff3df1f:

fuse2fs: adjust OOM killer score if possible (2026-03-08 19:14:05 -0700)

----------------------------------------------------------------
fuse2fs: refactor mount code [05/18]

Here, we hoist the mounting code out of main() into a pile of separate
helper functions to reduce the complexity of understanding the mount
code.  This isn't strictly required for iomap, but it makes main() a lot
easier to understand.

Signed-off-by: "Darrick J. Wong" <djwong@kernel.org>

----------------------------------------------------------------
Darrick J. Wong (3):
fuse2fs: split filesystem mounting into helper functions
fuse2fs: register as an IO flusher thread
fuse2fs: adjust OOM killer score if possible

configure       |  37 ++++
configure.ac    |  18 ++
lib/config.h.in |   3 +
misc/fuse2fs.c  | 634 +++++++++++++++++++++++++++++++-------------------------
4 files changed, 412 insertions(+), 280 deletions(-)


^ permalink raw reply

* [GIT PULL 6/9] fuse2fs: improve operation tracing
From: Darrick J. Wong @ 2026-03-12 21:00 UTC (permalink / raw)
  To: tytso; +Cc: djwong, linux-ext4
In-Reply-To: <20260312205728.GA6004@frogsfrogsfrogs>

Hi Ted,

Please pull this branch with changes for ext4.

As usual, I did a test-merge with the main upstream branch as of a few
minutes ago, and didn't see any conflicts.  Please let me know if you
encounter any problems.

The following changes since commit 9476b1377d887872f96d7144a81d2107cff3df1f:

fuse2fs: adjust OOM killer score if possible (2026-03-08 19:14:05 -0700)

are available in the Git repository at:

https://git.kernel.org/pub/scm/linux/kernel/git/djwong/e2fsprogs.git tags/fuse2fs-tracing_2026-03-12

for you to fetch changes up to fe8281316fd37133eb78474040affabb3f060e24:

fuse2fs: record thread id in debug trace data (2026-03-08 19:14:06 -0700)

----------------------------------------------------------------
fuse2fs: improve operation tracing [06/18]

This series improves the ability for developers to trace the activities
of fuse2fs by adding more debugging printfs and tracing abilities of
fuse2fs.  It also registers a com_err handler for libext2fs so we can
capture errors coming out of there, and changes filesystem error
reporting to tell us the function name instead of just fuse2fs.c.

Signed-off-by: "Darrick J. Wong" <djwong@kernel.org>

----------------------------------------------------------------
Darrick J. Wong (4):
fuse2fs: hook library error message printing
fuse2fs: print the function name in error messages, not the file name
fuse2fs: improve tracing for file range operations
fuse2fs: record thread id in debug trace data

misc/fuse2fs.c | 93 +++++++++++++++++++++++++++++++++++++++++++---------------
1 file changed, 69 insertions(+), 24 deletions(-)


^ permalink raw reply

* [GIT PULL 7/9] fuse2fs: better tracking of writable state
From: Darrick J. Wong @ 2026-03-12 21:01 UTC (permalink / raw)
  To: tytso; +Cc: djwong, linux-ext4
In-Reply-To: <20260312205728.GA6004@frogsfrogsfrogs>

Hi Ted,

Please pull this branch with changes for ext4.

As usual, I did a test-merge with the main upstream branch as of a few
minutes ago, and didn't see any conflicts.  Please let me know if you
encounter any problems.

The following changes since commit fe8281316fd37133eb78474040affabb3f060e24:

fuse2fs: record thread id in debug trace data (2026-03-08 19:14:06 -0700)

are available in the Git repository at:

https://git.kernel.org/pub/scm/linux/kernel/git/djwong/e2fsprogs.git tags/fuse2fs-writability_2026-03-12

for you to fetch changes up to f066b2d71d62705836e131bd03f71d42dd4f9376:

fuse2fs: enable the shutdown ioctl (2026-03-08 19:14:06 -0700)

----------------------------------------------------------------
fuse2fs: better tracking of writable state [07/18]

There are multiple mutability variables in play in fuse2fs -- first,
EXT2_FLAG_RW tracks whether or not we can write anything to the
filesystem.  However, there's a second state, which is whether or not
we actually want to write to the filesystem, regardless of the library
state.  This can happen if we open libext2fs for writing, but then
discover something about the filesystem that makes us not want to write
to it after all.

Split out this second variable into an explicit variable in fuse2fs.

Signed-off-by: "Darrick J. Wong" <djwong@kernel.org>

----------------------------------------------------------------
Darrick J. Wong (3):
fuse2fs: pass a struct fuse2fs to fs_writeable
fuse2fs: track our own writable state
fuse2fs: enable the shutdown ioctl

misc/fuse2fs.c | 102 +++++++++++++++++++++++++++++++++++++++++----------------
1 file changed, 73 insertions(+), 29 deletions(-)


^ permalink raw reply

* [GIT PULL 8/9] fuse2fs: upgrade to libfuse 3.17
From: Darrick J. Wong @ 2026-03-12 21:01 UTC (permalink / raw)
  To: tytso; +Cc: amir73il, djwong, linux-ext4
In-Reply-To: <20260312205728.GA6004@frogsfrogsfrogs>

Hi Ted,

Please pull this branch with changes for ext4.

As usual, I did a test-merge with the main upstream branch as of a few
minutes ago, and didn't see any conflicts.  Please let me know if you
encounter any problems.

The following changes since commit f066b2d71d62705836e131bd03f71d42dd4f9376:

fuse2fs: enable the shutdown ioctl (2026-03-08 19:14:06 -0700)

are available in the Git repository at:

https://git.kernel.org/pub/scm/linux/kernel/git/djwong/e2fsprogs.git tags/fuse2fs-library-upgrade_2026-03-12

for you to fetch changes up to 96ca2a29cc7dcb3100efa2efc3916aa8b66dcedc:

fuse2fs: drop fuse 2.x support code (2026-03-08 19:14:06 -0700)

----------------------------------------------------------------
fuse2fs: upgrade to libfuse 3.17 [08/18]

In preparation to start hacking on fuse2fs and iomap, upgrade fuse2fs
library support to 3.17, which is the latest upstream release as of this
writing.  Drop support for libfuse2, which is now very obsolete.

Signed-off-by: "Darrick J. Wong" <djwong@kernel.org>

----------------------------------------------------------------
Darrick J. Wong (4):
fuse2fs: bump library version
fuse2fs: wrap the fuse_set_feature_flag helper for older libfuse
fuse2fs: disable nfs exports
fuse2fs: drop fuse 2.x support code

configure      | 358 +++++----------------------------------------------------
configure.ac   |  85 +++++---------
misc/fuse2fs.c | 252 +++++++++-------------------------------
3 files changed, 115 insertions(+), 580 deletions(-)


^ permalink raw reply

* [GIT PULL 9/9] fuse4fs: fork a low level fuse server
From: Darrick J. Wong @ 2026-03-12 21:01 UTC (permalink / raw)
  To: tytso; +Cc: amir73il, djwong, linux-ext4
In-Reply-To: <20260312205728.GA6004@frogsfrogsfrogs>

Hi Ted,

Please pull this branch with changes for ext4.

As usual, I did a test-merge with the main upstream branch as of a few
minutes ago, and didn't see any conflicts.  Please let me know if you
encounter any problems.

The following changes since commit 96ca2a29cc7dcb3100efa2efc3916aa8b66dcedc:

fuse2fs: drop fuse 2.x support code (2026-03-08 19:14:06 -0700)

are available in the Git repository at:

https://git.kernel.org/pub/scm/linux/kernel/git/djwong/e2fsprogs.git tags/fuse4fs-fork_2026-03-12

for you to fetch changes up to 38cd25631692e61f0ea8f64c54f38cf2fb6b3360:

fuse4fs: create incore reverse orphan list (2026-03-08 19:15:03 -0700)

----------------------------------------------------------------
fuse4fs: fork a low level fuse server [09/18]

Whilst developing the fuse2fs+iomap prototype, I discovered a
fundamental design limitation of the upper-level libfuse API: hardlinks.
The upper level fuse library really wants to communicate with the fuse
server with file paths, instead of using inode numbers.  This works
great for filesystems that don't have inodes, create files dynamically
at runtime, or lack stable inode numbers.

Unfortunately, the libfuse path abstraction assigns a unique nodeid to
every child file in the entire filesystem, without regard to hard links.
In other words, a hardlinked regular file may have one ondisk inode
number but multiple kernel inodes.  For classic fuse2fs this isn't a
problem because all file access goes through the fuse server and the big
library lock protects us from corruption.

For fuse2fs + iomap this is a disaster because we rely on the kernel to
coordinate access to inodes.  For hardlinked files, we *require* that
there only be one in-kernel inode for each ondisk inode.

The path based mechanism is also very inefficient for fuse2fs.  Every
time a file is accessed, the upper level libfuse passes a new nodeid to
the kernel, and on every file access the kernel passes that same nodeid
back to libfuse.  libfuse then walks its internal directory entry cache
to construct a path string for that nodeid and hands it to fuse2fs.
fuse2fs then walks the ondisk directory structure to find the ext2 inode
number.  Every time.

Create a new fuse4fs server from fuse2fs that uses the lowlevel fuse
API.  This affords us direct control over nodeids and eliminates the
path wrangling.  Hardlinks can be supported when iomap is turned on,
and metadata-heavy workloads run twice as fast.

Signed-off-by: "Darrick J. Wong" <djwong@kernel.org>

----------------------------------------------------------------
Darrick J. Wong (23):
fuse2fs: separate libfuse3 and fuse2fs detection in configure
fuse2fs: start porting fuse2fs to lowlevel libfuse API
debian: create new package for fuse4fs
fuse4fs: namespace some helpers
fuse4fs: convert to low level API
libsupport: port the kernel list.h to libsupport
libsupport: add a cache
cache: disable debugging
cache: use modern list iterator macros
cache: embed struct cache in the owner
cache: pass cache pointer to callbacks
cache: pass a private data pointer through cache_walk
cache: add a helper to grab a new refcount for a cache_node
cache: return results of a cache flush
cache: add a "get only if incore" flag to cache_node_get
cache: support gradual expansion
cache: support updating maxcount and flags
cache: support channging flags
cache: implement automatic shrinking
fuse4fs: add cache to track open files
fuse4fs: use the orphaned inode list
fuse4fs: implement FUSE_TMPFILE
fuse4fs: create incore reverse orphan list

lib/ext2fs/jfs_compat.h  |    2 +-
lib/ext2fs/kernel-list.h |  111 -
lib/support/cache.h      |  184 ++
lib/support/list.h       |  901 +++++++
lib/support/xbitops.h    |  128 +
Makefile.in              |    3 +-
configure                |  441 ++--
configure.ac             |  156 +-
debian/control           |   12 +-
debian/fuse4fs.install   |    2 +
debian/fuse4fs.links     |    3 +
debian/rules             |   11 +
debugfs/Makefile.in      |   12 +-
e2fsck/Makefile.in       |   56 +-
fuse4fs/Makefile.in      |  193 ++
fuse4fs/fuse4fs.1.in     |  118 +
fuse4fs/fuse4fs.c        | 6448 ++++++++++++++++++++++++++++++++++++++++++++++
lib/config.h.in          |    3 +
lib/e2p/Makefile.in      |    4 +-
lib/ext2fs/Makefile.in   |   14 +-
lib/support/Makefile.in  |    8 +-
lib/support/cache.c      |  882 +++++++
misc/Makefile.in         |   18 +-
misc/tune2fs.c           |    4 -
24 files changed, 9245 insertions(+), 469 deletions(-)
delete mode 100644 lib/ext2fs/kernel-list.h
create mode 100644 lib/support/cache.h
create mode 100644 lib/support/list.h
create mode 100644 lib/support/xbitops.h
create mode 100644 debian/fuse4fs.install
create mode 100644 debian/fuse4fs.links
create mode 100644 fuse4fs/Makefile.in
create mode 100644 fuse4fs/fuse4fs.1.in
create mode 100644 fuse4fs/fuse4fs.c
create mode 100644 lib/support/cache.c


^ permalink raw reply

* [PATCH RFC 00/53] lift lookup out of exclive lock for dir ops
From: NeilBrown @ 2026-03-12 21:11 UTC (permalink / raw)
  To: Linus Torvalds, Alexander Viro, Christian Brauner, Jan Kara,
	Jeff Layton, Trond Myklebust, Anna Schumaker, Carlos Maiolino,
	Miklos Szeredi, Amir Goldstein, Jan Harkes, Hugh Dickins,
	Baolin Wang, David Howells, Marc Dionne, Steve French,
	Namjae Jeon, Sungjong Seo, Yuezhang Mo, Andreas Hindborg,
	Breno Leitao, Theodore Ts'o, Andreas Dilger, Steven Rostedt,
	Masami Hiramatsu, Ilya Dryomov, Alex Markuze, Viacheslav Dubeyko,
	Tyler Hicks, Andreas Gruenbacher, Richard Weinberger,
	Anton Ivanov, Johannes Berg, Jeremy Kerr, Ard Biesheuvel
  Cc: linux-fsdevel, linux-nfs, linux-xfs, linux-unionfs, coda,
	linux-mm, linux-afs, linux-cifs, linux-ext4, linux-kernel,
	linux-trace-kernel, ceph-devel, ecryptfs, gfs2, linux-um,
	linux-efi

This patch set progresses my effort to improve concurrency of
directory operations and specifically to allow concurrent updates
in a given directory.

There are a bunch of VFS patches which introduce some new APIs and
improve existing ones.  Then a bunch of per-filesystem changes which
adjust to meet new needs, often using the new APIs, then a final bunch
of VFS patches which discard some APIs that are no longer wanted, and
one (the second last) which makes the big change.  Some of the fs
patches don't depend on any preceeding patch and if maintainers wanted
to take those early I certainly wouldn't object!  I've put a '*' next
to patches which I think can be taken at any time.

My longer term goal involves pushing the parent-directory locking down
into filesystems (which can then discard it if it isn't needed) and using
exclusive dentry locking in the VFS for all directory operations other
than readdir - which by its nature needs shared locking and will
continue to use the directory lock.

The VFS already has exclusive dentry locking for the limited case of
lookup.  Newly created dentries (when created by d_alloc_parallel()) are
exclusively locked using the DCACHE_PAR_LOOKUP bit.  They remain
exclusive locked until they are hashed as negative or positive dentries,
or they are discarded.

DCACHE_PAR_LOOKUP currently depends on a shared parent lock to exclude
directory modifying operations.  This patch set removes this dependency
so that d_alloc_parallel() can be called without locking and all
directory modifying operations receive either a hashed dentry or an
in-lookup dentry (they currently recieve either a hashed or unhashed,
or sometimes in-lookup (atomic_open only)).

The cases where a filesystem can receive an in-lookup dentry are:
 - lookup. Currently can receive in-lookup or unhashed.  After this patch set
    it always receives in-lookup
 - atomic_open.  Currently can receive in-lookup or hashed-negative.
    This doesn't change with this patchset.
 - rename. currently can receive hashed or unhashed.  After this patchset
    can also receive in-lookup where previously it would receive unhashed.
    This is only for the target of a rename over NFS.
 - link, mknod, mkdir, symlink.  currently received hashed-negative except for
    NFS which notices the implied exclusive create and skips the lookup so
    the filesystem can received unhashed-negative for the operation.

There are two particular needs to be addressed before we can use d_alloc_parallel()
outside of the directory lock.

1/ d_alloc_parallel() effects a blocking lock so lock ordering is important.
  If we are to take the directory lock *after* calling d_alloc_parallel() (and 
  still holding an in-lookup dentry, as happens at least when ->atomic_open
  is called) then we must never call d_alloc_parallel() while holding the
  directory lock, even a shared lock.
  This particularly affects readdir as several filesystems prime the dcache
  with readdir results and so use d_alloc_parallel() in the ->iterate_shared
  handler, which will now have deadlock potential.  To address this we
  introduce d_alloc_noblock() which fails rather than blocking.

  A few other cases of potential lock inversion exist.  These are
  addressed by dropping the directory lock when it is safe to do so
  before calling d_alloc_parallel().  This requires the addtion of
  LOOKUP_SHARED so that ->lookup knows how the parent is locked.  This
  is ugly but is gone by the end of the series. After the locking is
  rearranged in the second last patch, ->lookup is only ever called
  with a shared lock.


2/ As d_alloc_parallel() will be able to run without the directory lock,
  holding that lock exclusively is not enough to protect some dcache
  manipulations.  In particular, several filesystems d_drop() a dentry
  and (possibly) re-hash it.  This will no longer be safe as
  d_alloc_parallel() could run while the dentry was dropped, would find
  that name doesn't exist in the dcache, and would create a new dentry
  leading to two uncoordinated dentries with the same name.

  It will still be safe to d_drop() a dentry after the operation has
  completed, whether in success or failure.  But d_drop()ing before that
  is best avoided.  An early d_drop() that isn't followed by a rehash is
  not clearly problematic for a filesystem which still uses parent locking
  (as all do at present) but is good to discourage that pattern now.

  This is addressed, in part, by changing d_splice_alias() to be able to
  instantiate any negative dentry, whether hashed, unhashed, or
  in-lookup.  This removes the need for d_drop() in most cases.

New APIs added are:

 - d_alloc_noblock - see patch 05 for details
 - d_duplicate - patch 06

Removed APIs:

 - d_alloc
 - d_rehash
 - d_add
 - lookup_one
 - lookup_noperm

Changed APIs:

 - d_alloc_paralle - no longer requires a waitqueue_head_t
 - d_splice_alias - now works with in-lookup dentry
 - d_alloc_name - now works with ->d_hash

d_alloc_name() should be used with d_make_persistent().  These don't require
VFS locking as the filesystem doesn't permit create/remove via VFS calls,
and provides its own locking to avoid duplicate names.

d_splice_alias() should *always* be used:
  in ->lookup 
  in ->iterate_shared for cache priming.
  in ->atomic_open, possibly via a call to ->lookup
  in ->mkdir unless d_instantiate_new() can be used.
  in ->link ->symlink ->mknod if ->lookup skips LOOKUP_CREATE|LOOKUP_EXCL

Thanks for reading this far!  I've been testing NFS but haven't tried
anything else yet.  As well as the normal review of details I'd love to
know if I've missed any important conseqeunces of the locking change.
It is a big conceptual change and there could easily be surprising
implications.

Thanks,
NeilBrown


 [PATCH 01/53] VFS: fix various typos in documentation for
 [PATCH 02/53] VFS: enhance d_splice_alias() to handle in-lookup
 [PATCH 03/53] VFS: allow d_alloc_name() to be used with ->d_hash
 [PATCH 04/53] VFS: use global wait-queue table for d_alloc_parallel()
 [PATCH 05/53] VFS: introduce d_alloc_noblock()
 [PATCH 06/53] VFS: add d_duplicate()
 [PATCH 07/53] VFS: Add LOOKUP_SHARED flag.
 [PATCH 08/53] VFS/xfs: drop parent lock across d_alloc_parallel() in
*[PATCH 09/53] nfs: remove d_drop()/d_alloc_parallel() from
 [PATCH 10/53] nfs: use d_splice_alias() in nfs_link()
 [PATCH 11/53] nfs: don't d_drop() before d_splice_alias()
 [PATCH 12/53] nfs: don't d_drop() before d_splice_alias() in
 [PATCH 13/53] nfs: Use d_alloc_noblock() in nfs_prime_dcache()
 [PATCH 14/53] nfs: use d_alloc_noblock() in silly-rename
 [PATCH 15/53] nfs: use d_duplicate()
*[PATCH 16/53] ovl: drop dir lock for lookups in impure readdir
*[PATCH 17/53] coda: don't d_drop() early.
 [PATCH 18/53] shmem: use d_duplicate()
*[PATCH 19/53] afs: use d_time instead of d_fsdata
*[PATCH 20/53] afs: don't unhash/rehash dentries during unlink/rename
 [PATCH 21/53] afs: use d_splice_alias() in afs_vnode_new_inode()
 [PATCH 22/53] afs: use d_alloc_nonblock in afs_sillyrename()
 [PATCH 23/53] afs: lookup_atsys to drop and reclaim lock.
 [PATCH 24/53] afs: use d_duplicate()
*[PATCH 25/53] smb/client: use d_time to store a timestamp in dentry,
*[PATCH 26/53] smb/client: don't unhashed and rehash to prevent new
*[PATCH 27/53] smb/client: use d_splice_alias() in atomic_open
 [PATCH 28/53] smb/client: Use d_alloc_noblock() in
*[PATCH 29/53] exfat: simplify exfat_lookup()
*[PATCH 30/53] configfs: remove d_add() calls before
 [PATCH 31/53] configfs: stop using d_add().
*[PATCH 32/53] ext4: move dcache modifying code out of __ext4_link()
*[PATCH 33/53] ext4: use on-stack dentries in
 [PATCH 34/53] tracefs: stop using d_add().
 [PATCH 35/53] cephfs: stop using d_add().
*[PATCH 36/53] cephfs: remove d_alloc from CEPH_MDS_OP_LOOKUPNAME
 [PATCH 37/53] cephfs: Use d_alloc_noblock() in
 [PATCH 38/53] cephfs: Don't d_drop() before d_splice_alias()
 [PATCH 39/53] ecryptfs: stop using d_add().
 [PATCH 40/53] gfs2: stop using d_add().
 [PATCH 41/53] libfs: stop using d_add().
 [PATCH 42/53] fuse: don't d_drop() before d_splice_alias()
 [PATCH 43/53] fuse: Use d_alloc_noblock() in fuse_direntplus_link()
 [PATCH 44/53] hostfs: don't d_drop() before d_splice_alias() in
 [PATCH 45/53] efivarfs: use d_alloc_name()
 [PATCH 46/53] Remove references to d_add() in documentation and
 [PATCH 47/53] VFS: make d_alloc() local to VFS.
 [PATCH 48/53] VFS: remove d_add()
 [PATCH 49/53] VFS: remove d_rehash()
 [PATCH 50/53] VFS: remove lookup_one() and lookup_noperm()
 [PATCH 51/53] VFS: use d_alloc_parallel() in lookup_one_qstr_excl().
 [PATCH 52/53] VFS: lift d_alloc_parallel above inode_lock
 [PATCH 53/53] VFS: remove LOOKUP_SHARED

^ permalink raw reply


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox