diff options
author | mckusick <mckusick@FreeBSD.org> | 2002-01-11 19:59:27 +0000 |
---|---|---|
committer | mckusick <mckusick@FreeBSD.org> | 2002-01-11 19:59:27 +0000 |
commit | b86f75b78bca0f0e60d5c0a167bf89e663374cc0 (patch) | |
tree | e7e66fa6144cc39b754afb2b24f549032b70fe09 /sys/ufs | |
parent | 732c36b4f36c769b32527e284c24877de4ec588e (diff) | |
download | FreeBSD-src-b86f75b78bca0f0e60d5c0a167bf89e663374cc0.zip FreeBSD-src-b86f75b78bca0f0e60d5c0a167bf89e663374cc0.tar.gz |
Must call drain_output() before checking the dirty block list
in softdep_sync_metadata(). Otherwise we may miss dependencies
that need to be flushed which will result in a later panic
with the message ``vinvalbuf: dirty bufs''.
Submitted by: Matthew Dillon <dillon@apollo.backplane.com>
MFC after: 1 week
Diffstat (limited to 'sys/ufs')
-rw-r--r-- | sys/ufs/ffs/ffs_softdep.c | 18 |
1 files changed, 10 insertions, 8 deletions
diff --git a/sys/ufs/ffs/ffs_softdep.c b/sys/ufs/ffs/ffs_softdep.c index 5233ff2..c2126c8 100644 --- a/sys/ufs/ffs/ffs_softdep.c +++ b/sys/ufs/ffs/ffs_softdep.c @@ -4344,6 +4344,11 @@ softdep_sync_metadata(ap) */ waitfor = MNT_NOWAIT; top: + /* + * We must wait for any I/O in progress to finish so that + * all potential buffers on the dirty list will be visible. + */ + drain_output(vp, 1); if (getdirtybuf(&TAILQ_FIRST(&vp->v_dirtyblkhd), MNT_WAIT) == 0) { FREE_LOCK(&lk); return (0); @@ -4502,15 +4507,8 @@ loop: goto loop; } /* - * We must wait for any I/O in progress to finish so that - * all potential buffers on the dirty list will be visible. - * Once they are all there, proceed with the second pass - * which will wait for the I/O as per above. - */ - drain_output(vp, 1); - /* * The brief unlock is to allow any pent up dependency - * processing to be done. + * processing to be done. Then proceed with the second pass. */ if (waitfor == MNT_NOWAIT) { waitfor = MNT_WAIT; @@ -4523,7 +4521,11 @@ loop: * If we have managed to get rid of all the dirty buffers, * then we are done. For certain directories and block * devices, we may need to do further work. + * + * We must wait for any I/O in progress to finish so that + * all potential buffers on the dirty list will be visible. */ + drain_output(vp, 1); if (TAILQ_FIRST(&vp->v_dirtyblkhd) == NULL) { FREE_LOCK(&lk); return (0); |