[prev in list] [next in list] [prev in thread] [next in thread]
List: busybox
Subject: [PATCH] mount: support the sizelimit and offset option for loop devices
From: Steffen Trumtrar <s.trumtrar () pengutronix ! de>
Date: 2020-07-29 8:43:53
Message-ID: 20200729084353.1634-1-s.trumtrar () pengutronix ! de
[Download RAW message or body]
Starting with linux kernel v5.4 squashfs has a more strict parameter
checking implemented. Unlike util-linux mount, busybox never supported
the sizelimit option but simply forwards it to the kernel.
Since v5.4 mounting will fail with
squashfs: Unknown parameter 'sizelimit'
Support the sizelimit parameter by setting it in the LOOP_SET_STATUS64
structure before handing it to the kernel.
While at it also add support for the offset option, which currently will
always be set to 0.
Signed-off-by: Steffen Trumtrar <s.trumtrar@pengutronix.de>
---
include/libbb.h | 3 ++-
libbb/loop.c | 4 +++-
util-linux/losetup.c | 2 +-
util-linux/mount.c | 38 +++++++++++++++++++++++++++++++++++++-
4 files changed, 43 insertions(+), 4 deletions(-)
diff --git a/include/libbb.h b/include/libbb.h
index 6be934994499..fe7fcff40ee0 100644
--- a/include/libbb.h
+++ b/include/libbb.h
@@ -1515,7 +1515,8 @@ int del_loop(const char *device) FAST_FUNC;
* malloc and return it in *devname.
* return value is the opened fd to the loop device, or < on error
*/
-int set_loop(char **devname, const char *file, unsigned long long offset, unsigned flags) FAST_FUNC;
+int set_loop(char **devname, const char *file, unsigned long long offset,
+ unsigned long long sizelimit, unsigned flags) FAST_FUNC;
/* These constants match linux/loop.h (without BB_ prefix): */
#define BB_LO_FLAGS_READ_ONLY 1
#define BB_LO_FLAGS_AUTOCLEAR 4
diff --git a/libbb/loop.c b/libbb/loop.c
index ada0c7638f3b..c65982c32b71 100644
--- a/libbb/loop.c
+++ b/libbb/loop.c
@@ -102,7 +102,8 @@ int FAST_FUNC get_free_loop(void)
* search will re-use an existing loop device already bound to that
* file/offset if it finds one.
*/
-int FAST_FUNC set_loop(char **device, const char *file, unsigned long long offset, unsigned flags)
+int FAST_FUNC set_loop(char **device, const char *file, unsigned long long offset,
+ unsigned long long sizelimit, unsigned flags)
{
char dev[LOOP_NAMESIZE];
char *try;
@@ -185,6 +186,7 @@ int FAST_FUNC set_loop(char **device, const char *file, unsigned long long offse
memset(&loopinfo, 0, sizeof(loopinfo));
safe_strncpy((char *)loopinfo.lo_file_name, file, LO_NAME_SIZE);
loopinfo.lo_offset = offset;
+ loopinfo.lo_sizelimit = sizelimit;
/*
* Used by mount to set LO_FLAGS_AUTOCLEAR.
* LO_FLAGS_READ_ONLY is not set because RO is controlled by open type of the file.
diff --git a/util-linux/losetup.c b/util-linux/losetup.c
index cc6c2b1d54e6..ec0cf04e4502 100644
--- a/util-linux/losetup.c
+++ b/util-linux/losetup.c
@@ -151,7 +151,7 @@ int losetup_main(int argc UNUSED_PARAM, char **argv)
if (opt & OPT_P) {
flags |= BB_LO_FLAGS_PARTSCAN;
}
- if (set_loop(&d, argv[0], offset, flags) < 0)
+ if (set_loop(&d, argv[0], offset, 0, flags) < 0)
bb_simple_perror_msg_and_die(argv[0]);
return EXIT_SUCCESS;
}
diff --git a/util-linux/mount.c b/util-linux/mount.c
index 84c85c0578ea..bd6dfa3ba0bd 100644
--- a/util-linux/mount.c
+++ b/util-linux/mount.c
@@ -2030,9 +2030,44 @@ static int singlemount(struct mntent *mp, int ignore_busy)
) {
// Do we need to allocate a loopback device for it?
if (ENABLE_FEATURE_MOUNT_LOOP && S_ISREG(st.st_mode)) {
+ char *opt;
+ unsigned long long offset = 0;
+ unsigned long long sizelimit = 0;
+
loopFile = bb_simplify_path(mp->mnt_fsname);
mp->mnt_fsname = NULL; // will receive malloced loop dev name
+ /* parse options */
+ if (filteropts)
+ for (opt = strtok(filteropts, ","); opt; opt = strtok(NULL, ",")) {
+ char *opteq = strchr(opt, '=');
+ int len = strlen(opt);
+ char *match;
+
+ if (opteq) {
+ int idx;
+ static const char options[] ALIGN1 =
+ /* 0 */ "offset\0"
+ /* 1 */ "sizelimit\0";
+
+ *opteq++ = '\0';
+ idx = index_in_strings(options, opt);
+ switch (idx) {
+ case 0: // "offset"
+ offset = strtoull(opteq, 0, 0);
+ match = strstr(filteropts, opt);
+ *match = '\0';
+ strcat(filteropts, match+len);
+ continue;
+ case 1: // "sizelimit"
+ sizelimit = strtoull(opteq, 0, 0);
+ match = strstr(filteropts, opt);
+ *match = '\0';
+ strcat(filteropts, match+len);
+ continue;
+ }
+ }
+ }
// mount always creates AUTOCLEARed loopdevs, so that umounting
// drops them without any code in the userspace.
// This happens since circa linux-2.6.25:
@@ -2041,7 +2076,8 @@ static int singlemount(struct mntent *mp, int ignore_busy)
// Subject: Allow auto-destruction of loop devices
loopfd = set_loop(&mp->mnt_fsname,
loopFile,
- 0,
+ offset,
+ sizelimit,
((vfsflags & MS_RDONLY) ? BB_LO_FLAGS_READ_ONLY : 0)
| BB_LO_FLAGS_AUTOCLEAR
);
--
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