Subject: Re: [solution] 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/30/2003 16:14:06
On Fri, 28 Mar 2003, Greg Troxel wrote:
> No. It's coda's issue. From another part of vnode_if.src:
>
> # For operations other than VOP_LOOKUP which require a component name
> # parameter, the flags required for the initial namei() call are listed.
> # Additional flags may be added to the namei() call, but these are required.
>
> which I take to mean you may get other flags. If you don't want them, be
> defensive.
>
> I read it otherwise, saying that you have to call namei with some
> flags, but you can put other flags on the namei call if you have some
> reason. The issue I'm talking about is whether it is ok to have
> random flags, such as LOCKPARENT, set on random vnodeops . And if so,
> whether they have the described semantics (the notion of LOCKPARENT
> makes sense for VOP_SYMLINK), or are _required to be ignored_ by the
> vnodeop. Currently, flags like LOCKPARENT appear to be ignored
> (leaving VOP_LOOKUP aside as a special case).
The vnode op should behave as described in vnode_if.src. For symlink, it
is defined to return with the parent unlocked, not with the parent's state
as set by the absense of LOCKPARENT. VOP_LOOKUP is the only call AFAIK
that is defined to respect LOCKPARENT.
> ufs_symlink, for example, does not respect the LOCKPARENT flag; the
> vput is buried deep in ufs_makeinode. ufs_mkdir is similar.
>
> The top half of the structure is used exclusively for the
> pathname lookups using VOP_LOOKUP() and is initialised by the
> caller.
>
> This is the place where it says that operations other than lookup have
> to ignore the flags.
>
> In the coda_symlink case, LOCKPARENT was on the namei call before
> VOP_SYMLINK, as required. coda_symlink should ignore LOCKPARENT, and
> thus can't just use the componentname to do a lookup. The bug is
> arguably in the new coda_symlink code, since VOP_LOOKUP is now called
> with the same componentname structure passed to VOP_SYMLINK.
I agree with the last part - it's coda_symlink's problem.
> The unintended consequences (leaving the parent locked) of reusing
> componentname like this violates the Principle of Least Astonishment,
> and I think it is unclean. Flags that are defined to be ignored
> shouldn't be set, and perhaps a #ifdef DIAGNOSTIC_EXTRA_PARANOID in
Uhm, that means they aren't being ignored. :-)
> vnode_if.c to check for them. This issue is quite common in
> kern/vfs_syscalls.c, though. Arguably it is just plain wrong to call
> lookup reusing a componentname struct one was passed.
>
> The LOCKPARENT issue is purely stylistic; with the &= ~LOCKPARENT in
> coda_symlink I am not aware of any incorrect behavior.
>
> Cool! Then this is probably the way to go!
>
> I think you are saying that you like the patch to coda_symlink, and
> that sys_symlink is correct. Committing the coda_symlink patch would
> be nice; the current code is certainly incorrect, although without the
> complication of cfs the bug seems not to be triggered.
I think that the coda_symlink change needs to happen, and that sys_symlink
is not wrong.
Take care,
Bill