Page MenuHomeFreeBSD

D36371.id.diff
No OneTemporary

D36371.id.diff

Index: share/man/man7/ffs.7
===================================================================
--- share/man/man7/ffs.7
+++ share/man/man7/ffs.7
@@ -287,6 +287,14 @@
Enable support for the rearrangement of blocks
to be contiguous.
.Pq Default: 1 .
+.It Va vfs.ffs.nocacheflush
+Disables device write cache flushes.
+Without cache flushes, data may be lost on power loss even after
+.Xr fsync 2
+or
+.Xr fdatasync 2
+completes, on storage with a volatile write cache.
+.Pq Default: 1 .
.El
.Sh HISTORY
The
Index: sys/ufs/ffs/ffs_vnops.c
===================================================================
--- sys/ufs/ffs/ffs_vnops.c
+++ sys/ufs/ffs/ffs_vnops.c
@@ -87,6 +87,8 @@
#include <sys/vmmeter.h>
#include <sys/vnode.h>
+#include <geom/geom.h>
+
#include <vm/vm.h>
#include <vm/vm_param.h>
#include <vm/vm_extern.h>
@@ -253,6 +255,46 @@
return (0);
}
+static int
+ffs_flushwritecache(struct vnode *vp)
+{
+ struct ufsmount *ump;
+ struct bio *bp;
+ int error;
+
+ ump = VFSTOUFS(vp->v_mount);
+
+ /*
+ * XXX How can we find out if ump has write caching enabled, especially
+ * volatile write caching, and has DISKFLAG_CANFLUSHCACHE, and skip all
+ * this if not?
+ */
+
+ bp = g_alloc_bio();
+
+ bp->bio_cmd = BIO_FLUSH;
+ bp->bio_flags = 0; /* don't need BIO_ORDERED, caller waited */
+ bp->bio_data = NULL;
+ bp->bio_offset = 0;
+ bp->bio_length = ump->um_cp->provider->mediasize;
+ bp->bio_done = NULL;
+ g_io_request(bp, ump->um_cp);
+ error = biowait(bp, "ffs_fc");
+
+ /* silently ignore errors due to lack of DISKFLAG_CANFLUSHCACHE */
+ if (error != 0 && bp->bio_error == EOPNOTSUPP)
+ error = 0;
+
+ g_destroy_bio(bp);
+
+ return (error);
+}
+
+SYSCTL_DECL(_vfs_ffs);
+static int nocacheflush = 1;
+SYSCTL_INT(_vfs_ffs, OID_AUTO, nocacheflush, CTLFLAG_RWTUN, &nocacheflush, 0,
+ "Disable write cache flushes");
+
int
ffs_syncvnode(struct vnode *vp, int waitfor, int flags)
{
@@ -460,6 +502,9 @@
error = ERELOOKUP;
if (error == 0)
ip->i_flag &= ~IN_NEEDSYNC;
+ if (error == 0 && waitfor == MNT_WAIT && nocacheflush == 0)
+ error = ffs_flushwritecache(vp);
+
return (error);
}
@@ -1036,6 +1081,12 @@
if (ffs_fsfail_cleanup(VFSTOUFS(vp->v_mount), error))
error = ENXIO;
}
+ /*
+ * For O_SYNC and O_DSYNC writes, we could potentially use FUA, but for
+ * now just flush like fsync/fdatasync.
+ */
+ if (error == 0 && (ioflag & IO_SYNC) && nocacheflush == 0)
+ error = ffs_flushwritecache(vp);
return (error);
}

File Metadata

Mime Type
text/plain
Expires
Fri, Mar 27, 5:42 AM (10 h, 52 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
30380074
Default Alt Text
D36371.id.diff (2 KB)

Event Timeline