kern/164261: [patch] fix panic with NFS served from NULLFS
kostikbel at gmail.com
Wed Jan 18 04:51:03 UTC 2012
On Wed, Jan 18, 2012 at 12:28:53AM +0400, Eygene Ryabinkin wrote:
> >Number: 164261
> >Category: kern
> >Synopsis: [patch] fix panic with NFS served from NULLFS
> >Confidential: no
> >Severity: serious
> >Priority: medium
> >Responsible: freebsd-bugs
> >State: open
> >Class: sw-bug
> >Submitter-Id: current-users
> >Arrival-Date: Tue Jan 17 20:40:14 UTC 2012
> >Originator: Eygene Ryabinkin
> >Release: FreeBSD 10.0-CURRENT amd64
> Code Labs
> System: FreeBSD 10.0-CURRENT, FreeBSD 9.0-STABLE
> When one exports NULLFS filesystems via NFS, he can face kernel
> panics if external clients use readdir+ feature and are accessing
> same directories simultaneously.
> The example of the backtrace can be obtained at
> This backtrace is from 9.x as of December 2011.
> The real problem is that the thread that loses the race in
> null_nodeget (/sys/fs/nullfs/null_subr.c) will put the native lock
> (vp->v_vnlock = &vp->v_lock) to the nullfs vnode that should be
> destroyed (because the thread lost the race). And null_reclaim
> (/sys/fs/nullfs/null_vnops.c) will try to lock vnode's v_lock in the
> exclusive mode. This will lead to panic, because v_vnlock is already
> locked at the time of VOP_RECLAIM processing and we have v_vnlock that
> points to v_lock. Bingo!
> See http://codelabs.ru/fbsd/prs/2012-jan-nullfs-LK_SHARED/README.txt
> section "How to reproduce".
This one is probably fine, assuming that the hashes are properly cleared
on unmount. Feel free to commit.
> will fix the problem (in reality, the first patch is just some
And I do not even read this.
The issue that the backtrace is pointing to seems to be the misuse of vrele(),
after the vnode lock is switched to null vnode v_lock. Since the vnode that
is being thrown out is exclusively locked, cleanup path shall do vput()
instead of vrele().
Despite above, vrele(lowervp) call is be fine, despite lowervp also
being locked exclusively, because usecount for the vnode must be > 1,
due to null_hashins() successfully found the ovp in the hash.
Try the change below.
diff --git a/sys/fs/nullfs/null_subr.c b/sys/fs/nullfs/null_subr.c
index 319e404..6ba7508 100644
@@ -252,7 +252,7 @@ null_nodeget(mp, lowervp, vpp)
vp->v_vnlock = &vp->v_lock;
xp->null_lowervp = NULL;
*vpp = vp;
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Size: 196 bytes
Desc: not available
Url : http://lists.freebsd.org/pipermail/freebsd-fs/attachments/20120118/ae55a2ac/attachment.pgp
More information about the freebsd-fs