From owner-freebsd-fs Thu Dec 5 2:22:38 2002 Delivered-To: freebsd-fs@freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id 2B66937B401; Thu, 5 Dec 2002 02:22:37 -0800 (PST) Received: from salmon.maths.tcd.ie (salmon.maths.tcd.ie [134.226.81.11]) by mx1.FreeBSD.org (Postfix) with SMTP id E034543ECD; Thu, 5 Dec 2002 02:22:35 -0800 (PST) (envelope-from iedowse@maths.tcd.ie) Received: from walton.maths.tcd.ie by salmon.maths.tcd.ie with SMTP id ; 5 Dec 2002 10:22:35 +0000 (GMT) To: Tim Robbins Cc: freebsd-fs@freebsd.org Subject: Re: vflush() and dependencies between vnodes In-Reply-To: Your message of "Thu, 05 Dec 2002 13:18:58 +1100." <20021205131858.A54625@dilbert.robbins.dropbear.id.au> Date: Thu, 05 Dec 2002 10:22:34 +0000 From: Ian Dowse Message-ID: <200212051022.aa49886@salmon.maths.tcd.ie> Sender: owner-freebsd-fs@FreeBSD.ORG Precedence: bulk List-ID: List-Archive: (Web Archive) List-Help: (List Instructions) List-Subscribe: List-Unsubscribe: X-Loop: FreeBSD.org 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. I have noticed panics recently when forcefully unmounting nfs filesystems, so there may be a more general problem here (I have some local changes that KASSERT that a vnode is unlocked when its last reference is vrele()'d, and I use vop_stdlock for nfs - the KASSERT often triggers after a forceful unmount, suggesting that something is doing too many vrele()'s and missing an unlock). Ian To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-fs" in the body of the message