fsync(1) patch to do DIOCGFLUSH on character devices
Julian Hsiao
julian at hsiao.email
Sun Jul 24 03:04:51 UTC 2016
Hi,
The fsync(1) utility is a simple wrapper around fsync(2), but I didn't find
a similar utility for calling ioctl(DIOCGFLUSH) for character devices.
fsync(2) is a no-op on character device files, which is a little surprising
but makes sense I suppose (would raising EINVAL be against POSIX?).
However, conceptually the goal is the same: commit writes to permanent
storage, so here's a small patch to fsync(1) that calls ioctl(DIOCGFLUSH)
for character device files instead.
Incidentally, turns out you need to open character device files with O_RDWR
(or maybe O_WRONLY is enough, I didn't check) for DIOCGFLUSH, but fsync(2)
only needs O_RDONLY for plain files. This seems a little odd; does anyone
know why?
Julian Hsiao
Index: usr.bin/fsync/fsync.1
===================================================================
diff --git a/head/usr.bin/fsync/fsync.1 b/head/usr.bin/fsync/fsync.1
--- a/head/usr.bin/fsync/fsync.1 (revision 303213)
+++ b/head/usr.bin/fsync/fsync.1 (working copy)
@@ -44,6 +44,8 @@
.Nm
utility uses the
.Xr fsync 2
+or the
+.Xr ioctl 2
function call.
.Sh EXIT STATUS
If an error occurs, the
Index: usr.bin/fsync/fsync.c
===================================================================
diff --git a/head/usr.bin/fsync/fsync.c b/head/usr.bin/fsync/fsync.c
--- a/head/usr.bin/fsync/fsync.c (revision 303213)
+++ b/head/usr.bin/fsync/fsync.c (working copy)
@@ -35,6 +35,10 @@
#include <stdlib.h>
#include <sysexits.h>
#include <unistd.h>
+#include <string.h>
+#include <sys/stat.h>
+#include <sys/disk.h>
+#include <sys/ioctl.h>
static void usage(void);
@@ -44,6 +48,7 @@
int fd;
int i;
int rval;
+ struct stat sb;
if (argc < 2) {
usage();
@@ -58,11 +63,35 @@
rval = EX_NOINPUT;
continue;
}
+ memset(&sb, 0, sizeof(sb));
+ if (fstat(fd, &sb) == -1) {
+ warn("fstat %s", argv[i]);
+ rval = EX_OSERR;
+ continue;
+ }
- if (fsync(fd) == -1) {
- warn("fsync %s", argv[i]);
- if (rval == EX_OK)
+ if (S_ISCHR(sb.st_mode)) {
+ if (close(fd) == -1) {
+ warn("close %s", argv[i]);
rval = EX_OSERR;
+ continue;
+ }
+ if ((fd = open(argv[i], O_RDWR)) == -1) {
+ warn("open %s", argv[i]);
+ rval = EX_NOINPUT;
+ continue;
+ }
+
+ if (ioctl(fd, DIOCGFLUSH) == -1) {
+ warn("ioctl %s", argv[i]);
+ rval = EX_OSERR;
+ }
+ } else {
+ if (fsync(fd) == -1) {
+ warn("fsync %s", argv[i]);
+ if (rval == EX_OK)
+ rval = EX_OSERR;
+ }
}
close(fd);
}
More information about the freebsd-hackers
mailing list