[prev in list] [next in list] [prev in thread] [next in thread] 

List:       busybox
Subject:    [PATCH v3 9/9] loop: Add LOOP_CONFIGURE ioctl
From:       Xiaoming Ni <nixiaoming () huawei ! com>
Date:       2022-11-21 2:46:39
Message-ID: 20221121024639.92549-10-nixiaoming () huawei ! com
[Download RAW message or body]

LOOP_CONFIGURE is added to Linux 5.8

This allows userspace to completely setup a loop device with a single
ioctl, removing the in-between state where the device can be partially
configured - eg the loop device has a backing file associated with it,
but is reading from the wrong offset.

https://lwn.net/Articles/820408/
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=3448914e8cc5

Builders can use config to choose which algorithm to build into their busybox binary
kernel version >= 5.8, choice CONFIG_LOOP_CONFIGURE
	function                                             old     new   delta
	set_loop                                             716     639     -77
	------------------------------------------------------------------------------
	(add/remove: 0/0 grow/shrink: 0/1 up/down: 0/-77)             Total: -77 bytes
kernel version < 5.8, choice CONFIG_NO_LOOP_CONFIGURE
	function                                             old     new   delta
	------------------------------------------------------------------------------
	(add/remove: 0/0 grow/shrink: 0/0 up/down: 0/0)                 Total: 0 bytes
kernel version is unknown, choice CONFIG_TRY_LOOP_CONFIGURE
	function                                             old     new   delta
	set_loop                                             716     832    +116
	------------------------------------------------------------------------------
	(add/remove: 0/0 grow/shrink: 1/0 up/down: 116/0)             Total: 116 bytes

Signed-off-by: Xiaoming Ni <nixiaoming@huawei.com>
---
 libbb/Config.src | 22 ++++++++++++++++++++++
 libbb/loop.c     | 47 ++++++++++++++++++++++++++++++++++++++++++++++-
 2 files changed, 68 insertions(+), 1 deletion(-)

diff --git a/libbb/Config.src b/libbb/Config.src
index 66a3ffa23..b7f9ddab4 100644
--- a/libbb/Config.src
+++ b/libbb/Config.src
@@ -369,3 +369,25 @@ config UNICODE_PRESERVE_BROKEN
 	For example, this means that entering 'l', 's', ' ', 0xff, [Enter]
 	at shell prompt will list file named 0xff (single char name
 	with char value 255), not file named '?'.
+
+choice
+	prompt "LOOP_CONFIGURE or LOOP_SET_FD + LOOP_SET_STATUS"
+	default TRY_LOOP_CONFIGURE
+	help
+	LOOP_CONFIGURE is added to Linux 5.8
+	https://lwn.net/Articles/820408/
+	This allows userspace to completely setup a loop device with a single
+	ioctl, removing the in-between state where the device can be partially
+	configured - eg the loop device has a backing file associated with it,
+	but is reading from the wrong offset.
+
+config LOOP_CONFIGURE
+	bool "always uses LOOP_CONFIGURE, kernel version >= 5.8"
+
+config NO_LOOP_CONFIGURE
+	bool "never uses LOOP_CONFIGURE, kernel version < 5.8"
+
+config TRY_LOOP_CONFIGURE
+	bool "try LOOP_CONFIGURE, kernel version is unknown"
+
+endchoice
diff --git a/libbb/loop.c b/libbb/loop.c
index 799936765..14919b318 100644
--- a/libbb/loop.c
+++ b/libbb/loop.c
@@ -126,7 +126,8 @@ static int open_file(const char *file, unsigned flags, int *mode)
 	return ffd;
 }
 
-static int set_loop_configure(int ffd, int lfd, bb_loop_info *loopinfo)
+#ifndef CONFIG_LOOP_CONFIGURE
+static int set_loop_fd_and_status(int ffd, int lfd, bb_loop_info *loopinfo)
 {
 	int rc;
 	bb_loop_info loopinfo2;
@@ -149,6 +150,46 @@ static int set_loop_configure(int ffd, int lfd, bb_loop_info *loopinfo)
 	ioctl(lfd, LOOP_CLR_FD, 0); // actually, 0 param is unnecessary
 	return -1;
 }
+#endif
+
+#ifndef CONFIG_NO_LOOP_CONFIGURE
+
+#ifndef LOOP_CONFIGURE
+#define LOOP_CONFIGURE 0x4C0A
+struct loop_config {
+	uint32_t fd;
+	uint32_t block_size;
+	struct loop_info64 info;
+	uint64_t __reserved[8];
+};
+#endif
+
+/*
+ * linux v5.8.0
+ * loop: Add LOOP_CONFIGURE ioctl
+ * https://lwn.net/Articles/820408/
+ * https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=3448914e8cc5
+ */
+static int set_loop_configure(int ffd, int lfd, bb_loop_info *loopinfo)
+{
+	int rc;
+	struct loop_config config;
+
+	memset(&config, 0, sizeof(config));
+	config.fd = ffd;
+	memcpy(&config.info, loopinfo, sizeof(config.info));
+
+	rc = ioctl(lfd, LOOP_CONFIGURE, &config);
+	if (rc == 0) {
+		return lfd;
+	}
+#ifdef CONFIG_TRY_LOOP_CONFIGURE
+	if (rc == -1 && errno == EINVAL) /* The system may not support LOOP_CONFIGURE. */
+		return set_loop_fd_and_status(ffd, lfd, loopinfo);
+#endif
+	return -1;
+}
+#endif
 
 static int set_loop_info(int ffd, int lfd, bb_loop_info *loopinfo)
 {
@@ -159,7 +200,11 @@ static int set_loop_info(int ffd, int lfd, bb_loop_info *loopinfo)
 
 	/* If device is free, try to claim it */
 	if (rc && errno == ENXIO) {
+#ifdef CONFIG_NO_LOOP_CONFIGURE
+		return set_loop_fd_and_status(ffd, lfd, loopinfo);
+#else
 		return set_loop_configure(ffd, lfd, loopinfo);
+#endif
 	}
 	return -1;
 }
-- 
2.27.0

_______________________________________________
busybox mailing list
busybox@busybox.net
http://lists.busybox.net/mailman/listinfo/busybox
[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic