From 43f2119341f2cf6c2d8a3f3d0ca3a58805522c01 Mon Sep 17 00:00:00 2001 From: ad Date: Thu, 25 Sep 2008 14:17:29 +0000 Subject: [PATCH] PR kern/39307 (mfs will sometimes panic at umount time) Change dounmount() so that it never drops the caller provided reference. Garbage collecting 'struct mount' is up to the caller. --- sys/fs/puffs/puffs_msgif.c | 16 +++++----------- sys/kern/vfs_syscalls.c | 12 +++++------- 2 files changed, 10 insertions(+), 18 deletions(-) diff --git a/sys/fs/puffs/puffs_msgif.c b/sys/fs/puffs/puffs_msgif.c index a7c630535d47..9ce2db836a36 100644 --- a/sys/fs/puffs/puffs_msgif.c +++ b/sys/fs/puffs/puffs_msgif.c @@ -1,4 +1,4 @@ -/* $NetBSD: puffs_msgif.c,v 1.71 2008/05/06 18:43:44 ad Exp $ */ +/* $NetBSD: puffs_msgif.c,v 1.72 2008/09/25 14:17:29 ad Exp $ */ /* * Copyright (c) 2005, 2006, 2007 Antti Kantee. All Rights Reserved. @@ -30,7 +30,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: puffs_msgif.c,v 1.71 2008/05/06 18:43:44 ad Exp $"); +__KERNEL_RCSID(0, "$NetBSD: puffs_msgif.c,v 1.72 2008/09/25 14:17:29 ad Exp $"); #include #include @@ -1018,19 +1018,13 @@ puffs_msgif_close(void *this) } /* Won't access pmp from here anymore */ + atomic_inc_uint((unsigned int*)&mp->mnt_refcnt); puffs_mp_release(pmp); mutex_exit(&pmp->pmp_lock); - /* - * Detach from VFS. First do necessary XXX-dance (from - * sys_unmount() & other callers of dounmount() - * - * XXX2: take a reference to the mountpoint before starting to - * wait for syncer_mutex. Otherwise the mointpoint can be - * wiped out while we wait. XXX Should be done earlier - */ - atomic_inc_uint((unsigned int*)&mp->mnt_refcnt); + /* Detach from VFS. */ (void)dounmount(mp, MNT_FORCE, curlwp); + vfs_destroy(mp); return 0; } diff --git a/sys/kern/vfs_syscalls.c b/sys/kern/vfs_syscalls.c index ce0570279e24..e7677cae9031 100644 --- a/sys/kern/vfs_syscalls.c +++ b/sys/kern/vfs_syscalls.c @@ -1,4 +1,4 @@ -/* $NetBSD: vfs_syscalls.c,v 1.373 2008/09/24 10:07:19 ad Exp $ */ +/* $NetBSD: vfs_syscalls.c,v 1.374 2008/09/25 14:17:29 ad Exp $ */ /*- * Copyright (c) 2008 The NetBSD Foundation, Inc. @@ -63,7 +63,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: vfs_syscalls.c,v 1.373 2008/09/24 10:07:19 ad Exp $"); +__KERNEL_RCSID(0, "$NetBSD: vfs_syscalls.c,v 1.374 2008/09/25 14:17:29 ad Exp $"); #include "opt_compat_netbsd.h" #include "opt_compat_43.h" @@ -695,6 +695,7 @@ sys_unmount(struct lwp *l, const struct sys_unmount_args *uap, register_t *retva vrele(vp); error = dounmount(mp, SCARG(uap, flags), l); + vfs_destroy(mp); return error; } @@ -702,8 +703,7 @@ sys_unmount(struct lwp *l, const struct sys_unmount_args *uap, register_t *retva * Do the actual file system unmount. File system is assumed to have * been locked by the caller. * - * => Caller gain reference to the mount, explicility for unmount. - * => Reference will be dropped in all cases. + * => Caller hold reference to the mount, explicility for dounmount(). */ int dounmount(struct mount *mp, int flags, struct lwp *l) @@ -728,7 +728,6 @@ dounmount(struct mount *mp, int flags, struct lwp *l) if ((mp->mnt_iflag & IMNT_GONE) != 0) { rw_exit(&mp->mnt_unmounting); mutex_exit(&syncer_mutex); - vfs_destroy(mp); return ENOENT; } @@ -787,8 +786,7 @@ dounmount(struct mount *mp, int flags, struct lwp *l) mutex_exit(&syncer_mutex); vfs_hooks_unmount(mp); rw_exit(&mp->mnt_unmounting); - vfs_destroy(mp); /* caller provided reference */ - vfs_destroy(mp); /* from mount(), final nail in coffin */ + vfs_destroy(mp); /* reference from mount() */ if (coveredvp != NULLVP) vrele(coveredvp); return (0);