kern/133439: [vfs][panic] Kernel Panic in kern_vfs
Keith Sklower
sklower at vangogh.CS.Berkeley.EDU
Tue Apr 7 08:40:06 PDT 2009
The following reply was made to PR kern/133439; it has been noted by GNATS.
From: Keith Sklower <sklower at vangogh.CS.Berkeley.EDU>
To: bug-followup at FreeBSD.org, Jhickey at isi.edu
Cc:
Subject: Re: kern/133439: [vfs][panic] Kernel Panic in kern_vfs
Date: Tue, 7 Apr 2009 08:03:38 -0700 (PDT)
I would have otherwise entitled this :
VFS_CHECKEXP inherently unsafe, even in 7.2 Beta?
I'm writing after having been one of the users inconvenienced by the crashes
reported by John Hickey in Problem report kerne/133439 who hypothesized
that the panics were caused by referencing memory in an 8-way CPU
in nfsrv_fhtovp that had been freed while revising the export list.
I have some historical connection to this code, having written the
original radix tree implementation, proposing its use to Kirk Mckusick for
nfs exports, and providing him the 30 lines or so of code that at
the time were need to switch from hash lists to the tree;
so I was intensely curious about the nature of the crash.
I spent a few hours enjoying some code spelunking yesterday afternoon,
and have the following impressions:
The VFS_CHECKEXP handle takes as inputs a mount point, and a network
address, and returns as output flags which are written into storage
provided by the caller, and a pointer to an internal u_cred which resides`
in storage provided by the the file system underneath, and not by the caller.
When the underlying interface handle is vfs_stdcheckexp, although
FreeBSD 7.2 improves the locking around looking up the the appropriate
credential, once that critical section is exited, nothing prevents
another kernel thread from freeing the netred element that encompasses
that credential.
This leaves us with 3 unfortunate choices:
1.) Acknowledging that the interface is SMP-unsafe and requiring
anybody using VFS_CHECKEXP to explicitly call
lockmgr(&mp->mnt_explock, LK_EXCLUSIVE, NULL, curthread);
and release it once having copied the u_cred structure
(and, of course removing the lockmgr calls from vfs_stdcheckexp()
so that it doesn't deadlock against itself)
or
2.) changing the definition of VFS_CHECKEXP so that the *caller*
provides storage for it to copy the u_cred structure into.
or
3.) defining a new handle in the interface, e.g. VFS_CHECKFREE so that
VFS_CHECKEXP can lock the specific opaque elment returned, and
VFS_CHECKFREE would unlock and do the actual freeing of it if
it has evaporated since being looked up, analogous to the way
rtalloc() and RTFREE() work. (which actually work by reference
counts).
I leave to your judgement which of the three to pick.
Regards,
Keith Sklower
P.S.
Given the comment at the bottom of vfs_export() in 7.2
I would recommend moving the
lockmgr(&mp->mnt_explock, LK_RELEASE, NULL, curthread);
from immediately after out:
to immediately before the return(error);
More information about the freebsd-bugs
mailing list