Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 4 Jan 2021 01:11:26 +0000
From:      Rick Macklem <rmacklem@uoguelph.ca>
To:        Konstantin Belousov <kostikbel@gmail.com>
Cc:        J David <j.david.lists@gmail.com>, "freebsd-fs@freebsd.org" <freebsd-fs@freebsd.org>
Subject:   Re: Major issues with nfsv4
Message-ID:  <YQXPR0101MB0968836D68FBBB0C19ACC2B4DDD20@YQXPR0101MB0968.CANPRD01.PROD.OUTLOOK.COM>
In-Reply-To: <X%2BitPGhDz6Vldqh%2B@kib.kiev.ua>
References:  <YQXPR0101MB0968B17010B3B36C8C41FDE1DDC90@YQXPR0101MB0968.CANPRD01.PROD.OUTLOOK.COM> <X9Q9GAhNHbXGbKy7@kib.kiev.ua> <YQXPR0101MB0968C7629D57CA21319E50C2DDC90@YQXPR0101MB0968.CANPRD01.PROD.OUTLOOK.COM> <X9UDArKjUqJVS035@kib.kiev.ua> <CABXB=RRNnW9nNhFCJS1evNUTEX9LNnzyf2gOmZHHGkzAoQxbPw@mail.gmail.com> <YQXPR0101MB0968B120A417AF69CEBB6A12DDC80@YQXPR0101MB0968.CANPRD01.PROD.OUTLOOK.COM> <X9aGwshgh7Cwiv8p@kib.kiev.ua> <CABXB=RTFSAEZvp%2BmoiF%2BrE9vpEjJVacLYa6G=yP641f9oHJ1zw@mail.gmail.com> <YQXPR0101MB09681D2CB8FBD5DDE907D5A5DDC40@YQXPR0101MB0968.CANPRD01.PROD.OUTLOOK.COM> <YQXPR0101MB096897CA4344DFDC8D22DFE9DDDB0@YQXPR0101MB0968.CANPRD01.PROD.OUTLOOK.COM>, <X%2BitPGhDz6Vldqh%2B@kib.kiev.ua>

next in thread | previous in thread | raw e-mail | index | archive | help
Kostik wrote:=0A=
>Rick Macklem wrote:=0A=
[stuff snipped]=0A=
>> I see vfs_deferred_inactive() in sys/kern/vfs_subr.c, but I do not=0A=
>> know when/how it gets called?=0A=
>Right, vfs_deferred_inactive() is one way which tries to handle missed=0A=
>inactivations. If upon vput() the lock is only shared and upgrade=0A=
>failed, vnode is marked as VI_OWEINACT and put onto 'lazy' list,=0A=
>processed by vfs_sync(MNT_LAZY). It is typically called from syncer,=0A=
>which means each 60 secs. There, if the vnode is still unreferenced, it=0A=
>is inactivated.=0A=
If I read the code correctly vfs_deferred_inactive() gets called with=0A=
LK_EXCLUSIVE | LK_NOWAIT | LK_INTERLOCK.=0A=
Then there is this code in nfs_lock():=0A=
        vp =3D ap->a_vp;=0A=
332	        lktype =3D ap->a_flags & LK_TYPE_MASK;=0A=
333	        error =3D VOP_LOCK1_APV(&default_vnodeops, ap);=0A=
334	        if (error !=3D 0 || vp->v_op !=3D &newnfs_vnodeops)=0A=
335	                return (error);=0A=
336	        np =3D VTONFS(vp);=0A=
337	        if (np =3D=3D NULL)=0A=
338	                return (0);=0A=
339	        NFSLOCKNODE(np);=0A=
340	        if ((np->n_flag & NVNSETSZSKIP) =3D=3D 0 || (lktype !=3D LK_SHA=
RED &&=0A=
341	            lktype !=3D LK_EXCLUSIVE && lktype !=3D LK_UPGRADE &&=0A=
342	            lktype !=3D LK_TRYUPGRADE)) {=0A=
343	                NFSUNLOCKNODE(np);=0A=
344	                return (0);=0A=
345	        }=0A=
346	        onfault =3D (ap->a_flags & LK_EATTR_MASK) =3D=3D LK_NOWAIT &&=
=0A=
347	            (ap->a_flags & LK_INIT_MASK) =3D=3D LK_CANRECURSE &&=0A=
348	            (lktype =3D=3D LK_SHARED || lktype =3D=3D LK_EXCLUSIVE);=0A=
349	        if (onfault && vp->v_vnlock->lk_recurse =3D=3D 0) {=0A=
350	                /*=0A=
351	                 * Force retry in vm_fault(), to make the lock request=
=0A=
352	                 * sleepable, which allows us to piggy-back the=0A=
353	                 * sleepable call to vnode_pager_setsize().=0A=
354	                 */=0A=
355	                NFSUNLOCKNODE(np);=0A=
356	                VOP_UNLOCK(vp);=0A=
357	                return (EBUSY);=0A=
358	        }=0A=
Would the above code result in an EBUSY reply when the vn_lock(LK_NOWAIT |=
=0A=
LK_EXCLUSIVE) is made in vfs_deferred_inactive()?=0A=
=0A=
If so, it looks like vfs_periodic_inactive()->vfs_deferred_inactive() will =
just=0A=
call vdefer_inactive_unlocked()->vdefer_inactive() and it will end up=0A=
on the lazy list with VI_DEFINACT set again, if I am reading the=0A=
code correctly?=0A=
=0A=
>Another place where inactivation can occur is reclamation. There in=0A=
>vgonel(), we call VOP_INACTIVE() if VI_OWEINACT is set. In principle,=0A=
>this is redundand because correct filesystem must do the same cleanup=0A=
>(and more) at reclamation as at the inactivation.  But we also call=0A=
>VOP_CLOSE(FNONBLOCK) before VOP_RECLAIM().=0A=
And this would make all the NFSv4 Opens go away (get closed)=0A=
when the nullfs mounts are unmounted, as reported by J. David.=0A=
=0A=
>Looking at this from another angle, if inactivation for NFSv4 vnodes=0A=
>is not called longer than 2 minutes, perhaps there is a reference leak.=0A=
>It is not due to VFS forgetting about due VOP_INACTIVE() call.=0A=
Unless the nfs_lock(LK_NOWAIT) call keeps failing with EBUSY,=0A=
I think?=0A=
=0A=
rick=0A=
ps: I need to find a way to reproduce this.=0A=
=0A=



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?YQXPR0101MB0968836D68FBBB0C19ACC2B4DDD20>