diff options
author | peter <peter@FreeBSD.org> | 1995-11-28 02:15:29 +0000 |
---|---|---|
committer | peter <peter@FreeBSD.org> | 1995-11-28 02:15:29 +0000 |
commit | 17cfbbe7dfdf8533d89b6d58e8530f8869312b78 (patch) | |
tree | 71bf08c00b95cb57bfa2131b3d930bc0e2175922 /sys/ufs | |
parent | 3ce680f86e8546763e962f268e5848bf19529ba8 (diff) | |
download | FreeBSD-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.c | 18 |
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); } |