Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 7 Dec 2002 10:59:23 +1100
From:      Tim Robbins <tjr@FreeBSD.ORG>
To:        Ian Dowse <iedowse@maths.tcd.ie>
Cc:        freebsd-fs@FreeBSD.ORG
Subject:   Re: vflush() and dependencies between vnodes
Message-ID:  <20021207105923.A57199@dilbert.robbins.dropbear.id.au>
In-Reply-To: <200212051022.aa49886@salmon.maths.tcd.ie>; from iedowse@maths.tcd.ie on Thu, Dec 05, 2002 at 10:22:34AM %2B0000
References:  <20021205131858.A54625@dilbert.robbins.dropbear.id.au> <200212051022.aa49886@salmon.maths.tcd.ie>

next in thread | previous in thread | raw e-mail | index | archive | help
On Thu, Dec 05, 2002 at 10:22:34AM +0000, Ian Dowse wrote:

> In message <20021205131858.A54625@dilbert.robbins.dropbear.id.au>, Tim Robbins 
> writes:
> >I've spent the past couple of days tracking down the bug that caused
> >umount -f on smbfs to panic, and umount without -f to often give EBUSY
> >when it should not have.
> >
> >smbfs stores a pointer to each file or directory's parent directory in
> >the smbnode struct and vref()'s the parent directory's vnode. This means
> >that an smbfs directory vnode cannot be removed before all of its
> >children have vrele()'d it. However, vflush() iterates through the
> >mount's vnode list from start to end, so if a directory vnode appears
> >in the list before its children, it will not be removed. This causes a
> >panic when umount -f is used because smbfs_reclaim() calls vrele() on the
> >parent vnode after it has already been freed. This also causes umount
> >without -f to erroneously return EBUSY.
> 
> >Can anyone think of a better way to solve this problem than to keep
> >rescanning the mount's vnode list until no more vnodes can be freed,
> >like the patch below does?
> 
> I think for the non-forced case, an approach like this is quite a
> reasonable solution to avoid the EBUSY errors. For the forced case
> it shouldn't be necessary though - vnodes are not freed until the
> last reference is dropped, so even if a referenced vnode gets killed
> before the vnode that references it, calling vrele() on the original
> vnode should do the right thing and be safe.

True, there's no need to rescan the mount's vnode list when it's been
forcibly unmounted. All of the "lastpass" logic can probably be removed,
then.

And you're right, it is safe to vrele() the original vnode. The problem
with smbfs is that it stores a pointer to the parent's "smbnode" structure
inside its own, but the parent's smbnode is freed when the parent is
reclaimed. It ends up accessing data that has already been freed since
the parent's vnode is stored inside its smbnode. The solution seems to be
to store a pointer to the parent's vnode inside the childrens' struct smbnodes.


Tim

To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-fs" in the body of the message




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