diff options
author | Manuel Bentele | 2019-06-23 15:53:29 +0200 |
---|---|---|
committer | Manuel Bentele | 2019-08-21 21:29:03 +0200 |
commit | 2ee25102f66dc0cf74a279cd4763066d744dff29 (patch) | |
tree | 7997c0a069ac96b35a2f40f92dedc3213add9e4e /drivers/block/loop.c | |
parent | Linux 4.19.67 (diff) | |
download | kernel-qcow2-linux-2ee25102f66dc0cf74a279cd4763066d744dff29.tar.gz kernel-qcow2-linux-2ee25102f66dc0cf74a279cd4763066d744dff29.tar.xz kernel-qcow2-linux-2ee25102f66dc0cf74a279cd4763066d744dff29.zip |
block: loop: extend kernel module interface for file format support
The existing loop device kernel module is extended by a configurable
file format for each loop device. The file format can be specified
by the LOOP_SET_STATUS or LOOP_SET_STATUS64 ioctl with the
corresponding data structure loop_info or respectively loop_info64.
Signed-off-by: Manuel Bentele <development@manuel-bentele.de>
Diffstat (limited to 'drivers/block/loop.c')
-rw-r--r-- | drivers/block/loop.c | 33 |
1 files changed, 33 insertions, 0 deletions
diff --git a/drivers/block/loop.c b/drivers/block/loop.c index cef8e00c9d9d..d94332851ef7 100644 --- a/drivers/block/loop.c +++ b/drivers/block/loop.c @@ -782,6 +782,33 @@ static ssize_t loop_attr_backing_file_show(struct loop_device *lo, char *buf) return ret; } +static ssize_t __print_file_fmt_type(__u32 file_fmt_type, char* buf) { + switch(file_fmt_type) { + case LO_FILE_FMT_RAW: + sprintf(buf, "%s\n", "RAW"); + break; + case LO_FILE_FMT_QCOW: + sprintf(buf, "%s\n", "QCOW"); + break; + case LO_FILE_FMT_VDI: + sprintf(buf, "%s\n", "VDI"); + break; + case LO_FILE_FMT_VMDK: + sprintf(buf, "%s\n", "VMDK"); + break; + default: + sprintf(buf, "%s\n", "ERROR: Unsupported loop file format!"); + break; + } + + return strlen(buf); +} + +static ssize_t loop_attr_file_fmt_type_show(struct loop_device *lo, char *buf) +{ + return __print_file_fmt_type(lo->lo_file_fmt_type, buf); +} + static ssize_t loop_attr_offset_show(struct loop_device *lo, char *buf) { return sprintf(buf, "%llu\n", (unsigned long long)lo->lo_offset); @@ -814,6 +841,7 @@ static ssize_t loop_attr_dio_show(struct loop_device *lo, char *buf) } LOOP_ATTR_RO(backing_file); +LOOP_ATTR_RO(file_fmt_type); LOOP_ATTR_RO(offset); LOOP_ATTR_RO(sizelimit); LOOP_ATTR_RO(autoclear); @@ -822,6 +850,7 @@ LOOP_ATTR_RO(dio); static struct attribute *loop_attrs[] = { &loop_attr_backing_file.attr, + &loop_attr_file_fmt_type.attr, &loop_attr_offset.attr, &loop_attr_sizelimit.attr, &loop_attr_autoclear.attr, @@ -1272,6 +1301,7 @@ loop_set_status(struct loop_device *lo, const struct loop_info64 *info) lo->lo_encrypt_key_size = info->lo_encrypt_key_size; lo->lo_init[0] = info->lo_init[0]; lo->lo_init[1] = info->lo_init[1]; + lo->lo_file_fmt_type = info->lo_file_fmt_type; if (info->lo_encrypt_key_size) { memcpy(lo->lo_encrypt_key, info->lo_encrypt_key, info->lo_encrypt_key_size); @@ -1328,6 +1358,7 @@ loop_get_status(struct loop_device *lo, struct loop_info64 *info) memcpy(info->lo_encrypt_key, lo->lo_encrypt_key, lo->lo_encrypt_key_size); } + info->lo_file_fmt_type = lo->lo_file_fmt_type; /* Drop loop_ctl_mutex while we call into the filesystem. */ path = lo->lo_backing_file->f_path; @@ -1358,6 +1389,7 @@ loop_info64_from_old(const struct loop_info *info, struct loop_info64 *info64) info64->lo_flags = info->lo_flags; info64->lo_init[0] = info->lo_init[0]; info64->lo_init[1] = info->lo_init[1]; + info64->lo_file_fmt_type = info->lo_file_fmt_type; if (info->lo_encrypt_type == LO_CRYPT_CRYPTOAPI) memcpy(info64->lo_crypt_name, info->lo_name, LO_NAME_SIZE); else @@ -1379,6 +1411,7 @@ loop_info64_to_old(const struct loop_info64 *info64, struct loop_info *info) info->lo_flags = info64->lo_flags; info->lo_init[0] = info64->lo_init[0]; info->lo_init[1] = info64->lo_init[1]; + info->lo_file_fmt_type = info64->lo_file_fmt_type; if (info->lo_encrypt_type == LO_CRYPT_CRYPTOAPI) memcpy(info->lo_name, info64->lo_crypt_name, LO_NAME_SIZE); else |