Thu Jul 2 16:17:52 2009 UTC ()
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@.


(njoly)
diff -r1.40 -r1.41 src/sys/fs/smbfs/smbfs_node.c
diff -r1.87 -r1.88 src/sys/fs/smbfs/smbfs_vfsops.c

cvs diff -r1.40 -r1.41 src/sys/fs/smbfs/Attic/smbfs_node.c (expand / switch to unified diff)

--- src/sys/fs/smbfs/Attic/smbfs_node.c 2009/03/14 21:04:24 1.40
+++ src/sys/fs/smbfs/Attic/smbfs_node.c 2009/07/02 16:17:52 1.41
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: smbfs_node.c,v 1.40 2009/03/14 21:04:24 dsl Exp $ */ 1/* $NetBSD: smbfs_node.c,v 1.41 2009/07/02 16:17:52 njoly Exp $ */
2 2
3/* 3/*
4 * Copyright (c) 2000-2001 Boris Popov 4 * Copyright (c) 2000-2001 Boris Popov
5 * All rights reserved. 5 * All rights reserved.
6 * 6 *
7 * Redistribution and use in source and binary forms, with or without 7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions 8 * modification, are permitted provided that the following conditions
9 * are met: 9 * are met:
10 * 1. Redistributions of source code must retain the above copyright 10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer. 11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright 12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the 13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution. 14 * documentation and/or other materials provided with the distribution.
@@ -25,27 +25,27 @@ @@ -25,27 +25,27 @@
25 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 25 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
26 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 26 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 27 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
28 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 28 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 29 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 30 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 31 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32 * SUCH DAMAGE. 32 * SUCH DAMAGE.
33 * 33 *
34 * FreeBSD: src/sys/fs/smbfs/smbfs_node.c,v 1.5 2001/12/20 22:42:26 dillon Exp 34 * FreeBSD: src/sys/fs/smbfs/smbfs_node.c,v 1.5 2001/12/20 22:42:26 dillon Exp
35 */ 35 */
36 36
37#include <sys/cdefs.h> 37#include <sys/cdefs.h>
38__KERNEL_RCSID(0, "$NetBSD: smbfs_node.c,v 1.40 2009/03/14 21:04:24 dsl Exp $"); 38__KERNEL_RCSID(0, "$NetBSD: smbfs_node.c,v 1.41 2009/07/02 16:17:52 njoly Exp $");
39 39
40#include <sys/param.h> 40#include <sys/param.h>
41#include <sys/systm.h> 41#include <sys/systm.h>
42#include <sys/kernel.h> 42#include <sys/kernel.h>
43#include <sys/lock.h> 43#include <sys/lock.h>
44#include <sys/malloc.h> 44#include <sys/malloc.h>
45#include <sys/mount.h> 45#include <sys/mount.h>
46#include <sys/namei.h> 46#include <sys/namei.h>
47#include <sys/proc.h> 47#include <sys/proc.h>
48#include <sys/queue.h> 48#include <sys/queue.h>
49#include <sys/sysctl.h> 49#include <sys/sysctl.h>
50#include <sys/time.h> 50#include <sys/time.h>
51#include <sys/vnode.h> 51#include <sys/vnode.h>
@@ -234,28 +234,26 @@ smbfs_reclaim(void *v) @@ -234,28 +234,26 @@ smbfs_reclaim(void *v)
234 struct vnode *a_vp; 234 struct vnode *a_vp;
235 struct thread *a_p; 235 struct thread *a_p;
236 } */ *ap = v; 236 } */ *ap = v;
237 struct vnode *vp = ap->a_vp; 237 struct vnode *vp = ap->a_vp;
238 struct vnode *dvp; 238 struct vnode *dvp;
239 struct smbnode *np = VTOSMB(vp); 239 struct smbnode *np = VTOSMB(vp);
240 struct smbmount *smp = VTOSMBFS(vp); 240 struct smbmount *smp = VTOSMBFS(vp);
241 241
242 if (prtactive && vp->v_usecount > 1) 242 if (prtactive && vp->v_usecount > 1)
243 vprint("smbfs_reclaim(): pushing active", vp); 243 vprint("smbfs_reclaim(): pushing active", vp);
244 244
245 SMBVDEBUG("%.*s,%d\n", (int) np->n_nmlen, np->n_name, vp->v_usecount); 245 SMBVDEBUG("%.*s,%d\n", (int) np->n_nmlen, np->n_name, vp->v_usecount);
246 246
247 KASSERT((np->n_flag & NOPEN) == 0); 
248 
249 mutex_enter(&smp->sm_hashlock); 247 mutex_enter(&smp->sm_hashlock);
250 248
251 dvp = (np->n_parent && (np->n_flag & NREFPARENT)) ? 249 dvp = (np->n_parent && (np->n_flag & NREFPARENT)) ?
252 np->n_parent : NULL; 250 np->n_parent : NULL;
253 251
254 LIST_REMOVE(np, n_hash); 252 LIST_REMOVE(np, n_hash);
255 253
256 cache_purge(vp); 254 cache_purge(vp);
257 if (smp->sm_root == np) { 255 if (smp->sm_root == np) {
258 SMBVDEBUG0("root vnode\n"); 256 SMBVDEBUG0("root vnode\n");
259 smp->sm_root = NULL; 257 smp->sm_root = NULL;
260 } 258 }
261 genfs_node_destroy(vp); 259 genfs_node_destroy(vp);

