aboutsummaryrefslogtreecommitdiff
path: root/bin
diff options
context:
space:
mode:
authorRichard Scheffenegger <rscheff@FreeBSD.org>2020-06-04 20:47:11 +0000
committerRichard Scheffenegger <rscheff@FreeBSD.org>2020-06-04 20:47:11 +0000
commitf4b4526f233c5a84388390279fc40ef8ecaa359f (patch)
tree880a891e84535997f265e8222674e30634ce3599 /bin
parent51569bd793756dac42a370221f89b52b4b080af7 (diff)
downloadsrc-f4b4526f233c5a84388390279fc40ef8ecaa359f.tar.gz
src-f4b4526f233c5a84388390279fc40ef8ecaa359f.zip
Add O_DIRECT flag to DD for cache bypass
FreeBSD DD utility has not had support for the O_DIRECT flag, which is useful to bypass local caching, e.g. for unconditionally issuing NFS IO requests during testing. Reviewed by: rgrimes (mentor) Approved by: rgrimes (mentor, blanket) MFC after: 3 weeks Sponsored by: NetApp, Inc. Differential Revision: https://reviews.freebsd.org/D25066
Notes
Notes: svn path=/head/; revision=361806
Diffstat (limited to 'bin')
-rw-r--r--bin/dd/args.c2
-rw-r--r--bin/dd/dd.18
-rw-r--r--bin/dd/dd.c9
-rw-r--r--bin/dd/dd.h2
4 files changed, 17 insertions, 4 deletions
diff --git a/bin/dd/args.c b/bin/dd/args.c
index 3ca49d243ce8..35a076175a93 100644
--- a/bin/dd/args.c
+++ b/bin/dd/args.c
@@ -266,6 +266,7 @@ static const struct iflag {
const char *name;
uint64_t set, noset;
} ilist[] = {
+ { "direct", C_IDIRECT, 0 },
{ "fullblock", C_IFULLBLOCK, C_SYNC },
};
@@ -410,6 +411,7 @@ static const struct oflag {
const char *name;
uint64_t set;
} olist[] = {
+ { "direct", C_ODIRECT },
{ "fsync", C_OFSYNC },
{ "sync", C_OFSYNC },
};
diff --git a/bin/dd/dd.1 b/bin/dd/dd.1
index 756a585d3b26..8bd5fa662ac6 100644
--- a/bin/dd/dd.1
+++ b/bin/dd/dd.1
@@ -32,7 +32,7 @@
.\" @(#)dd.1 8.2 (Berkeley) 1/13/94
.\" $FreeBSD$
.\"
-.Dd March 26, 2019
+.Dd June 4, 2020
.Dt DD 1
.Os
.Sh NAME
@@ -117,6 +117,8 @@ limits the number of times
is called on the input rather than the number of blocks copied in full.
May not be combined with
.Cm conv=sync .
+.It Cm direct
+Set the O_DIRECT flag on the input file to make reads bypass any local caching.
.El
.It Cm iseek Ns = Ns Ar n
Seek on the input file
@@ -143,7 +145,7 @@ the output file is truncated at that point.
Where
.Cm value
is one of the symbols from the following list.
-.Bl -tag -width "fsync"
+.Bl -tag -width "direct"
.It Cm fsync
Set the O_FSYNC flag on the output file to make writes synchronous.
.It Cm sync
@@ -151,6 +153,8 @@ Set the O_SYNC flag on the output file to make writes synchronous.
This is synonymous with the
.Cm fsync
value.
+.It Cm direct
+Set the O_DIRECT flag on the output file to make writes bypass any local caching.
.El
.It Cm oseek Ns = Ns Ar n
Seek on the output file
diff --git a/bin/dd/dd.c b/bin/dd/dd.c
index fd228f332b98..c43645fa0073 100644
--- a/bin/dd/dd.c
+++ b/bin/dd/dd.c
@@ -143,7 +143,7 @@ static void
setup(void)
{
u_int cnt;
- int oflags;
+ int iflags, oflags;
cap_rights_t rights;
unsigned long cmds[] = { FIODTYPE, MTIOCTOP };
@@ -151,7 +151,10 @@ setup(void)
in.name = "stdin";
in.fd = STDIN_FILENO;
} else {
- in.fd = open(in.name, O_RDONLY, 0);
+ iflags = 0;
+ if (ddflags & C_IDIRECT)
+ iflags |= O_DIRECT;
+ in.fd = open(in.name, O_RDONLY | iflags, 0);
if (in.fd == -1)
err(1, "%s", in.name);
}
@@ -186,6 +189,8 @@ setup(void)
oflags |= O_TRUNC;
if (ddflags & C_OFSYNC)
oflags |= O_FSYNC;
+ if (ddflags & C_ODIRECT)
+ oflags |= O_DIRECT;
out.fd = open(out.name, O_RDWR | oflags, DEFFILEMODE);
/*
* May not have read access, so try again with write only.
diff --git a/bin/dd/dd.h b/bin/dd/dd.h
index a39f879830de..ea606f288f3f 100644
--- a/bin/dd/dd.h
+++ b/bin/dd/dd.h
@@ -105,6 +105,8 @@ typedef struct {
#define C_FDATASYNC 0x0000000100000000ULL
#define C_OFSYNC 0x0000000200000000ULL
#define C_IFULLBLOCK 0x0000000400000000ULL
+#define C_IDIRECT 0x0000000800000000ULL
+#define C_ODIRECT 0x0000001000000000ULL
#define C_PARITY (C_PAREVEN | C_PARODD | C_PARNONE | C_PARSET)