Re: Why does namei return an exclusively locked vnode when LOCKSHARED is specified?
Date: Tue, 17 Dec 2024 19:27:38 UTC
On Tue, Dec 17, 2024 at 12:19:26PM -0700, Alan Somers wrote: > According to namei(9), namei should return a shared lock when > LOCKSHARED is specified. But in my experiments, it always seems to > return an exclusive lock instead. For example: > > $ cd /usr/tests/sys/fs/fusefs > $ sudo dtrace -i 'fbt:fusefs:fuse_vnop_getattr:entry /pid==$target/ > {printf("islocked=%#x", args[0]->a_vp->v_vnlock->lk_lock); stack();}' > -i 'fbt:kernel:vop_stdstat:entry /pid==$target/ > {printf("islocked=%#x", args[0]->a_vp->v_vnlock->lk_lock);}' -c > "./getattr --gtest_filter=Getattr.attr_cache -v" > [==========] Running 1 test from 1 test suite. > [----------] Global test environment set-up. > [----------] 1 test from Getattr > [ RUN ] Getattr.attr_cache > INIT ino= 0 > ACCESS ino= 1 mask=0x1 > LOOKUP ino= 1 some_file.txt > GETATTR ino=42 > [ OK ] Getattr.attr_cache (3 ms) > [----------] 1 test from Getattr (3 ms total) > > [----------] Global test environment tear-down > [==========] 1 test from 1 test suite ran. (4 ms total) > [ PASSED ] 1 test. > CPU ID FUNCTION:NAME > 3 19743 vop_stdstat:entry islocked=0x21 > 3 19743 vop_stdstat:entry islocked=0xfffff80004f16740 > 3 68298 fuse_vnop_getattr:entry islocked=0xfffff80004f16740 > kernel`VOP_GETATTR_APV+0x90 > kernel`vop_stdstat+0x147 > kernel`VOP_STAT_APV+0x91 > kernel`kern_statat+0x183 > kernel`sys_fstatat+0x27 > kernel`amd64_syscall+0x1af > kernel`0xffffffff8106cd5b > > 3 19743 vop_stdstat:entry islocked=0xfffff80004f16740 > 3 68298 fuse_vnop_getattr:entry islocked=0xfffff80004f16740 > kernel`VOP_GETATTR_APV+0x90 > kernel`vop_stdstat+0x147 > kernel`VOP_STAT_APV+0x91 > kernel`kern_statat+0x183 > kernel`sys_fstatat+0x27 > kernel`amd64_syscall+0x1af > kernel`0xffffffff8106cd5b > > dtrace: pid 3554 has exited > > From that output, the first vop_stdstat is probably for the > mountpoint, and isn't what I'm concerned about. But the second two > are for a fusefs file. The LK_SHARE bit is not set, indicating an > exclusive lock. That's even though the call to namei in kern_statat > specifies LOCKSHARED | LOCKLEAF. > > What am I missing? Having noticed the same phenomenon in p9fs and scratching my head for a while: is fusefs failing to call VN_LOCK_ASHARE() in this case? I see that it's predicated on "data->dataflags & FSESS_ASYNC_READ", but I'm not sure why - the comment seems to suggest a misunderstanding of what VN_LOCK_ASHARE() does. ... oh, also perhaps because fusefs mounts don't set MNTK_LOOKUP_SHARED?