summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorManuel Bentele2019-08-14 18:19:24 +0200
committerManuel Bentele2019-08-14 18:19:24 +0200
commit5930cc1020706f90eafefac5d52535d0f49d2640 (patch)
treef1565940c9a59591347723c0e0f9d56186c2dc8a
parentlib/losetup: added file format support (diff)
downloadkernel-qcow2-util-linux-5930cc1020706f90eafefac5d52535d0f49d2640.tar.gz
kernel-qcow2-util-linux-5930cc1020706f90eafefac5d52535d0f49d2640.tar.xz
kernel-qcow2-util-linux-5930cc1020706f90eafefac5d52535d0f49d2640.zip
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 <development@manuel-bentele.de>
-rw-r--r--include/loopdev.h3
-rw-r--r--lib/loopdev.c11
2 files changed, 13 insertions, 1 deletions
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)