Subject: Re: vnode refcount panic, perhaps due to kern/vfs_lookup.c:lookup()
To: Greg Troxel <gdt@ir.bbn.com>
From: Bill Studenmund <wrstuden@netbsd.org>
List: tech-kern
Date: 03/14/2003 14:24:59
On 14 Mar 2003, Greg Troxel wrote:
> I just read some more code, and noticed that
> coda/coda_vfsops.c:coda_symlink() calls vput just before calling
> lookup. From what I can tell, lookup expects that the vnode passed in
> is both locked and referenced, so this seems just plain wrong. So it
> may be that there were two locks on the same vnode in lookup, and that
> code is correct. But, I really don't understand vfs/vnode rules very
> well.
lookup() is complicated, but it isn't that bad.
Here's how VOP_LOOKUP()'s locking is described in vnode_if.src:
# XXX - the lookup locking protocol defies simple description and depends
# on the flags and operation fields in the (cnp) structure. Note
# especially that *vpp may equal dvp and both may be locked.
#
# More details:
# There are three types of lookups: ".", ".." (ISDOTDOT), and other.
# On successful lookup of ".", a reference is added to dvp, and it
# is returned in *vpp.
# To look up ISDOTDOT, dvp is unlocked, the ".." node is locked, and
# then dvp is relocked iff LOCKPARENT is set and this is the last
# component name (ISLASTCN set). This preserves the
# protocol of always locking nodes from root ("/") downward and
# prevents deadlock.
# Other lookups find the named node (creating the vnode if needed) and
# return it, locked, in *vpp.
# For non-"." lookups, if LOCKPARENT is not set or this was not the
# last component name, dvp is returned unlocked on a successful
# lookup.
# On failure, *vpp is NULL, and *dvp is usually left locked. If there was
# an error re-locking dvp (for instance in the ISDOTDOT case),
# or dvp was not re-locked for some other reason, the error is
# returned and the PDIRUNLOCK flag is set.
#
# *vpp is always locked on return if the operation succeeds.
# typically, if *vpp == dvp, you need to release twice, but unlock once.
#
# The PDIRUNLOCK flag is set when dvp is unlocked in the lookup routine.
# It signals the caller that dvp's lock state changed. It will
# be set on exit if either a successful lookup unlocked the
# parrent, there was an error re-locking dvp in the ISDOTDOT case,
# or if there was some other error and the lookup routine did
# not re-lock dvp.
The only time that *vpp and dvp should match is if you're looking up '.',
which you aren't.
Something looks wrong...
Take care,
Bill