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
This commit is contained in:
mmacy 2019-09-30 21:48:12 +00:00
parent 4d2327369d
commit c67dc60f49
5 changed files with 46 additions and 37 deletions

View File

@ -77,7 +77,7 @@ static off_t get_off_t(const char *);
static const struct arg { static const struct arg {
const char *name; const char *name;
void (*f)(char *); void (*f)(char *);
u_int set, noset; uint64_t set, noset;
} args[] = { } args[] = {
{ "bs", f_bs, C_BS, C_BS|C_IBS|C_OBS|C_OSYNC }, { "bs", f_bs, C_BS, C_BS|C_IBS|C_OBS|C_OSYNC },
{ "cbs", f_cbs, C_CBS, C_CBS }, { "cbs", f_cbs, C_CBS, C_CBS },
@ -314,12 +314,13 @@ f_status(char *arg)
static const struct conv { static const struct conv {
const char *name; const char *name;
u_int set, noset; uint64_t set, noset;
const u_char *ctab; const u_char *ctab;
} clist[] = { } clist[] = {
{ "ascii", C_ASCII, C_EBCDIC, e2a_POSIX }, { "ascii", C_ASCII, C_EBCDIC, e2a_POSIX },
{ "block", C_BLOCK, C_UNBLOCK, NULL }, { "block", C_BLOCK, C_UNBLOCK, NULL },
{ "ebcdic", C_EBCDIC, C_ASCII, a2e_POSIX }, { "ebcdic", C_EBCDIC, C_ASCII, a2e_POSIX },
{ "fdatasync", C_FDATASYNC, 0, NULL },
{ "fsync", C_FSYNC, 0, NULL }, { "fsync", C_FSYNC, 0, NULL },
{ "ibm", C_EBCDIC, C_ASCII, a2ibm_POSIX }, { "ibm", C_EBCDIC, C_ASCII, a2ibm_POSIX },
{ "lcase", C_LCASE, C_UCASE, NULL }, { "lcase", C_LCASE, C_UCASE, NULL },

View File

@ -252,6 +252,10 @@ are maps used in historic
and and
.No pre- Ns Bx 4.3 reno .No pre- Ns Bx 4.3 reno
systems. systems.
.It Cm fdatasync
Perform an
.Xr fdatasync 2
on the output file before closing it.
.It Cm fsync .It Cm fsync
Perform an Perform an
.Xr fsync 2 .Xr fsync 2

View File

@ -83,7 +83,7 @@ STAT st; /* statistics */
void (*cfunc)(void); /* conversion function */ void (*cfunc)(void); /* conversion function */
uintmax_t cpy_cnt; /* # of blocks to copy */ uintmax_t cpy_cnt; /* # of blocks to copy */
static off_t pending = 0; /* pending seek if sparse */ 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 */ size_t cbsz; /* conversion block size */
uintmax_t files_cnt = 1; /* # of files to copy */ uintmax_t files_cnt = 1; /* # of files to copy */
const u_char *ctab; /* conversion table */ const u_char *ctab; /* conversion table */
@ -164,7 +164,7 @@ setup(void)
errx(1, "files is not supported for non-tape devices"); errx(1, "files is not supported for non-tape devices");
cap_rights_set(&rights, CAP_FTRUNCATE, CAP_IOCTL, CAP_WRITE); 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); cap_rights_set(&rights, CAP_FSYNC);
if (out.name == NULL) { if (out.name == NULL) {
/* No way to check for read access here. */ /* No way to check for read access here. */
@ -511,6 +511,9 @@ dd_close(void)
if (ddflags & C_FSYNC) { if (ddflags & C_FSYNC) {
if (fsync(out.fd) == -1) if (fsync(out.fd) == -1)
err(1, "fsyncing %s", out.name); err(1, "fsyncing %s", out.name);
} else if (ddflags & C_FDATASYNC) {
if (fdatasync(out.fd) == -1)
err(1, "fdatasyncing %s", out.name);
} }
} }

View File

@ -70,38 +70,39 @@ typedef struct {
} STAT; } STAT;
/* Flags (in ddflags). */ /* Flags (in ddflags). */
#define C_ASCII 0x00000001 #define C_ASCII 0x0000000000000001ULL
#define C_BLOCK 0x00000002 #define C_BLOCK 0x0000000000000002ULL
#define C_BS 0x00000004 #define C_BS 0x0000000000000004ULL
#define C_CBS 0x00000008 #define C_CBS 0x0000000000000008ULL
#define C_COUNT 0x00000010 #define C_COUNT 0x0000000000000010ULL
#define C_EBCDIC 0x00000020 #define C_EBCDIC 0x0000000000000020ULL
#define C_FILES 0x00000040 #define C_FILES 0x0000000000000040ULL
#define C_IBS 0x00000080 #define C_IBS 0x0000000000000080ULL
#define C_IF 0x00000100 #define C_IF 0x0000000000000100ULL
#define C_LCASE 0x00000200 #define C_LCASE 0x0000000000000200ULL
#define C_NOERROR 0x00000400 #define C_NOERROR 0x0000000000000400ULL
#define C_NOTRUNC 0x00000800 #define C_NOTRUNC 0x0000000000000800ULL
#define C_OBS 0x00001000 #define C_OBS 0x0000000000001000ULL
#define C_OF 0x00002000 #define C_OF 0x0000000000002000ULL
#define C_OSYNC 0x00004000 #define C_OSYNC 0x0000000000004000ULL
#define C_PAREVEN 0x00008000 #define C_PAREVEN 0x0000000000008000ULL
#define C_PARNONE 0x00010000 #define C_PARNONE 0x0000000000010000ULL
#define C_PARODD 0x00020000 #define C_PARODD 0x0000000000020000ULL
#define C_PARSET 0x00040000 #define C_PARSET 0x0000000000040000ULL
#define C_SEEK 0x00080000 #define C_SEEK 0x0000000000080000ULL
#define C_SKIP 0x00100000 #define C_SKIP 0x0000000000100000ULL
#define C_SPARSE 0x00200000 #define C_SPARSE 0x0000000000200000ULL
#define C_SWAB 0x00400000 #define C_SWAB 0x0000000000400000ULL
#define C_SYNC 0x00800000 #define C_SYNC 0x0000000000800000ULL
#define C_UCASE 0x01000000 #define C_UCASE 0x0000000001000000ULL
#define C_UNBLOCK 0x02000000 #define C_UNBLOCK 0x0000000002000000ULL
#define C_FILL 0x04000000 #define C_FILL 0x0000000004000000ULL
#define C_STATUS 0x08000000 #define C_STATUS 0x0000000008000000ULL
#define C_NOXFER 0x10000000 #define C_NOXFER 0x0000000010000000ULL
#define C_NOINFO 0x20000000 #define C_NOINFO 0x0000000020000000ULL
#define C_PROGRESS 0x40000000 #define C_PROGRESS 0x0000000040000000ULL
#define C_FSYNC 0x80000000 #define C_FSYNC 0x0000000080000000ULL
#define C_FDATASYNC 0x0000000100000000ULL
#define C_PARITY (C_PAREVEN | C_PARODD | C_PARNONE | C_PARSET) #define C_PARITY (C_PAREVEN | C_PARODD | C_PARNONE | C_PARSET)

View File

@ -58,7 +58,7 @@ extern STAT st;
extern void (*cfunc)(void); extern void (*cfunc)(void);
extern uintmax_t cpy_cnt; extern uintmax_t cpy_cnt;
extern size_t cbsz; extern size_t cbsz;
extern u_int ddflags; extern uint64_t ddflags;
extern size_t speed; extern size_t speed;
extern uintmax_t files_cnt; extern uintmax_t files_cnt;
extern const u_char *ctab; extern const u_char *ctab;