[poky,dunfell] busybox: Implement dd iflag/oflag=direct

Submitted by akash hadke on Dec. 12, 2020, 12:48 p.m. | Patch ID: 179008

Details

Message ID 1607777301-27257-1-git-send-email-akash.hadke@kpit.com
State New
Headers show

Commit Message

akash hadke Dec. 12, 2020, 12:48 p.m.
This implementation assumes that iflag/oflag=direct will be used only
on block devices and files that are multiples of pagesize, and makes
no effort to solve issues with unaligned or partial reads (unlike gnu
coreutils dd)

Signed-off-by: akash hadke <akash.hadke@kpit.com>

---
 ...d-implement-iflag-direct-and-oflag-direct.patch | 197 +++++++++++++++++++++
 meta/recipes-core/busybox/busybox_1.31.1.bb        |   1 +
 2 files changed, 198 insertions(+)
 create mode 100644 meta/recipes-core/busybox/busybox/0001-dd-implement-iflag-direct-and-oflag-direct.patch

-- 
2.7.4
-=-=-=-=-=-=-=-=-=-=-=-
Links: You receive all messages sent to this group.
View/Reply Online (#145485): https://lists.openembedded.org/g/openembedded-core/message/145485
Mute This Topic: https://lists.openembedded.org/mt/78905692/1003190
Group Owner: openembedded-core+owner@lists.openembedded.org
Unsubscribe: https://lists.openembedded.org/g/openembedded-core/unsub [mhalstead@linuxfoundation.org]
-=-=-=-=-=-=-=-=-=-=-=-

Patch hide | download patch | download mbox

diff --git a/meta/recipes-core/busybox/busybox/0001-dd-implement-iflag-direct-and-oflag-direct.patch b/meta/recipes-core/busybox/busybox/0001-dd-implement-iflag-direct-and-oflag-direct.patch
new file mode 100644
index 0000000..9682323
--- /dev/null
+++ b/meta/recipes-core/busybox/busybox/0001-dd-implement-iflag-direct-and-oflag-direct.patch
@@ -0,0 +1,197 @@ 
+From 52bce91b58dd9d9ee51c1b84ae53f91e2a3e156d Mon Sep 17 00:00:00 2001
+From: Ricardo Leite <ricardo.leite@criticaltechworks.com>
+Date: Tue, 10 Nov 2020 16:21:51 +0000
+Subject: [PATCH] dd: implement iflag=direct and oflag=direct
+
+This implementation assumes that iflag/oflag=direct will be used only on
+block devices and files that are multiples of pagesize, and makes no
+effort to solve issues with unaligned or partial reads (unlike gnu
+coreutils dd)
+
+Using iflag/oflag=direct will also limit usage block sizes, which must
+also be a multiple of pagesize
+
+Upstream-Status: Submitted [busybox@busybox.net]
+---
+ coreutils/dd.c | 80 ++++++++++++++++++++++++++++++++++++++++----------
+ 1 file changed, 64 insertions(+), 16 deletions(-)
+
+diff --git a/coreutils/dd.c b/coreutils/dd.c
+index b5f3cbec5..b4fb71a49 100644
+--- a/coreutils/dd.c
++++ b/coreutils/dd.c
+@@ -59,7 +59,7 @@
+ //usage:       "[if=FILE] [of=FILE] [" IF_FEATURE_DD_IBS_OBS("ibs=N obs=N/") "bs=N] [count=N] [skip=N] [seek=N]\n"
+ //usage:	IF_FEATURE_DD_IBS_OBS(
+ //usage:       "	[conv=notrunc|noerror|sync|fsync]\n"
+-//usage:       "	[iflag=skip_bytes|fullblock] [oflag=seek_bytes|append]"
++//usage:       "	[iflag=skip_bytes|fullblock|direct] [oflag=seek_bytes|append|direct]"
+ //usage:	)
+ //usage:#define dd_full_usage "\n\n"
+ //usage:       "Copy a file with converting and formatting\n"
+@@ -83,8 +83,10 @@
+ //usage:     "\n	conv=swab	Swap every pair of bytes"
+ //usage:     "\n	iflag=skip_bytes	skip=N is in bytes"
+ //usage:     "\n	iflag=fullblock	Read full blocks"
++//usage:     "\n	iflag=direct	use direct I/O for data (limited support, file and bs must be a pagesize multiple)"
+ //usage:     "\n	oflag=seek_bytes	seek=N is in bytes"
+ //usage:     "\n	oflag=append	Open output file in append mode"
++//usage:     "\n	oflag=direct	use direct I/O for data (limited support, file and bs must be a pagesize multiple)"
+ //usage:	)
+ //usage:	IF_FEATURE_DD_STATUS(
+ //usage:     "\n	status=noxfer	Suppress rate output"
+@@ -137,16 +139,18 @@ enum {
+ 	FLAG_IFLAG_SHIFT = 5,
+ 	FLAG_SKIP_BYTES = (1 << 5) * ENABLE_FEATURE_DD_IBS_OBS,
+ 	FLAG_FULLBLOCK = (1 << 6) * ENABLE_FEATURE_DD_IBS_OBS,
++	FLAG_IDIRECT = (1 << 7) * ENABLE_FEATURE_DD_IBS_OBS,
+ 	/* end of input flags */
+ 	/* start of output flags */
+-	FLAG_OFLAG_SHIFT = 7,
+-	FLAG_SEEK_BYTES = (1 << 7) * ENABLE_FEATURE_DD_IBS_OBS,
+-	FLAG_APPEND = (1 << 8) * ENABLE_FEATURE_DD_IBS_OBS,
++	FLAG_OFLAG_SHIFT = 8,
++	FLAG_SEEK_BYTES = (1 << 8) * ENABLE_FEATURE_DD_IBS_OBS,
++	FLAG_APPEND = (1 << 9) * ENABLE_FEATURE_DD_IBS_OBS,
++	FLAG_ODIRECT = (1 << 10) * ENABLE_FEATURE_DD_IBS_OBS,
+ 	/* end of output flags */
+-	FLAG_TWOBUFS = (1 << 9) * ENABLE_FEATURE_DD_IBS_OBS,
+-	FLAG_COUNT   = 1 << 10,
+-	FLAG_STATUS_NONE = 1 << 11,
+-	FLAG_STATUS_NOXFER = 1 << 12,
++	FLAG_TWOBUFS = (1 << 11) * ENABLE_FEATURE_DD_IBS_OBS,
++	FLAG_COUNT   = 1 << 12,
++	FLAG_STATUS_NONE = 1 << 13,
++	FLAG_STATUS_NOXFER = 1 << 14,
+ };
+ 
+ static void dd_output_status(int UNUSED_PARAM cur_signal)
+@@ -252,6 +256,13 @@ static int parse_comma_flags(char *val, const char *words, const char *error_in)
+ 	}
+ 	return flags;
+ }
++
++static char *ptr_align(char *ptr, size_t alignment)
++{
++  char *p0 = ptr;
++  char *p1 = p0 + alignment - 1;
++  return p1 - (size_t) p1 % alignment;
++}
+ #endif
+ 
+ int dd_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
+@@ -267,9 +278,9 @@ int dd_main(int argc UNUSED_PARAM, char **argv)
+ 	static const char conv_words[] ALIGN1 =
+ 		"notrunc\0""sync\0""noerror\0""fsync\0""swab\0";
+ 	static const char iflag_words[] ALIGN1 =
+-		"skip_bytes\0""fullblock\0";
++		"skip_bytes\0""fullblock\0""direct\0";
+ 	static const char oflag_words[] ALIGN1 =
+-		"seek_bytes\0append\0";
++		"seek_bytes\0append\0""direct\0";
+ #endif
+ #if ENABLE_FEATURE_DD_STATUS
+ 	static const char status_words[] ALIGN1 =
+@@ -310,7 +321,9 @@ int dd_main(int argc UNUSED_PARAM, char **argv)
+ 	//swab          swap every pair of input bytes: will abort on non-even reads
+ 		OP_iflag_skip_bytes,
+ 		OP_iflag_fullblock,
++		OP_iflag_direct,
+ 		OP_oflag_seek_bytes,
++		OP_oflag_direct,
+ #endif
+ 	};
+ 	smallint exitcode = EXIT_FAILURE;
+@@ -320,9 +333,13 @@ int dd_main(int argc UNUSED_PARAM, char **argv)
+ #if ENABLE_FEATURE_DD_IBS_OBS
+ 	size_t obs = 512;
+ 	char *obuf;
++	char *ibufptr, *obufptr;
++	int pagesize;
+ #else
+ # define obs  ibs
+ # define obuf ibuf
++# define ibufptr ibuf
++# define obufptr ibuf
+ #endif
+ 	/* These are all zeroed at once! */
+ 	struct {
+@@ -427,13 +444,33 @@ int dd_main(int argc UNUSED_PARAM, char **argv)
+ 	} /* end of "for (argv[i])" */
+ 
+ //XXX:FIXME for huge ibs or obs, malloc'ing them isn't the brightest idea ever
+-	ibuf = xmalloc(ibs);
+-	obuf = ibuf;
+ #if ENABLE_FEATURE_DD_IBS_OBS
++	/* because of O_DIRECT, block needs to be page-aligned */
++	pagesize = getpagesize();
++	ibufptr = xmalloc(ibs + pagesize);
++	obufptr = ibufptr;
+ 	if (ibs != obs) {
+ 		G.flags |= FLAG_TWOBUFS;
+-		obuf = xmalloc(obs);
++		obufptr = xmalloc(obs + pagesize);
+ 	}
++
++	/* most filesystems will refuse O_DIRECT if read/writes aren't pagesize aligned */
++	if ((G.flags & FLAG_IDIRECT) && (ibs % pagesize)) {
++		bb_error_msg_and_die("iflag=direct needs bs %lu to be a multiple of pagesize %d",
++			ibs, pagesize);
++	}
++	if ((G.flags & FLAG_ODIRECT) && (obs % pagesize)) {
++		bb_error_msg_and_die("oflag=direct needs bs %lu to be a multiple of pagesize %d",
++			ibs, pagesize);
++	}
++
++	ibuf = ptr_align(ibufptr, pagesize);
++	obuf = ptr_align(obufptr, pagesize);
++#else
++	ibufptr = xmalloc(ibs);
++	obufptr = ibufptr;
++	ibuf = ibufptr;
++	obuf = obufptr;
+ #endif
+ 
+ #if ENABLE_FEATURE_DD_SIGNAL_HANDLING
+@@ -444,7 +481,14 @@ int dd_main(int argc UNUSED_PARAM, char **argv)
+ #endif
+ 
+ 	if (infile) {
+-		xmove_fd(xopen(infile, O_RDONLY), ifd);
++		int iflag = O_RDONLY;
++
++#if ENABLE_FEATURE_DD_IBS_OBS
++		if (G.flags & FLAG_IDIRECT)
++			iflag |= O_DIRECT;
++#endif
++
++		xmove_fd(xopen(infile, iflag), ifd);
+ 	} else {
+ 		infile = bb_msg_standard_input;
+ 	}
+@@ -455,6 +499,10 @@ int dd_main(int argc UNUSED_PARAM, char **argv)
+ 			oflag |= O_TRUNC;
+ 		if (G.flags & FLAG_APPEND)
+ 			oflag |= O_APPEND;
++#if ENABLE_FEATURE_DD_IBS_OBS
++		if (G.flags & FLAG_ODIRECT)
++			oflag |= O_DIRECT;
++#endif
+ 
+ 		xmove_fd(xopen(outfile, oflag), ofd);
+ 
+@@ -601,9 +649,9 @@ int dd_main(int argc UNUSED_PARAM, char **argv)
+ 		dd_output_status(0);
+ 
+ 	if (ENABLE_FEATURE_CLEAN_UP) {
+-		free(obuf);
++		free(obufptr);
+ 		if (G.flags & FLAG_TWOBUFS)
+-			free(ibuf);
++			free(ibufptr);
+ 	}
+ 
+ 	return exitcode;
+-- 
+2.29.2
+
diff --git a/meta/recipes-core/busybox/busybox_1.31.1.bb b/meta/recipes-core/busybox/busybox_1.31.1.bb
index 7563368..f7df4a6 100644
--- a/meta/recipes-core/busybox/busybox_1.31.1.bb
+++ b/meta/recipes-core/busybox/busybox_1.31.1.bb
@@ -50,6 +50,7 @@  SRC_URI = "https://busybox.net/downloads/busybox-${PV}.tar.bz2;name=tarball \
            file://0001-sysctl-ignore-EIO-of-stable_secret-below-proc-sys-ne.patch \
            file://busybox-CVE-2018-1000500.patch \
            file://0001-hwclock-make-glibc-2.31-compatible.patch \
+           file://0001-dd-implement-iflag-direct-and-oflag-direct.patch \
 "
 SRC_URI_append_libc-musl = " file://musl.cfg "