Re: [PATCH v2 04/18] nfs: separate locked regions in nfs_clear_verifier_directory()
NeilBrown <[email protected]>
| Newsgroups | gmane.linux.file-systems,gmane.linux.kernel.autofs,gmane.linux.kernel,gmane.comp.file-systems.ceph.devel,gmane.comp.file-systems.coda.general,gmane.linux.nfs |
|---|---|
| Message-ID | <[email protected]> |
On Tue, 25 Aug 2026, Chuck Lever wrote: > On Sat, Aug 15, 2026, at 2:21 PM, NeilBrown wrote: > > nfs_clear_verifier_directory() locks the dir to call > > nfs_unset_verifier_delegated() > > and also to walk the d_children list. > > These are two separate needs and they don't need to both > > be in the same locked region. > > > > Subsequent patches will use a helper for walking the d_children list and > > that helper may drop the lock temporarily. To simplify this transition, > > split the locked range by dropping and retaking the lock between to make > > two separate locked regions. > > I hit this running xfstests against tmpfs with the series applied. The > trigger was incidental (an unrelated process chmod'ed a file on an > NFSv4 mount while xfstests was running) so it is not deterministic, but > the path looks reachable by any SETATTR that returns a delegation on a > directory: > > BUG: sleeping function called from invalid context at fs/nfs/dir.c:1497 > in_atomic(): 1, irqs_disabled(): 0, non_block: 0, pid: 2385380 > preempt_count: 1, expected: 0 > Call Trace: > __might_resched+0x165/0x180 > nfs_clear_verifier_delegated+0x112/0x250 [nfs] > nfs_start_delegation_return+0xa1/0x130 [nfsv4] > nfs4_inode_return_delegation+0x1b/0xf0 [nfsv4] > nfs4_inode_make_writeable+0xa9/0x130 [nfsv4] > nfs4_proc_setattr+0xa2/0xf0 [nfsv4] > nfs_setattr+0x1f2/0x480 [nfs] > notify_change+0x321/0x380 > chmod_common+0x10d/0x1c0 > do_fchmodat+0x8a/0x110 > __x64_sys_chmod+0x1d/0x30 > > Line 1497 is the d_for_each_positive_child() call. Thanks for testing! nfs_clear_verifier_deleted() holds the inode i_lock across nfs_clear_verifier_directory() which walks the the d_children list. I'll need to use d_find_alias() to get the dentry like I did in the notify code. Hopefully I'll send another RFC tomorrow. Thanks, NeilBrown