cvs diff -r1.87 -r1.88 src/sys/fs/smbfs/Attic/smbfs_vfsops.c (expand / switch to unified diff)

--- src/sys/fs/smbfs/Attic/smbfs_vfsops.c 2008/12/17 20:51:35 1.87
+++ src/sys/fs/smbfs/Attic/smbfs_vfsops.c 2009/07/02 16:17:52 1.88
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: smbfs_vfsops.c,v 1.87 2008/12/17 20:51:35 cegger Exp $ */ 1/* $NetBSD: smbfs_vfsops.c,v 1.88 2009/07/02 16:17:52 njoly Exp $ */
2 2
3/* 3/*
4 * Copyright (c) 2000-2001, Boris Popov 4 * Copyright (c) 2000-2001, Boris Popov
5 * All rights reserved. 5 * All rights reserved.
6 * 6 *
7 * Redistribution and use in source and binary forms, with or without 7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions 8 * modification, are permitted provided that the following conditions
9 * are met: 9 * are met:
10 * 1. Redistributions of source code must retain the above copyright 10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer. 11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright 12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the 13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution. 14 * documentation and/or other materials provided with the distribution.
@@ -25,27 +25,27 @@ @@ -25,27 +25,27 @@
25 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 25 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
26 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 26 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 27 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
28 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 28 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 29 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 30 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 31 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32 * SUCH DAMAGE. 32 * SUCH DAMAGE.
33 * 33 *
34 * FreeBSD: src/sys/fs/smbfs/smbfs_vfsops.c,v 1.5 2001/12/13 13:08:34 sheldonh Exp 34 * FreeBSD: src/sys/fs/smbfs/smbfs_vfsops.c,v 1.5 2001/12/13 13:08:34 sheldonh Exp
35 */ 35 */
36 36
37#include <sys/cdefs.h> 37#include <sys/cdefs.h>
38__KERNEL_RCSID(0, "$NetBSD: smbfs_vfsops.c,v 1.87 2008/12/17 20:51:35 cegger Exp $"); 38__KERNEL_RCSID(0, "$NetBSD: smbfs_vfsops.c,v 1.88 2009/07/02 16:17:52 njoly Exp $");
39 39
40#include <sys/param.h> 40#include <sys/param.h>
41#include <sys/systm.h> 41#include <sys/systm.h>
42#include <sys/proc.h> 42#include <sys/proc.h>
43#include <sys/buf.h> 43#include <sys/buf.h>
44#include <sys/kernel.h> 44#include <sys/kernel.h>
45#include <sys/dirent.h> 45#include <sys/dirent.h>
46#include <sys/sysctl.h> 46#include <sys/sysctl.h>
47#include <sys/vnode.h> 47#include <sys/vnode.h>
48#include <sys/mount.h> 48#include <sys/mount.h>
49#include <sys/stat.h> 49#include <sys/stat.h>
50#include <sys/malloc.h> 50#include <sys/malloc.h>
51#include <sys/kauth.h> 51#include <sys/kauth.h>
@@ -221,59 +221,62 @@ smbfs_mount(struct mount *mp, const char @@ -221,59 +221,62 @@ smbfs_mount(struct mount *mp, const char
221 "//%s@%s/%s", vcp->vc_username, vcp->vc_srvname, ssp->ss_name); 221 "//%s@%s/%s", vcp->vc_username, vcp->vc_srvname, ssp->ss_name);
222 222
223 vfs_getnewfsid(mp); 223 vfs_getnewfsid(mp);
224 return (0); 224 return (0);
225} 225}
226 226
227/* Unmount the filesystem described by mp. */ 227/* Unmount the filesystem described by mp. */
228int 228int
229smbfs_unmount(struct mount *mp, int mntflags) 229smbfs_unmount(struct mount *mp, int mntflags)
230{ 230{
231 struct lwp *l = curlwp; 231 struct lwp *l = curlwp;
232 struct smbmount *smp = VFSTOSMBFS(mp); 232 struct smbmount *smp = VFSTOSMBFS(mp);
233 struct smb_cred scred; 233 struct smb_cred scred;
 234 struct vnode *smbfs_rootvp = SMBTOV(smp->sm_root);
234 int error, flags; 235 int error, flags;
235 236
236 SMBVDEBUG("smbfs_unmount: flags=%04x\n", mntflags); 237 SMBVDEBUG("smbfs_unmount: flags=%04x\n", mntflags);
237 flags = 0; 238 flags = 0;
238 if (mntflags & MNT_FORCE) 239 if (mntflags & MNT_FORCE)
239 flags |= FORCECLOSE; 240 flags |= FORCECLOSE;
240 /* Drop the extra reference to root vnode. */ 241
241 if (smp->sm_root) { 242 if (smbfs_rootvp->v_usecount > 1 && (mntflags & MNT_FORCE) == 0)
242 vrele(SMBTOV(smp->sm_root)); 243 return EBUSY;
243 smp->sm_root = NULL; 
244 } 
245 244
246 /* Flush all vnodes. 245 /* Flush all vnodes.
247 * Keep trying to flush the vnode list for the mount while  246 * Keep trying to flush the vnode list for the mount while
248 * some are still busy and we are making progress towards 247 * some are still busy and we are making progress towards
249 * making them not busy. This is needed because smbfs vnodes 248 * making them not busy. This is needed because smbfs vnodes
250 * reference their parent directory but may appear after their 249 * reference their parent directory but may appear after their
251 * parent in the list; one pass over the vnode list is not 250 * parent in the list; one pass over the vnode list is not
252 * sufficient in this case. */ 251 * sufficient in this case. */
253 do { 252 do {
254 smp->sm_didrele = 0; 253 smp->sm_didrele = 0;
255 error = vflush(mp, NULLVP, flags); 254 error = vflush(mp, smbfs_rootvp, flags);
256 } while (error == EBUSY && smp->sm_didrele != 0); 255 } while (error == EBUSY && smp->sm_didrele != 0);
 256 if (error)
 257 return error;
 258
 259 vgone(smbfs_rootvp);
257 260
258 smb_makescred(&scred, l, l->l_cred); 261 smb_makescred(&scred, l, l->l_cred);
259 smb_share_lock(smp->sm_share); 262 smb_share_lock(smp->sm_share);
260 smb_share_put(smp->sm_share, &scred); 263 smb_share_put(smp->sm_share, &scred);
261 mp->mnt_data = NULL; 264 mp->mnt_data = NULL;
262 265
263 hashdone(smp->sm_hash, HASH_LIST, smp->sm_hashlen); 266 hashdone(smp->sm_hash, HASH_LIST, smp->sm_hashlen);
264 mutex_destroy(&smp->sm_hashlock); 267 mutex_destroy(&smp->sm_hashlock);
265 free(smp, M_SMBFSDATA); 268 free(smp, M_SMBFSDATA);
266 return error; 269 return 0;
267} 270}
268 271
269/* 272/*
270 * Get root vnode of the smbfs filesystem, and store it in sm_root. 273 * Get root vnode of the smbfs filesystem, and store it in sm_root.
271 */ 274 */
272static int 275static int
273smbfs_setroot(struct mount *mp) 276smbfs_setroot(struct mount *mp)
274{ 277{
275 struct smbmount *smp = VFSTOSMBFS(mp); 278 struct smbmount *smp = VFSTOSMBFS(mp);
276 struct vnode *vp; 279 struct vnode *vp;
277 struct smbfattr fattr; 280 struct smbfattr fattr;
278 struct lwp *l = curlwp; 281 struct lwp *l = curlwp;
279 kauth_cred_t cred = l->l_cred; 282 kauth_cred_t cred = l->l_cred;