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.trumt...@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