summaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authorArtur Grabowski <art@cvs.openbsd.org>1999-09-03 18:18:17 +0000
committerArtur Grabowski <art@cvs.openbsd.org>1999-09-03 18:18:17 +0000
commit0538511c0a9248c3acf6f202cb2d448bc59f1344 (patch)
tree8d15bd0bc1db8bf625598d627f47f79aebc2ce29 /sys
parentd73b291db7c33b3ed8bbd893de34e58c1865387a (diff)
Horrible workaround for hanging mount_mfs processes that received a signal.
After finding the third deadlock during dounmount, I decided that it would be less painful to let the unmounting be handled with a separate thread. XXX - this is a kludge.
Diffstat (limited to 'sys')
-rw-r--r--sys/ufs/mfs/mfs_vfsops.c43
1 files changed, 32 insertions, 11 deletions
diff --git a/sys/ufs/mfs/mfs_vfsops.c b/sys/ufs/mfs/mfs_vfsops.c
index cb01fc418d7..ad415f35cf5 100644
--- a/sys/ufs/mfs/mfs_vfsops.c
+++ b/sys/ufs/mfs/mfs_vfsops.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: mfs_vfsops.c,v 1.8 1999/05/31 17:34:55 millert Exp $ */
+/* $OpenBSD: mfs_vfsops.c,v 1.9 1999/09/03 18:18:16 art Exp $ */
/* $NetBSD: mfs_vfsops.c,v 1.10 1996/02/09 22:31:28 christos Exp $ */
/*
@@ -46,6 +46,7 @@
#include <sys/signalvar.h>
#include <sys/vnode.h>
#include <sys/malloc.h>
+#include <sys/kthread.h>
#include <ufs/ufs/quota.h>
#include <ufs/ufs/inode.h>
@@ -65,6 +66,9 @@ static int mfs_minor; /* used for building internal dev_t */
extern int (**mfs_vnodeop_p) __P((void *));
+int mfs_dounmount __P((struct mount *));
+void mfs_dounmount1 __P((void *));
+
/*
* mfs vfs operations.
*/
@@ -272,16 +276,8 @@ mfs_start(mp, flags, p)
* EINTR/ERESTART.
*/
if (tsleep((caddr_t)vp, mfs_pri, "mfsidl", 0)) {
- /*
- * Don't attempt to unmount when MNT_UNMOUNT is set,
- * that means that someone is waiting for us to
- * finish our operations and it also means that
- * we will sleep until he is finished. deadlock.
- * XXX - there is a multiprocessor race here.
- */
- if ((mp->mnt_flag & MNT_UNMOUNT) ||
- dounmount(mp, 0, p) != 0)
- CLRSIG(p, CURSIG(p));
+ mfs_dounmount(mp);
+ CLRSIG(p, CURSIG(p));
}
}
return (0);
@@ -305,3 +301,28 @@ mfs_statfs(mp, sbp, p)
&sbp->mount_info.mfs_args, sizeof(struct mfs_args));
return (error);
}
+
+/*
+ * Spawn off a kernel thread to do the unmounting to avoid all deadlocks.
+ * XXX - this is horrible, but it was the only sane thing to do.
+ */
+int
+mfs_dounmount(mp)
+ struct mount *mp;
+{
+ if (kthread_create(mfs_dounmount1, (void *)mp, NULL, "mfs_unmount"))
+ return 1;
+
+ return 0;
+}
+
+void
+mfs_dounmount1(v)
+ void *v;
+{
+ struct mount *mp = v;
+
+ dounmount(mp, 0, curproc);
+
+ kthread_exit(0);
+}