On our final pass through ffs_fsync, do all I/O synchronously so that

we can find out if our flush is failing because of write errors. This
change avoids a "flush failed" panic during unrecoverable disk errors.
This commit is contained in:
Kirk McKusick 1999-06-18 05:49:46 +00:00
parent 7c903b3d7e
commit 7481264c1e
1 changed files with 8 additions and 7 deletions

View File

@ -31,7 +31,7 @@
* SUCH DAMAGE. * SUCH DAMAGE.
* *
* @(#)ffs_vnops.c 8.15 (Berkeley) 5/14/95 * @(#)ffs_vnops.c 8.15 (Berkeley) 5/14/95
* $Id: ffs_vnops.c,v 1.55 1999/03/02 04:04:31 mckusick Exp $ * $Id: ffs_vnops.c,v 1.56 1999/05/14 01:26:05 mckusick Exp $
*/ */
#include <sys/param.h> #include <sys/param.h>
@ -143,7 +143,7 @@ ffs_fsync(ap)
/* /*
* Flush all dirty buffers associated with a vnode. * Flush all dirty buffers associated with a vnode.
*/ */
passes = NIADDR; passes = NIADDR + 1;
skipmeta = 0; skipmeta = 0;
if (ap->a_waitfor == MNT_WAIT) if (ap->a_waitfor == MNT_WAIT)
skipmeta = 1; skipmeta = 1;
@ -174,11 +174,11 @@ loop:
((vp->v_type != VREG) && (vp->v_type != VBLK))) { ((vp->v_type != VREG) && (vp->v_type != VBLK))) {
/* /*
* Wait for I/O associated with indirect blocks to * On our final pass through, do all I/O synchronously
* complete, since there is no way to quickly wait * so that we can find out if our flush is failing
* for them below. * because of write errors.
*/ */
if ((bp->b_vp == vp) || (ap->a_waitfor != MNT_WAIT)) { if (passes > 0 || (ap->a_waitfor != MNT_WAIT)) {
if ((bp->b_flags & B_CLUSTEROK) && if ((bp->b_flags & B_CLUSTEROK) &&
ap->a_waitfor != MNT_WAIT) { ap->a_waitfor != MNT_WAIT) {
(void) vfs_bio_awrite(bp); (void) vfs_bio_awrite(bp);
@ -193,7 +193,8 @@ loop:
bremfree(bp); bremfree(bp);
bp->b_flags |= B_BUSY; bp->b_flags |= B_BUSY;
splx(s); splx(s);
(void) bwrite(bp); if ((error = bwrite(bp)) != 0)
return (error);
s = splbio(); s = splbio();
} }
} else if ((vp->v_type == VREG) && (bp->b_lblkno >= lbn)) { } else if ((vp->v_type == VREG) && (bp->b_lblkno >= lbn)) {