From 5930cc1020706f90eafefac5d52535d0f49d2640 Mon Sep 17 00:00:00 2001 From: Manuel Bentele Date: Wed, 14 Aug 2019 18:19:24 +0200 Subject: lib/losetup: added backward compatibility for file format support While using the new loop kernel module with file format support and an old losetup without file format support, problems occur. If losetup wants to have the loop_info structure filled by the loop kernel module, the kernel module writes across the boundaries of the old structure. A new flag called LO_FLAGS_FILE_FMT is introduced to specify the support of the loop_info extension for the file format support. If the flag is set before an - LOOP_GET_STATUS - LOOP_GET_STATUS64 - LOOP_SET_STATUS - LOOP_SET_STATUS64 ioctl call, the caller informs the kernel module about the usage of the extended loop_info structure. The module cna access the extension. Older versions of losetup do not set the flag by default and the loop module preserves the backward compatibility and do not write across the boundaries of the structure. Signed-off-by: Manuel Bentele --- include/loopdev.h | 3 ++- lib/loopdev.c | 11 +++++++++++ 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/include/loopdev.h b/include/loopdev.h index bc68e526b..f8559afd6 100644 --- a/include/loopdev.h +++ b/include/loopdev.h @@ -50,6 +50,7 @@ enum { LO_FLAGS_AUTOCLEAR = 4, /* kernel >= 2.6.25 */ LO_FLAGS_PARTSCAN = 8, /* kernel >= 3.2 */ LO_FLAGS_DIRECT_IO = 16, /* kernel >= 4.2 */ + LO_FLAGS_FILE_FMT = 32 }; #define LO_NAME_SIZE 64 @@ -73,7 +74,7 @@ struct loop_info64 { uint8_t lo_encrypt_key[LO_KEY_SIZE]; uint64_t lo_init[2]; uint32_t lo_file_fmt_type; -}; +} __attribute__((packed)); #define LOOPDEV_MAJOR 7 /* loop major number */ #define LOOPDEV_DEFAULT_NNODES 8 /* default number of loop devices */ diff --git a/lib/loopdev.c b/lib/loopdev.c index 676cc02f3..26ab402fa 100644 --- a/lib/loopdev.c +++ b/lib/loopdev.c @@ -665,6 +665,9 @@ struct loop_info64 *loopcxt_get_info(struct loopdev_cxt *lc) if (fd < 0) return NULL; + /* indicate that file format support is implemented in sys-utils */ + lc->info.lo_flags |= LO_FLAGS_FILE_FMT; + if (ioctl(fd, LOOP_GET_STATUS64, &lc->info) == 0) { lc->has_info = 1; lc->info_failed = 0; @@ -1439,6 +1442,10 @@ int loopcxt_setup_device(struct loopdev_cxt *lc) } do { + /* indicate that file format support is implemented in + * sys-utils */ + lc->info.lo_flags |= LO_FLAGS_FILE_FMT; + err = ioctl(dev_fd, LOOP_SET_STATUS64, &lc->info); again = err && errno == EAGAIN; if (again) @@ -1501,6 +1508,10 @@ int loopcxt_ioctl_status(struct loopdev_cxt *lc) DBG(SETUP, ul_debugobj(lc, "device open: OK")); do { + /* indicate that file format support is implemented in + * sys-utils */ + lc->info.lo_flags |= LO_FLAGS_FILE_FMT; + err = ioctl(dev_fd, LOOP_SET_STATUS64, &lc->info); again = err && errno == EAGAIN; if (again) -- cgit v1.2.3-55-g7522