Wed Sep 24 09:33:41 2008 UTC ()
PR kern/39307 mfs will sometimes panic at umount time

In vfs_destroy, assert that the refcount is not dropping below zero.


(ad)
diff -r1.356 -r1.357 src/sys/kern/vfs_subr.c

cvs diff -r1.356 -r1.357 src/sys/kern/vfs_subr.c (expand / switch to unified diff)

--- src/sys/kern/vfs_subr.c 2008/09/07 13:09:36 1.356
+++ src/sys/kern/vfs_subr.c 2008/09/24 09:33:40 1.357
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: vfs_subr.c,v 1.356 2008/09/07 13:09:36 tron Exp $ */ 1/* $NetBSD: vfs_subr.c,v 1.357 2008/09/24 09:33:40 ad Exp $ */
2 2
3/*- 3/*-
4 * Copyright (c) 1997, 1998, 2004, 2005, 2007, 2008 The NetBSD Foundation, Inc. 4 * Copyright (c) 1997, 1998, 2004, 2005, 2007, 2008 The NetBSD Foundation, Inc.
5 * All rights reserved. 5 * All rights reserved.
6 * 6 *
7 * This code is derived from software contributed to The NetBSD Foundation 7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Jason R. Thorpe of the Numerical Aerospace Simulation Facility, 8 * by Jason R. Thorpe of the Numerical Aerospace Simulation Facility,
9 * NASA Ames Research Center, by Charles M. Hannum, and by Andrew Doran. 9 * NASA Ames Research Center, by Charles M. Hannum, and by Andrew Doran.
10 * 10 *
11 * Redistribution and use in source and binary forms, with or without 11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions 12 * modification, are permitted provided that the following conditions
13 * are met: 13 * are met:
14 * 1. Redistributions of source code must retain the above copyright 14 * 1. Redistributions of source code must retain the above copyright
@@ -71,27 +71,27 @@ @@ -71,27 +71,27 @@
71 * 71 *
72 * At nearly all points it is known that v_usecount could be zero, the 72 * At nearly all points it is known that v_usecount could be zero, the
73 * vnode interlock will be held. 73 * vnode interlock will be held.
74 * 74 *
75 * To change v_usecount away from zero, the interlock must be held. To 75 * To change v_usecount away from zero, the interlock must be held. To
76 * change from a non-zero value to zero, again the interlock must be 76 * change from a non-zero value to zero, again the interlock must be
77 * held. 77 * held.
78 * 78 *
79 * Changing the usecount from a non-zero value to a non-zero value can 79 * Changing the usecount from a non-zero value to a non-zero value can
80 * safely be done using atomic operations, without the interlock held. 80 * safely be done using atomic operations, without the interlock held.
81 */ 81 */
82 82
83#include <sys/cdefs.h> 83#include <sys/cdefs.h>
84__KERNEL_RCSID(0, "$NetBSD: vfs_subr.c,v 1.356 2008/09/07 13:09:36 tron Exp $"); 84__KERNEL_RCSID(0, "$NetBSD: vfs_subr.c,v 1.357 2008/09/24 09:33:40 ad Exp $");
85 85
86#include "opt_ddb.h" 86#include "opt_ddb.h"
87#include "opt_compat_netbsd.h" 87#include "opt_compat_netbsd.h"
88#include "opt_compat_43.h" 88#include "opt_compat_43.h"
89 89
90#include <sys/param.h> 90#include <sys/param.h>
91#include <sys/systm.h> 91#include <sys/systm.h>
92#include <sys/proc.h> 92#include <sys/proc.h>
93#include <sys/kernel.h> 93#include <sys/kernel.h>
94#include <sys/mount.h> 94#include <sys/mount.h>
95#include <sys/fcntl.h> 95#include <sys/fcntl.h>
96#include <sys/vnode.h> 96#include <sys/vnode.h>
97#include <sys/stat.h> 97#include <sys/stat.h>
@@ -272,34 +272,35 @@ vfs_getvfs(fsid_t *fsid) @@ -272,34 +272,35 @@ vfs_getvfs(fsid_t *fsid)
272 } 272 }
273 } 273 }
274 mutex_exit(&mountlist_lock); 274 mutex_exit(&mountlist_lock);
275 return ((struct mount *)0); 275 return ((struct mount *)0);
276} 276}
277 277
278/* 278/*
279 * Drop a reference to a mount structure, freeing if the last reference. 279 * Drop a reference to a mount structure, freeing if the last reference.
280 */ 280 */
281void 281void
282vfs_destroy(struct mount *mp) 282vfs_destroy(struct mount *mp)
283{ 283{
284 284
285 if (__predict_true(atomic_dec_uint_nv(&mp->mnt_refcnt) > 0)) { 285 if (__predict_true((int)atomic_dec_uint_nv(&mp->mnt_refcnt) > 0)) {
286 return; 286 return;
287 } 287 }
288 288
289 /* 289 /*
290 * Nothing else has visibility of the mount: we can now 290 * Nothing else has visibility of the mount: we can now
291 * free the data structures. 291 * free the data structures.
292 */ 292 */
 293 KASSERT(mp->mnt_refcnt == 0);
293 specificdata_fini(mount_specificdata_domain, &mp->mnt_specdataref); 294 specificdata_fini(mount_specificdata_domain, &mp->mnt_specdataref);
294 rw_destroy(&mp->mnt_unmounting); 295 rw_destroy(&mp->mnt_unmounting);
295 mutex_destroy(&mp->mnt_updating); 296 mutex_destroy(&mp->mnt_updating);
296 mutex_destroy(&mp->mnt_renamelock); 297 mutex_destroy(&mp->mnt_renamelock);
297 if (mp->mnt_op != NULL) { 298 if (mp->mnt_op != NULL) {
298 vfs_delref(mp->mnt_op); 299 vfs_delref(mp->mnt_op);
299 } 300 }
300 kmem_free(mp, sizeof(*mp)); 301 kmem_free(mp, sizeof(*mp));
301} 302}
302 303
303/* 304/*
304 * grab a vnode from freelist and clean it. 305 * grab a vnode from freelist and clean it.
305 */ 306 */