diff options
author | Artur Grabowski <art@cvs.openbsd.org> | 1999-09-03 18:18:17 +0000 |
---|---|---|
committer | Artur Grabowski <art@cvs.openbsd.org> | 1999-09-03 18:18:17 +0000 |
commit | 0538511c0a9248c3acf6f202cb2d448bc59f1344 (patch) | |
tree | 8d15bd0bc1db8bf625598d627f47f79aebc2ce29 /sys/ufs | |
parent | d73b291db7c33b3ed8bbd893de34e58c1865387a (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/ufs')
-rw-r--r-- | sys/ufs/mfs/mfs_vfsops.c | 43 |
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); +} |