summaryrefslogtreecommitdiff
path: root/sys/kern/vfs_default.c
diff options
context:
space:
mode:
authorAlexander Bluhm <bluhm@cvs.openbsd.org>2007-09-15 19:22:19 +0000
committerAlexander Bluhm <bluhm@cvs.openbsd.org>2007-09-15 19:22:19 +0000
commit1048dee18994bd356dfb09463e60f9821548f834 (patch)
tree03c94ee72b9ce47147e46463c1f1eb079fdfa6b0 /sys/kern/vfs_default.c
parent288752b760425fddc6fe00d317697ef966764b4c (diff)
Allow to pull out an usb stick with ffs filesystem while mounted
and a file is written onto the stick. Without these fixes the machine panics or hangs. The usb fix calls the callback when the stick is pulled out to free the associated buffers. Otherwise we have busy buffers for ever and the automatic unmount will panic. The change in the scsi layer prevents passing down further dirty buffers to usb after the stick has been deactivated. In vfs the automatic unmount has moved from the function vgonel() to vop_generic_revoke(). Both are called when the sd device's vnode is removed. In vgonel() the VXLOCK is already held which can cause a deadlock. So call dounmount() earlier. ok krw@, I like this marco@, tested by ian@
Diffstat (limited to 'sys/kern/vfs_default.c')
-rw-r--r--sys/kern/vfs_default.c14
1 files changed, 13 insertions, 1 deletions
diff --git a/sys/kern/vfs_default.c b/sys/kern/vfs_default.c
index b36090ffcb7..df06e7a0358 100644
--- a/sys/kern/vfs_default.c
+++ b/sys/kern/vfs_default.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: vfs_default.c,v 1.34 2007/06/01 23:47:56 deraadt Exp $ */
+/* $OpenBSD: vfs_default.c,v 1.35 2007/09/15 19:22:18 bluhm Exp $ */
/*
* Portions of this code are:
@@ -68,6 +68,18 @@ vop_generic_revoke(void *v)
vp = ap->a_vp;
+ if (vp->v_type == VBLK && vp->v_specinfo != 0) {
+ struct mount *mp = vp->v_specmountpoint;
+
+ /*
+ * If we have a mount point associated with the vnode, we must
+ * flush it out now, as to not leave a dangling zombie mount
+ * point laying around in VFS.
+ */
+ if (mp != NULL && !vfs_busy(mp, VB_WRITE|VB_WAIT))
+ dounmount(mp, MNT_FORCE | MNT_DOOMED, p, NULL);
+ }
+
if (vp->v_flag & VALIASED) {
/*
* If a vgone (or vclean) is already in progress,