Fix some panics while trying to umount a smbfs share.

Be sure that no other active vnodes remains, before trying to release
the root one. Likewise, do not destroy the smbmount specific structure
if the umount will fail (busy conditions).

No objection from pooka@.
This commit is contained in:
njoly 2009-07-02 16:17:52 +00:00
parent 7146d4f874
commit 84a85be4f9
2 changed files with 14 additions and 13 deletions

View File

@ -1,4 +1,4 @@
/* $NetBSD: smbfs_node.c,v 1.40 2009/03/14 21:04:24 dsl Exp $ */
/* $NetBSD: smbfs_node.c,v 1.41 2009/07/02 16:17:52 njoly Exp $ */
/*
* Copyright (c) 2000-2001 Boris Popov
@ -35,7 +35,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: smbfs_node.c,v 1.40 2009/03/14 21:04:24 dsl Exp $");
__KERNEL_RCSID(0, "$NetBSD: smbfs_node.c,v 1.41 2009/07/02 16:17:52 njoly Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@ -244,8 +244,6 @@ smbfs_reclaim(void *v)
SMBVDEBUG("%.*s,%d\n", (int) np->n_nmlen, np->n_name, vp->v_usecount);
KASSERT((np->n_flag & NOPEN) == 0);
mutex_enter(&smp->sm_hashlock);
dvp = (np->n_parent && (np->n_flag & NREFPARENT)) ?

View File

@ -1,4 +1,4 @@
/* $NetBSD: smbfs_vfsops.c,v 1.87 2008/12/17 20:51:35 cegger Exp $ */
/* $NetBSD: smbfs_vfsops.c,v 1.88 2009/07/02 16:17:52 njoly Exp $ */
/*
* Copyright (c) 2000-2001, Boris Popov
@ -35,7 +35,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: smbfs_vfsops.c,v 1.87 2008/12/17 20:51:35 cegger Exp $");
__KERNEL_RCSID(0, "$NetBSD: smbfs_vfsops.c,v 1.88 2009/07/02 16:17:52 njoly Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@ -231,17 +231,16 @@ smbfs_unmount(struct mount *mp, int mntflags)
struct lwp *l = curlwp;
struct smbmount *smp = VFSTOSMBFS(mp);
struct smb_cred scred;
struct vnode *smbfs_rootvp = SMBTOV(smp->sm_root);
int error, flags;
SMBVDEBUG("smbfs_unmount: flags=%04x\n", mntflags);
flags = 0;
if (mntflags & MNT_FORCE)
flags |= FORCECLOSE;
/* Drop the extra reference to root vnode. */
if (smp->sm_root) {
vrele(SMBTOV(smp->sm_root));
smp->sm_root = NULL;
}
if (smbfs_rootvp->v_usecount > 1 && (mntflags & MNT_FORCE) == 0)
return EBUSY;
/* Flush all vnodes.
* Keep trying to flush the vnode list for the mount while
@ -252,8 +251,12 @@ smbfs_unmount(struct mount *mp, int mntflags)
* sufficient in this case. */
do {
smp->sm_didrele = 0;
error = vflush(mp, NULLVP, flags);
error = vflush(mp, smbfs_rootvp, flags);
} while (error == EBUSY && smp->sm_didrele != 0);
if (error)
return error;
vgone(smbfs_rootvp);
smb_makescred(&scred, l, l->l_cred);
smb_share_lock(smp->sm_share);
@ -263,7 +266,7 @@ smbfs_unmount(struct mount *mp, int mntflags)
hashdone(smp->sm_hash, HASH_LIST, smp->sm_hashlen);
mutex_destroy(&smp->sm_hashlock);
free(smp, M_SMBFSDATA);
return error;
return 0;
}
/*