diff -r 7b8d88655640 -r ee687e1e0283 sys/geom/geom_vfs.c --- a/sys/geom/geom_vfs.c Wed May 11 19:34:11 2011 +0200 +++ b/sys/geom/geom_vfs.c Tue May 31 00:47:16 2011 +0200 @@ -123,11 +123,26 @@ bip = g_alloc_bio(); bip->bio_cmd = bp->b_iocmd; bip->bio_offset = bp->b_iooffset; + bip->bio_length = bp->b_bcount; bip->bio_data = bp->b_data; bip->bio_done = g_vfs_done; bip->bio_caller2 = bp; - bip->bio_length = bp->b_bcount; g_io_request(bip, cp); + + if (bp->b_flags & B_FSYNC) { + bp->b_flags &= ~B_FSYNC; + /* Send a BIO_FLUSH to follow this request */ + printf("fsync BIO candidate cmd: %d, offset: %ju, length: %lu\n", + bp->b_iocmd, bp->b_iooffset, bp->b_bcount); + bip = g_alloc_bio(); + bip->bio_cmd = BIO_FLUSH; + bip->bio_flags = BIO_ORDERED; + bip->bio_offset = bp->b_iooffset; + bip->bio_length = bp->b_bcount; + bip->bio_data = NULL; + bip->bio_done = g_destroy_bio; + g_io_request(bip, cp); + } } static void diff -r 7b8d88655640 -r ee687e1e0283 sys/sys/buf.h --- a/sys/sys/buf.h Wed May 11 19:34:11 2011 +0200 +++ b/sys/sys/buf.h Tue May 31 00:47:16 2011 +0200 @@ -211,7 +211,7 @@ #define B_CLUSTEROK 0x00020000 /* Pagein op, so swap() can count it. */ #define B_000400000 0x00040000 /* Available flag. */ #define B_000800000 0x00080000 /* Available flag. */ -#define B_00100000 0x00100000 /* Available flag. */ +#define B_FSYNC 0x00100000 /* Operation caused by fsync. */ #define B_DIRTY 0x00200000 /* Needs writing later (in EXT2FS). */ #define B_RELBUF 0x00400000 /* Release VMIO buffer. */ #define B_00800000 0x00800000 /* Available flag. */ diff -r 7b8d88655640 -r ee687e1e0283 sys/ufs/ffs/ffs_softdep.c --- a/sys/ufs/ffs/ffs_softdep.c Wed May 11 19:34:11 2011 +0200 +++ b/sys/ufs/ffs/ffs_softdep.c Tue May 31 00:47:16 2011 +0200 @@ -709,6 +709,8 @@ SYSINIT(sdproc, SI_SUB_KTHREAD_UPDATE, SI_ORDER_ANY, kproc_start, &softdep_kp); +extern int ffs_fsync_flush; + static void softdep_flush(void) { @@ -5329,8 +5331,11 @@ FREE_LOCK(&lk); if (waitfor == MNT_NOWAIT) { bawrite(nbp); - } else if ((error = bwrite(nbp)) != 0) { - break; + } else { + if (ffs_fsync_flush) + nbp->b_flags |= B_FSYNC; + if ((error = bwrite(nbp)) != 0) + break; } ACQUIRE_LOCK(&lk); continue; @@ -5346,8 +5351,11 @@ FREE_LOCK(&lk); if (waitfor == MNT_NOWAIT) { bawrite(nbp); - } else if ((error = bwrite(nbp)) != 0) { - break; + } else { + if (ffs_fsync_flush) + nbp->b_flags |= B_FSYNC; + if ((error = bwrite(nbp)) != 0) + break; } ACQUIRE_LOCK(&lk); continue; @@ -5363,6 +5371,8 @@ if (nbp == NULL) goto restart; FREE_LOCK(&lk); + if (ffs_fsync_flush) + nbp->b_flags |= B_FSYNC; if ((error = bwrite(nbp)) != 0) { goto loop_end; } @@ -5415,8 +5425,11 @@ FREE_LOCK(&lk); if (waitfor == MNT_NOWAIT) { bawrite(nbp); - } else if ((error = bwrite(nbp)) != 0) { - break; + } else { + if (ffs_fsync_flush) + nbp->b_flags |= B_FSYNC; + if ((error = bwrite(nbp)) != 0) + break; } ACQUIRE_LOCK(&lk); continue; @@ -5436,8 +5449,11 @@ FREE_LOCK(&lk); if (waitfor == MNT_NOWAIT) { bawrite(nbp); - } else if ((error = bwrite(nbp)) != 0) { - break; + } else { + if (ffs_fsync_flush) + nbp->b_flags |= B_FSYNC; + if ((error = bwrite(nbp)) != 0) + break; } ACQUIRE_LOCK(&lk); continue; diff -r 7b8d88655640 -r ee687e1e0283 sys/ufs/ffs/ffs_vnops.c --- a/sys/ufs/ffs/ffs_vnops.c Wed May 11 19:34:11 2011 +0200 +++ b/sys/ufs/ffs/ffs_vnops.c Tue May 31 00:47:16 2011 +0200 @@ -76,6 +76,7 @@ #include #include #include +#include #include #include #include @@ -173,6 +174,11 @@ .vop_vptofh = ffs_vptofh, }; +SYSCTL_DECL(_vfs_ffs); + +int ffs_fsync_flush = 1; +SYSCTL_INT(_vfs_ffs, OID_AUTO, fsync_flush, CTLFLAG_RW, &ffs_fsync_flush, 0, + "Issue BIO_FLUSH to devices on fsync"); /* * Synch an open file. */ @@ -270,7 +276,6 @@ * file or device, start the write on this buffer immediately. */ if (wait || (vp->v_type != VREG && vp->v_type != VBLK)) { - /* * On our final pass through, do all I/O synchronously * so that we can find out if our flush is failing @@ -288,6 +293,8 @@ } else { bremfree(bp); splx(s); + if (ffs_fsync_flush) + bp->b_flags |= B_FSYNC; if ((error = bwrite(bp)) != 0) return (error); s = splbio();