Re: Why does namei return an exclusively locked vnode when LOCKSHARED is specified?
Date: Tue, 17 Dec 2024 20:02:18 UTC
On Tue, Dec 17, 2024 at 12:27 PM Mark Johnston <markj@freebsd.org> wrote:
>
> 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?
Yes, that's it! Both of those things need to change. Now I can get
on with solving my real bug. Thank you.