From 3b96efbda0395b5bacfb6930dfaf664f5c718512 Mon Sep 17 00:00:00 2001 From: Matt Macy Date: Mon, 30 Sep 2019 21:48:12 +0000 Subject: [PATCH] Add conv=fdatasync flag to dd The fdatasync flag performs an fdatasync(2) on the output file before closing it. This will be useful for the ZFS test suite. Submitted by: Ryan Moeller Reviewed by: manpages, mmacy@ MFC after: 1 week Sponsored by: iXSystems, Inc. Differential Revision: https://reviews.freebsd.org/D21373 --- bin/dd/args.c | 5 ++-- bin/dd/dd.1 | 4 +++ bin/dd/dd.c | 7 ++++-- bin/dd/dd.h | 65 +++++++++++++++++++++++++------------------------ bin/dd/extern.h | 2 +- 5 files changed, 46 insertions(+), 37 deletions(-) diff --git a/bin/dd/args.c b/bin/dd/args.c index 8e83c6cc608..87385d2d6a9 100644 --- a/bin/dd/args.c +++ b/bin/dd/args.c @@ -77,7 +77,7 @@ static off_t get_off_t(const char *); static const struct arg { const char *name; void (*f)(char *); - u_int set, noset; + uint64_t set, noset; } args[] = { { "bs", f_bs, C_BS, C_BS|C_IBS|C_OBS|C_OSYNC }, { "cbs", f_cbs, C_CBS, C_CBS }, @@ -314,12 +314,13 @@ f_status(char *arg) static const struct conv { const char *name; - u_int set, noset; + uint64_t set, noset; const u_char *ctab; } clist[] = { { "ascii", C_ASCII, C_EBCDIC, e2a_POSIX }, { "block", C_BLOCK, C_UNBLOCK, NULL }, { "ebcdic", C_EBCDIC, C_ASCII, a2e_POSIX }, + { "fdatasync", C_FDATASYNC, 0, NULL }, { "fsync", C_FSYNC, 0, NULL }, { "ibm", C_EBCDIC, C_ASCII, a2ibm_POSIX }, { "lcase", C_LCASE, C_UCASE, NULL }, diff --git a/bin/dd/dd.1 b/bin/dd/dd.1 index 539e448b28b..e1fa48a8252 100644 --- a/bin/dd/dd.1 +++ b/bin/dd/dd.1 @@ -252,6 +252,10 @@ are maps used in historic and .No pre- Ns Bx 4.3 reno systems. +.It Cm fdatasync +Perform an +.Xr fdatasync 2 +on the output file before closing it. .It Cm fsync Perform an .Xr fsync 2 diff --git a/bin/dd/dd.c b/bin/dd/dd.c index 3db678b8500..e3916fe7dcc 100644 --- a/bin/dd/dd.c +++ b/bin/dd/dd.c @@ -83,7 +83,7 @@ STAT st; /* statistics */ void (*cfunc)(void); /* conversion function */ uintmax_t cpy_cnt; /* # of blocks to copy */ static off_t pending = 0; /* pending seek if sparse */ -u_int ddflags = 0; /* conversion options */ +uint64_t ddflags = 0; /* conversion options */ size_t cbsz; /* conversion block size */ uintmax_t files_cnt = 1; /* # of files to copy */ const u_char *ctab; /* conversion table */ @@ -164,7 +164,7 @@ setup(void) errx(1, "files is not supported for non-tape devices"); cap_rights_set(&rights, CAP_FTRUNCATE, CAP_IOCTL, CAP_WRITE); - if (ddflags & C_FSYNC) + if (ddflags & (C_FDATASYNC | C_FSYNC)) cap_rights_set(&rights, CAP_FSYNC); if (out.name == NULL) { /* No way to check for read access here. */ @@ -511,6 +511,9 @@ dd_close(void) if (ddflags & C_FSYNC) { if (fsync(out.fd) == -1) err(1, "fsyncing %s", out.name); + } else if (ddflags & C_FDATASYNC) { + if (fdatasync(out.fd) == -1) + err(1, "fdatasyncing %s", out.name); } } diff --git a/bin/dd/dd.h b/bin/dd/dd.h index 8c01cb4d17c..a255a5970e5 100644 --- a/bin/dd/dd.h +++ b/bin/dd/dd.h @@ -70,38 +70,39 @@ typedef struct { } STAT; /* Flags (in ddflags). */ -#define C_ASCII 0x00000001 -#define C_BLOCK 0x00000002 -#define C_BS 0x00000004 -#define C_CBS 0x00000008 -#define C_COUNT 0x00000010 -#define C_EBCDIC 0x00000020 -#define C_FILES 0x00000040 -#define C_IBS 0x00000080 -#define C_IF 0x00000100 -#define C_LCASE 0x00000200 -#define C_NOERROR 0x00000400 -#define C_NOTRUNC 0x00000800 -#define C_OBS 0x00001000 -#define C_OF 0x00002000 -#define C_OSYNC 0x00004000 -#define C_PAREVEN 0x00008000 -#define C_PARNONE 0x00010000 -#define C_PARODD 0x00020000 -#define C_PARSET 0x00040000 -#define C_SEEK 0x00080000 -#define C_SKIP 0x00100000 -#define C_SPARSE 0x00200000 -#define C_SWAB 0x00400000 -#define C_SYNC 0x00800000 -#define C_UCASE 0x01000000 -#define C_UNBLOCK 0x02000000 -#define C_FILL 0x04000000 -#define C_STATUS 0x08000000 -#define C_NOXFER 0x10000000 -#define C_NOINFO 0x20000000 -#define C_PROGRESS 0x40000000 -#define C_FSYNC 0x80000000 +#define C_ASCII 0x0000000000000001ULL +#define C_BLOCK 0x0000000000000002ULL +#define C_BS 0x0000000000000004ULL +#define C_CBS 0x0000000000000008ULL +#define C_COUNT 0x0000000000000010ULL +#define C_EBCDIC 0x0000000000000020ULL +#define C_FILES 0x0000000000000040ULL +#define C_IBS 0x0000000000000080ULL +#define C_IF 0x0000000000000100ULL +#define C_LCASE 0x0000000000000200ULL +#define C_NOERROR 0x0000000000000400ULL +#define C_NOTRUNC 0x0000000000000800ULL +#define C_OBS 0x0000000000001000ULL +#define C_OF 0x0000000000002000ULL +#define C_OSYNC 0x0000000000004000ULL +#define C_PAREVEN 0x0000000000008000ULL +#define C_PARNONE 0x0000000000010000ULL +#define C_PARODD 0x0000000000020000ULL +#define C_PARSET 0x0000000000040000ULL +#define C_SEEK 0x0000000000080000ULL +#define C_SKIP 0x0000000000100000ULL +#define C_SPARSE 0x0000000000200000ULL +#define C_SWAB 0x0000000000400000ULL +#define C_SYNC 0x0000000000800000ULL +#define C_UCASE 0x0000000001000000ULL +#define C_UNBLOCK 0x0000000002000000ULL +#define C_FILL 0x0000000004000000ULL +#define C_STATUS 0x0000000008000000ULL +#define C_NOXFER 0x0000000010000000ULL +#define C_NOINFO 0x0000000020000000ULL +#define C_PROGRESS 0x0000000040000000ULL +#define C_FSYNC 0x0000000080000000ULL +#define C_FDATASYNC 0x0000000100000000ULL #define C_PARITY (C_PAREVEN | C_PARODD | C_PARNONE | C_PARSET) diff --git a/bin/dd/extern.h b/bin/dd/extern.h index 45e3fb1b280..07c08e2ef8f 100644 --- a/bin/dd/extern.h +++ b/bin/dd/extern.h @@ -58,7 +58,7 @@ extern STAT st; extern void (*cfunc)(void); extern uintmax_t cpy_cnt; extern size_t cbsz; -extern u_int ddflags; +extern uint64_t ddflags; extern size_t speed; extern uintmax_t files_cnt; extern const u_char *ctab;