summaryrefslogtreecommitdiffstats
path: root/sys/ufs
diff options
context:
space:
mode:
authorpeter <peter@FreeBSD.org>1995-11-28 02:15:29 +0000
committerpeter <peter@FreeBSD.org>1995-11-28 02:15:29 +0000
commit17cfbbe7dfdf8533d89b6d58e8530f8869312b78 (patch)
tree71bf08c00b95cb57bfa2131b3d930bc0e2175922 /sys/ufs
parent3ce680f86e8546763e962f268e5848bf19529ba8 (diff)
downloadFreeBSD-src-17cfbbe7dfdf8533d89b6d58e8530f8869312b78.zip
FreeBSD-src-17cfbbe7dfdf8533d89b6d58e8530f8869312b78.tar.gz
Attempt to solve the busy-buffers-on-shutdown caused by MFS once and for all.
What was happening, was that the main mfs loop was sleeping, and when it was being awoken by a wakeup when it was supposed to process some IO requests. The problem was that if it was being woken out of the tsleep() by a signal at shutdown, it was going straight into dounmount() without servicing any pending IO requests, causing dounmount() to fail because there were busy buffers (and they could not be "processed" because the processing loop was trying to unmount rather than dispatching into mfs_doio()). This (dare I say it :-) appears to be a layering problem....
Diffstat (limited to 'sys/ufs')
-rw-r--r--sys/ufs/mfs/mfs_vfsops.c18
1 files changed, 14 insertions, 4 deletions
diff --git a/sys/ufs/mfs/mfs_vfsops.c b/sys/ufs/mfs/mfs_vfsops.c
index dcc0358..eafc84a 100644
--- a/sys/ufs/mfs/mfs_vfsops.c
+++ b/sys/ufs/mfs/mfs_vfsops.c
@@ -31,7 +31,7 @@
* SUCH DAMAGE.
*
* @(#)mfs_vfsops.c 8.4 (Berkeley) 4/16/94
- * $Id: mfs_vfsops.c,v 1.13 1995/08/30 01:34:28 bde Exp $
+ * $Id: mfs_vfsops.c,v 1.14 1995/11/09 08:14:26 bde Exp $
*/
#include <sys/param.h>
@@ -344,6 +344,7 @@ mfs_start(mp, flags, p)
register struct mfsnode *mfsp = VTOMFS(vp);
register struct buf *bp;
register caddr_t base;
+ register int gotsig = 0;
base = mfsp->mfs_baseoff;
while (mfsp->mfs_buflist != (struct buf *)(-1)) {
@@ -358,9 +359,18 @@ mfs_start(mp, flags, p)
* otherwise we will loop here, as tsleep will always return
* EINTR/ERESTART.
*/
- if (tsleep((caddr_t)vp, mfs_pri, "mfsidl", 0) &&
- dounmount(mp, 0, p) != 0)
- CLRSIG(p, CURSIG(p));
+ /*
+ * Note that dounmount() may fail if work was queued after
+ * we slept. We have to jump hoops here to make sure that we
+ * process any buffers after the sleep, before we dounmount()
+ */
+ if (gotsig) {
+ gotsig = 0;
+ if (dounmount(mp, 0, p) != 0)
+ CLRSIG(p, CURSIG(p)); /* try sleep again.. */
+ }
+ else if (tsleep((caddr_t)vp, mfs_pri, "mfsidl", 0))
+ gotsig++; /* try to unmount in next pass */
}
return (0);
}
OpenPOWER on IntegriCloud