Re: [PATCH v4 0/7]] VFS: Prepare to lift lookup out of exclusive lock for directory ops
From: Jeff Layton
Date: Thu Apr 30 2026 - 03:50:45 EST
On Thu, 2026-04-30 at 12:03 +1000, NeilBrown wrote:
> Following are 7 VFS patches which modify or introduce APIs that will
> allow modifying filesystems so that they will work with a proposed
> change to move d_alloc_paralle() out from the parent i_rw_sem lock.
>
> If these can land in a non-rebasing tree, I can work with individual
> filesystem maintainers to start using these APIs.
>
> I haven't included d_alloc_noblock_return() as it is only needed for one
> fs (ovl) and it is not yet clear that it is the best approach.
>
> I also haven't included the change to d_alloc_name() as that is only
> needed so that I can deprecate d_alloc() and there is no rush for that.
>
> Patch 2/7 is exactly the patch Al proposed in the conversation for v3.
> I have taken the libery of adding a Signed-off-by from Al to match the
> Co-developed-by. I hope that was not inappropriate.
>
> I have been testing this series over NFS mounts from XFS so patches 2
> and 3 don't seem to be causing any problems. The changes in 4/5/6/7
> won't be tested by this, and some cannot be tested until filesystems
> start using new interfaces.
>
> Thanks,
> NeilBrown
>
>
> [PATCH v4 1/7] VFS: fix various typos in documentation for
> [PATCH v4 2/7] VFS: use wait_var_event for waiting in
> [PATCH v4 3/7] VFS: enhance d_splice_alias() to handle in-lookup
> [PATCH v4 4/7] VFS: introduce d_alloc_noblock()
> [PATCH v4 5/7] VFS: add d_duplicate()
> [PATCH v4 6/7] VFS: Add LOOKUP_SHARED flag.
> [PATCH v4 7/7] VFS/xfs/ntfs: drop parent lock across
I pointed Claude at the version of this in your tree and it spotted a
regression that I think looks legitimate:
2. Lock imbalance on early return: The parent lock is dropped unconditionally before
d_alloc_parallel()/d_alloc(), but three early return paths exit without reacquiring it:
- IS_ERR(found) from d_alloc_parallel()
- !d_in_lookup(found) from d_alloc_parallel()
- !found from d_alloc()
The callers (lookup_slow(), lookup_slow_killable()) unconditionally call inode_unlock_shared()
after ->lookup() returns. If d_add_ci() returns without the lock held, the caller unlocks an
unheld rwsem — corrupting its state.
Cheers,
--
Jeff Layton <jlayton@xxxxxxxxxx>