summaryrefslogtreecommitdiffstats
path: root/drivers/block/loop.c
diff options
context:
space:
mode:
authorManuel Bentele2019-06-23 15:53:29 +0200
committerManuel Bentele2019-08-21 21:29:03 +0200
commit2ee25102f66dc0cf74a279cd4763066d744dff29 (patch)
tree7997c0a069ac96b35a2f40f92dedc3213add9e4e /drivers/block/loop.c
parentLinux 4.19.67 (diff)
downloadkernel-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.c33
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