diff options
author | Manuel Bentele | 2019-06-23 15:53:29 +0200 |
---|---|---|
committer | Manuel Bentele | 2019-06-23 15:53:29 +0200 |
commit | 1be5b2686b67f85d2d76a14532c8a649bd8d1c61 (patch) | |
tree | b546376c9cf98364d33509a9929520333da45d99 /drivers/block/loop.c | |
parent | Merge tag 'arm64-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/arm6... (diff) | |
download | kernel-qcow2-linux-1be5b2686b67f85d2d76a14532c8a649bd8d1c61.tar.gz kernel-qcow2-linux-1be5b2686b67f85d2d76a14532c8a649bd8d1c61.tar.xz kernel-qcow2-linux-1be5b2686b67f85d2d76a14532c8a649bd8d1c61.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 f11b7dc16e9d..ac26a9d4d4d6 100644 --- a/drivers/block/loop.c +++ b/drivers/block/loop.c @@ -789,6 +789,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); @@ -821,6 +848,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); @@ -829,6 +857,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, @@ -1314,6 +1343,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); @@ -1370,6 +1400,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; @@ -1400,6 +1431,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 @@ -1421,6 +1453,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 |