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:
parent
7146d4f874
commit
84a85be4f9
|
@ -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)) ?
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
Loading…
Reference in New Issue