summaryrefslogtreecommitdiffstats
path: root/src/kernel/xloop_file_fmt_qcow_main.c
diff options
context:
space:
mode:
authorManuel Bentele2021-03-15 12:18:10 +0100
committerManuel Bentele2021-03-15 12:18:10 +0100
commit3bc3b89d5a85b9642e96688e6c9c2862a95e7b45 (patch)
tree7f4e067962ced878427d128410671e6d1c1d4154 /src/kernel/xloop_file_fmt_qcow_main.c
parentAdd support in CMake to validate (lint) the source code (diff)
downloadxloop-3bc3b89d5a85b9642e96688e6c9c2862a95e7b45.tar.gz
xloop-3bc3b89d5a85b9642e96688e6c9c2862a95e7b45.tar.xz
xloop-3bc3b89d5a85b9642e96688e6c9c2862a95e7b45.zip
Refactor kernel code to satisfy Linux kernel code style
Diffstat (limited to 'src/kernel/xloop_file_fmt_qcow_main.c')
-rw-r--r--src/kernel/xloop_file_fmt_qcow_main.c733
1 files changed, 298 insertions, 435 deletions
diff --git a/src/kernel/xloop_file_fmt_qcow_main.c b/src/kernel/xloop_file_fmt_qcow_main.c
index 376273d..e642160 100644
--- a/src/kernel/xloop_file_fmt_qcow_main.c
+++ b/src/kernel/xloop_file_fmt_qcow_main.c
@@ -1,4 +1,4 @@
-/* SPDX-License-Identifier: GPL-2.0 */
+// SPDX-License-Identifier: GPL-2.0
/*
* xloop_file_fmt_qcow.c
*
@@ -36,15 +36,15 @@
#include "xloop_file_fmt_qcow_cluster.h"
#ifdef CONFIG_ZSTD_DECOMPRESS
-#define ZSTD_WINDOWLOG_LIMIT_DEFAULT 27
-#define ZSTD_MAXWINDOWSIZE ((U32_C(1) << ZSTD_WINDOWLOG_LIMIT_DEFAULT) + 1)
+#define ZSTD_WINDOWLOG_LIMIT_DEFAULT 27
+#define ZSTD_MAXWINDOWSIZE ((U32_C(1) << ZSTD_WINDOWLOG_LIMIT_DEFAULT) + 1)
#endif
-typedef ssize_t (*qcow_file_fmt_decompress_fn)(struct xloop_file_fmt *xlo_fmt,
- void *dest, size_t dest_size, const void *src, size_t src_size);
+typedef ssize_t (*qcow_file_fmt_decompress_fn)(struct xloop_file_fmt *xlo_fmt, void *dest, size_t dest_size,
+ const void *src, size_t src_size);
-static int __qcow_file_fmt_header_read(struct xloop_file_fmt *xlo_fmt,
- struct file *file, struct xloop_file_fmt_qcow_header *header)
+static int __qcow_file_fmt_header_read(struct xloop_file_fmt *xlo_fmt, struct file *file,
+ struct xloop_file_fmt_qcow_header *header)
{
ssize_t len;
loff_t offset;
@@ -54,8 +54,7 @@ static int __qcow_file_fmt_header_read(struct xloop_file_fmt *xlo_fmt,
offset = 0;
len = kernel_read(file, header, sizeof(*header), &offset);
if (len < 0) {
- dev_err(xloop_file_fmt_to_dev(xlo_fmt), "could not read QCOW "
- "header\n");
+ dev_err(xloop_file_fmt_to_dev(xlo_fmt), "could not read QCOW header\n");
return len;
}
@@ -68,40 +67,33 @@ static int __qcow_file_fmt_header_read(struct xloop_file_fmt *xlo_fmt,
header->crypt_method = be32_to_cpu(header->crypt_method);
header->l1_size = be32_to_cpu(header->l1_size);
header->l1_table_offset = be64_to_cpu(header->l1_table_offset);
- header->refcount_table_offset =
- be64_to_cpu(header->refcount_table_offset);
- header->refcount_table_clusters =
- be32_to_cpu(header->refcount_table_clusters);
+ header->refcount_table_offset = be64_to_cpu(header->refcount_table_offset);
+ header->refcount_table_clusters = be32_to_cpu(header->refcount_table_clusters);
header->nb_snapshots = be32_to_cpu(header->nb_snapshots);
header->snapshots_offset = be64_to_cpu(header->snapshots_offset);
/* check QCOW file format and header version */
if (header->magic != QCOW_MAGIC) {
- dev_err(xloop_file_fmt_to_dev(xlo_fmt), "image is not in QCOW "
- "format\n");
+ dev_err(xloop_file_fmt_to_dev(xlo_fmt), "image is not in QCOW format\n");
return -EINVAL;
}
if (header->version < 2 || header->version > 3) {
- dev_err(xloop_file_fmt_to_dev(xlo_fmt), "unsupported QCOW "
- "version %d\n", header->version);
+ dev_err(xloop_file_fmt_to_dev(xlo_fmt), "unsupported QCOW version %d\n", header->version);
return -ENOTSUPP;
}
/* initialize version 3 header fields */
if (header->version == 2) {
- header->incompatible_features = 0;
- header->compatible_features = 0;
- header->autoclear_features = 0;
- header->refcount_order = 4;
- header->header_length = 72;
+ header->incompatible_features = 0;
+ header->compatible_features = 0;
+ header->autoclear_features = 0;
+ header->refcount_order = 4;
+ header->header_length = 72;
} else {
- header->incompatible_features =
- be64_to_cpu(header->incompatible_features);
- header->compatible_features =
- be64_to_cpu(header->compatible_features);
- header->autoclear_features =
- be64_to_cpu(header->autoclear_features);
+ header->incompatible_features = be64_to_cpu(header->incompatible_features);
+ header->compatible_features = be64_to_cpu(header->compatible_features);
+ header->autoclear_features = be64_to_cpu(header->autoclear_features);
header->refcount_order = be32_to_cpu(header->refcount_order);
header->header_length = be32_to_cpu(header->header_length);
@@ -114,9 +106,8 @@ static int __qcow_file_fmt_header_read(struct xloop_file_fmt *xlo_fmt,
return ret;
}
-static int __qcow_file_fmt_validate_table(struct xloop_file_fmt *xlo_fmt,
- u64 offset, u64 entries, size_t entry_len, s64 max_size_bytes,
- const char *table_name)
+static int __qcow_file_fmt_validate_table(struct xloop_file_fmt *xlo_fmt, u64 offset, u64 entries, size_t entry_len,
+ s64 max_size_bytes, const char *table_name)
{
struct xloop_file_fmt_qcow_data *qcow_data = xlo_fmt->private_data;
@@ -125,24 +116,24 @@ static int __qcow_file_fmt_validate_table(struct xloop_file_fmt *xlo_fmt,
return -EFBIG;
}
- /* Use signed S64_MAX as the maximum even for u64 header fields,
- * because values will be passed to qemu functions taking s64. */
- if ((S64_MAX - entries * entry_len < offset) || (
- xloop_file_fmt_qcow_offset_into_cluster(qcow_data, offset) != 0)
- ) {
- dev_err(xloop_file_fmt_to_dev(xlo_fmt), "%s offset invalid",
- table_name);
+ /*
+ * Use signed S64_MAX as the maximum even for u64 header fields,
+ * because values will be passed to qemu functions taking s64.
+ */
+ if ((S64_MAX - entries * entry_len < offset) ||
+ (xloop_file_fmt_qcow_offset_into_cluster(qcow_data, offset) != 0)) {
+ dev_err(xloop_file_fmt_to_dev(xlo_fmt), "%s offset invalid", table_name);
return -EINVAL;
}
return 0;
}
-static inline loff_t __qcow_file_fmt_rq_get_pos(struct xloop_file_fmt *xlo_fmt,
- struct request *rq)
+static inline loff_t __qcow_file_fmt_rq_get_pos(struct xloop_file_fmt *xlo_fmt, struct request *rq)
{
struct xloop_device *xlo = xloop_file_fmt_get_xlo(xlo_fmt);
- return ((loff_t) blk_rq_pos(rq) << 9) + xlo->xlo_offset;
+
+ return ((loff_t)blk_rq_pos(rq) << 9) + xlo->xlo_offset;
}
static int __qcow_file_fmt_compression_init(struct xloop_file_fmt *xlo_fmt)
@@ -168,10 +159,10 @@ static int __qcow_file_fmt_compression_init(struct xloop_file_fmt *xlo_fmt)
/* set up ZLIB decompression stream */
ret = zlib_inflateInit2(qcow_data->zlib_dstrm, -12);
- if (ret != Z_OK) {
- ret = -EIO;
+ if (ret != Z_OK) {
+ ret = -EIO;
goto out_free_zlib_dworkspace;
- }
+ }
#ifdef CONFIG_ZSTD_DECOMPRESS
/* create workspace for ZSTD decompression stream */
@@ -183,8 +174,7 @@ static int __qcow_file_fmt_compression_init(struct xloop_file_fmt *xlo_fmt)
}
/* set up ZSTD decompression stream */
- qcow_data->zstd_dstrm = ZSTD_initDStream(ZSTD_MAXWINDOWSIZE,
- qcow_data->zstd_dworkspace, workspace_size);
+ qcow_data->zstd_dstrm = ZSTD_initDStream(ZSTD_MAXWINDOWSIZE, qcow_data->zstd_dworkspace, workspace_size);
if (!qcow_data->zstd_dstrm) {
ret = -EINVAL;
goto out_free_zstd_dworkspace;
@@ -237,85 +227,53 @@ static void __qcow_file_fmt_compression_exit(struct xloop_file_fmt *xlo_fmt)
#ifdef CONFIG_DEBUG_FS
static void __qcow_file_fmt_header_to_buf(struct xloop_file_fmt *xlo_fmt,
- const struct xloop_file_fmt_qcow_header *header)
+ const struct xloop_file_fmt_qcow_header *header)
{
struct xloop_file_fmt_qcow_data *qcow_data = xlo_fmt->private_data;
char *header_buf = qcow_data->dbgfs_file_qcow_header_buf;
ssize_t len = 0;
- len += sprintf(header_buf + len, "magic: %d\n",
- header->magic);
- len += sprintf(header_buf + len, "version: %d\n",
- header->version);
- len += sprintf(header_buf + len, "backing_file_offset: %lld\n",
- header->backing_file_offset);
- len += sprintf(header_buf + len, "backing_file_size: %d\n",
- header->backing_file_size);
- len += sprintf(header_buf + len, "cluster_bits: %d\n",
- header->cluster_bits);
- len += sprintf(header_buf + len, "size: %lld\n",
- header->size);
- len += sprintf(header_buf + len, "crypt_method: %d\n",
- header->crypt_method);
- len += sprintf(header_buf + len, "l1_size: %d\n",
- header->l1_size);
- len += sprintf(header_buf + len, "l1_table_offset: %lld\n",
- header->l1_table_offset);
- len += sprintf(header_buf + len, "refcount_table_offset: %lld\n",
- header->refcount_table_offset);
- len += sprintf(header_buf + len, "refcount_table_clusters: %d\n",
- header->refcount_table_clusters);
- len += sprintf(header_buf + len, "nb_snapshots: %d\n",
- header->nb_snapshots);
- len += sprintf(header_buf + len, "snapshots_offset: %lld\n",
- header->snapshots_offset);
+ len += sprintf(header_buf + len, "magic: %d\n", header->magic);
+ len += sprintf(header_buf + len, "version: %d\n", header->version);
+ len += sprintf(header_buf + len, "backing_file_offset: %lld\n", header->backing_file_offset);
+ len += sprintf(header_buf + len, "backing_file_size: %d\n", header->backing_file_size);
+ len += sprintf(header_buf + len, "cluster_bits: %d\n", header->cluster_bits);
+ len += sprintf(header_buf + len, "size: %lld\n", header->size);
+ len += sprintf(header_buf + len, "crypt_method: %d\n", header->crypt_method);
+ len += sprintf(header_buf + len, "l1_size: %d\n", header->l1_size);
+ len += sprintf(header_buf + len, "l1_table_offset: %lld\n", header->l1_table_offset);
+ len += sprintf(header_buf + len, "refcount_table_offset: %lld\n", header->refcount_table_offset);
+ len += sprintf(header_buf + len, "refcount_table_clusters: %d\n", header->refcount_table_clusters);
+ len += sprintf(header_buf + len, "nb_snapshots: %d\n", header->nb_snapshots);
+ len += sprintf(header_buf + len, "snapshots_offset: %lld\n", header->snapshots_offset);
if (header->version == 3) {
- len += sprintf(header_buf + len,
- "incompatible_features: %lld\n",
- header->incompatible_features);
- len += sprintf(header_buf + len,
- "compatible_features: %lld\n",
- header->compatible_features);
- len += sprintf(header_buf + len,
- "autoclear_features: %lld\n",
- header->autoclear_features);
- len += sprintf(header_buf + len,
- "refcount_order: %d\n",
- header->refcount_order);
- len += sprintf(header_buf + len,
- "header_length: %d\n",
- header->header_length);
+ len += sprintf(header_buf + len, "incompatible_features: %lld\n", header->incompatible_features);
+ len += sprintf(header_buf + len, "compatible_features: %lld\n", header->compatible_features);
+ len += sprintf(header_buf + len, "autoclear_features: %lld\n", header->autoclear_features);
+ len += sprintf(header_buf + len, "refcount_order: %d\n", header->refcount_order);
+ len += sprintf(header_buf + len, "header_length: %d\n", header->header_length);
}
- if (header->header_length > offsetof(struct xloop_file_fmt_qcow_header,
- compression_type)) {
- len += sprintf(header_buf + len,
- "compression_type: %d\n",
- header->compression_type);
- }
+ if (header->header_length > offsetof(struct xloop_file_fmt_qcow_header, compression_type))
+ len += sprintf(header_buf + len, "compression_type: %d\n", header->compression_type);
ASSERT(len < QCOW_HEADER_BUF_LEN);
}
-static ssize_t __qcow_file_fmt_dbgfs_hdr_read(struct file *file,
- char __user *buf, size_t size, loff_t *ppos)
+static ssize_t __qcow_file_fmt_dbgfs_hdr_read(struct file *file, char __user *buf, size_t size, loff_t *ppos)
{
struct xloop_file_fmt *xlo_fmt = file->private_data;
struct xloop_file_fmt_qcow_data *qcow_data = xlo_fmt->private_data;
char *header_buf = qcow_data->dbgfs_file_qcow_header_buf;
- return simple_read_from_buffer(buf, size, ppos, header_buf,
- strlen(header_buf));
+ return simple_read_from_buffer(buf, size, ppos, header_buf, strlen(header_buf));
}
-static const struct file_operations qcow_file_fmt_dbgfs_hdr_fops = {
- .open = simple_open,
- .read = __qcow_file_fmt_dbgfs_hdr_read
-};
+static const struct file_operations qcow_file_fmt_dbgfs_hdr_fops = { .open = simple_open,
+ .read = __qcow_file_fmt_dbgfs_hdr_read };
-static ssize_t __qcow_file_fmt_dbgfs_ofs_read(struct file *file,
- char __user *buf, size_t size, loff_t *ppos)
+static ssize_t __qcow_file_fmt_dbgfs_ofs_read(struct file *file, char __user *buf, size_t size, loff_t *ppos)
{
struct xloop_file_fmt *xlo_fmt = file->private_data;
struct xloop_file_fmt_qcow_data *qcow_data = xlo_fmt->private_data;
@@ -337,44 +295,37 @@ static ssize_t __qcow_file_fmt_dbgfs_ofs_read(struct file *file,
mutex_unlock(&qcow_data->dbgfs_qcow_offset_mutex);
/* calculate and print the cluster offset */
- ret = xloop_file_fmt_qcow_get_host_offset(xlo_fmt,
- offset, &cur_bytes, &host_offset, &type);
+ ret = xloop_file_fmt_qcow_get_host_offset(xlo_fmt, offset, &cur_bytes, &host_offset, &type);
if (ret < 0)
return -EINVAL;
- offset_in_cluster = xloop_file_fmt_qcow_offset_into_cluster(qcow_data,
- offset);
+ offset_in_cluster = xloop_file_fmt_qcow_offset_into_cluster(qcow_data, offset);
len = sprintf(qcow_data->dbgfs_file_qcow_cluster_buf,
- "cluster type: %s\n"
- "cluster offset host: %lld\n"
- "cluster offset guest: %lld\n"
- "cluster offset in-cluster: %lld\n",
- xloop_file_fmt_qcow_get_subcluster_name(type),
- host_offset, offset, offset_in_cluster);
-
- if (type == QCOW_SUBCLUSTER_COMPRESSED) {
- coffset = host_offset & qcow_data->cluster_offset_mask;
- nb_csectors = ((host_offset >> qcow_data->csize_shift) &
- qcow_data->csize_mask) + 1;
- csize = nb_csectors * QCOW_COMPRESSED_SECTOR_SIZE -
- (coffset & ~QCOW_COMPRESSED_SECTOR_MASK);
+ "cluster type: %s\n"
+ "cluster offset host: %lld\n"
+ "cluster offset guest: %lld\n"
+ "cluster offset in-cluster: %lld\n",
+ xloop_file_fmt_qcow_get_subcluster_name(type), host_offset, offset, offset_in_cluster);
+
+ if (type == QCOW_SUBCLUSTER_COMPRESSED) {
+ coffset = host_offset & qcow_data->cluster_offset_mask;
+ nb_csectors = ((host_offset >> qcow_data->csize_shift) & qcow_data->csize_mask) + 1;
+ csize = nb_csectors * QCOW_COMPRESSED_SECTOR_SIZE - (coffset & ~QCOW_COMPRESSED_SECTOR_MASK);
len += sprintf(qcow_data->dbgfs_file_qcow_cluster_buf + len,
- "cluster compressed offset: %lld\n"
- "cluster compressed sectors: %d\n"
- "cluster compressed size: %d\n",
- coffset, nb_csectors, csize);
- }
+ "cluster compressed offset: %lld\n"
+ "cluster compressed sectors: %d\n"
+ "cluster compressed size: %d\n",
+ coffset, nb_csectors, csize);
+ }
ASSERT(len < QCOW_CLUSTER_BUF_LEN);
- return simple_read_from_buffer(buf, size, ppos,
- qcow_data->dbgfs_file_qcow_cluster_buf, len);
+ return simple_read_from_buffer(buf, size, ppos, qcow_data->dbgfs_file_qcow_cluster_buf, len);
}
-static ssize_t __qcow_file_fmt_dbgfs_ofs_write(struct file *file,
- const char __user *buf, size_t size, loff_t *ppos)
+static ssize_t __qcow_file_fmt_dbgfs_ofs_write(struct file *file, const char __user *buf, size_t size, loff_t *ppos)
{
struct xloop_file_fmt *xlo_fmt = file->private_data;
struct xloop_file_fmt_qcow_data *qcow_data = xlo_fmt->private_data;
@@ -384,8 +335,7 @@ static ssize_t __qcow_file_fmt_dbgfs_ofs_write(struct file *file,
if (*ppos > QCOW_OFFSET_BUF_LEN || size > QCOW_OFFSET_BUF_LEN)
return -EINVAL;
- len = simple_write_to_buffer(qcow_data->dbgfs_file_qcow_offset_buf,
- QCOW_OFFSET_BUF_LEN, ppos, buf, size);
+ len = simple_write_to_buffer(qcow_data->dbgfs_file_qcow_offset_buf, QCOW_OFFSET_BUF_LEN, ppos, buf, size);
if (len < 0)
return len;
@@ -395,8 +345,7 @@ static ssize_t __qcow_file_fmt_dbgfs_ofs_write(struct file *file,
if (ret)
return ret;
- ret = kstrtou64(qcow_data->dbgfs_file_qcow_offset_buf, 10,
- &qcow_data->dbgfs_qcow_offset);
+ ret = kstrtou64(qcow_data->dbgfs_file_qcow_offset_buf, 10, &qcow_data->dbgfs_qcow_offset);
if (ret < 0)
goto out;
@@ -406,11 +355,9 @@ out:
return ret;
}
-static const struct file_operations qcow_file_fmt_dbgfs_ofs_fops = {
- .open = simple_open,
- .read = __qcow_file_fmt_dbgfs_ofs_read,
- .write = __qcow_file_fmt_dbgfs_ofs_write
-};
+static const struct file_operations qcow_file_fmt_dbgfs_ofs_fops = { .open = simple_open,
+ .read = __qcow_file_fmt_dbgfs_ofs_read,
+ .write = __qcow_file_fmt_dbgfs_ofs_write };
static int __qcow_file_fmt_dbgfs_init(struct xloop_file_fmt *xlo_fmt)
{
@@ -424,17 +371,15 @@ static int __qcow_file_fmt_dbgfs_init(struct xloop_file_fmt *xlo_fmt)
goto out;
}
- qcow_data->dbgfs_file_qcow_header = debugfs_create_file("header",
- S_IRUGO, qcow_data->dbgfs_dir, xlo_fmt,
- &qcow_file_fmt_dbgfs_hdr_fops);
+ qcow_data->dbgfs_file_qcow_header =
+ debugfs_create_file("header", 0444, qcow_data->dbgfs_dir, xlo_fmt, &qcow_file_fmt_dbgfs_hdr_fops);
if (IS_ERR_OR_NULL(qcow_data->dbgfs_file_qcow_header)) {
ret = -ENODEV;
goto out_free_dbgfs_dir;
}
- qcow_data->dbgfs_file_qcow_offset = debugfs_create_file("offset",
- S_IRUGO | S_IWUSR, qcow_data->dbgfs_dir, xlo_fmt,
- &qcow_file_fmt_dbgfs_ofs_fops);
+ qcow_data->dbgfs_file_qcow_offset = debugfs_create_file("offset", 0644, qcow_data->dbgfs_dir,
+ xlo_fmt, &qcow_file_fmt_dbgfs_ofs_fops);
if (IS_ERR_OR_NULL(qcow_data->dbgfs_file_qcow_offset)) {
qcow_data->dbgfs_file_qcow_offset = NULL;
ret = -ENODEV;
@@ -460,55 +405,50 @@ static void __qcow_file_fmt_dbgfs_exit(struct xloop_file_fmt *xlo_fmt)
{
struct xloop_file_fmt_qcow_data *qcow_data = xlo_fmt->private_data;
- if (qcow_data->dbgfs_file_qcow_offset)
- debugfs_remove(qcow_data->dbgfs_file_qcow_offset);
+ debugfs_remove(qcow_data->dbgfs_file_qcow_offset);
mutex_destroy(&qcow_data->dbgfs_qcow_offset_mutex);
- if (qcow_data->dbgfs_file_qcow_header)
- debugfs_remove(qcow_data->dbgfs_file_qcow_header);
+ debugfs_remove(qcow_data->dbgfs_file_qcow_header);
- if (qcow_data->dbgfs_dir)
- debugfs_remove(qcow_data->dbgfs_dir);
+ debugfs_remove(qcow_data->dbgfs_dir);
}
#endif
-static int __qcow_file_fmt_validate_compression_type(
- struct xloop_file_fmt *xlo_fmt)
+static int __qcow_file_fmt_validate_compression_type(struct xloop_file_fmt *xlo_fmt)
{
struct xloop_file_fmt_qcow_data *qcow_data = xlo_fmt->private_data;
- switch (qcow_data->compression_type) {
- case QCOW_COMPRESSION_TYPE_ZLIB:
+ switch (qcow_data->compression_type) {
+ case QCOW_COMPRESSION_TYPE_ZLIB:
#ifdef CONFIG_ZSTD_DECOMPRESS
- case QCOW_COMPRESSION_TYPE_ZSTD:
+ case QCOW_COMPRESSION_TYPE_ZSTD:
#endif
- break;
- default:
- dev_err(xloop_file_fmt_to_dev(xlo_fmt), "unknown compression type: %u",
- qcow_data->compression_type);
- return -ENOTSUPP;
- }
-
- /*
- * if the compression type differs from QCOW_COMPRESSION_TYPE_ZLIB
- * the incompatible feature flag must be set
- */
- if (qcow_data->compression_type == QCOW_COMPRESSION_TYPE_ZLIB) {
- if (qcow_data->incompatible_features & QCOW_INCOMPAT_COMPRESSION) {
- dev_err(xloop_file_fmt_to_dev(xlo_fmt), "compression type "
- "incompatible feature bit must not be set\n");
- return -EINVAL;
- }
- } else {
- if (!(qcow_data->incompatible_features & QCOW_INCOMPAT_COMPRESSION)) {
- dev_err(xloop_file_fmt_to_dev(xlo_fmt), "compression type "
- "incompatible feature bit must be set\n");
- return -EINVAL;
- }
- }
-
- return 0;
+ break;
+ default:
+ dev_err(xloop_file_fmt_to_dev(xlo_fmt), "unknown compression type: %u", qcow_data->compression_type);
+ return -ENOTSUPP;
+ }
+
+ /*
+ * if the compression type differs from QCOW_COMPRESSION_TYPE_ZLIB
+ * the incompatible feature flag must be set
+ */
+ if (qcow_data->compression_type == QCOW_COMPRESSION_TYPE_ZLIB) {
+ if (qcow_data->incompatible_features & QCOW_INCOMPAT_COMPRESSION) {
+ dev_err(xloop_file_fmt_to_dev(xlo_fmt),
+ "compression type incompatible feature bit must not be set\n");
+ return -EINVAL;
+ }
+ } else {
+ if (!(qcow_data->incompatible_features & QCOW_INCOMPAT_COMPRESSION)) {
+ dev_err(xloop_file_fmt_to_dev(xlo_fmt),
+ "compression type incompatible feature bit must be set\n");
+ return -EINVAL;
+ }
+ }
+
+ return 0;
}
static int qcow_file_fmt_init(struct xloop_file_fmt *xlo_fmt)
@@ -539,8 +479,10 @@ static int qcow_file_fmt_init(struct xloop_file_fmt *xlo_fmt)
if (ret)
goto free_qcow_data;
- /* save information of the header fields in human readable format in
- * a file buffer to access it with debugfs */
+ /*
+ * save information of the header fields in human readable format in
+ * a file buffer to access it with debugfs
+ */
#ifdef CONFIG_DEBUG_FS
__qcow_file_fmt_header_to_buf(xlo_fmt, &header);
#endif
@@ -548,10 +490,8 @@ static int qcow_file_fmt_init(struct xloop_file_fmt *xlo_fmt)
qcow_data->qcow_version = header.version;
/* Initialise cluster size */
- if (header.cluster_bits < QCOW_MIN_CLUSTER_BITS
- || header.cluster_bits > QCOW_MAX_CLUSTER_BITS) {
- dev_err(xloop_file_fmt_to_dev(xlo_fmt), "unsupported cluster size: "
- "2^%d\n", header.cluster_bits);
+ if (header.cluster_bits < QCOW_MIN_CLUSTER_BITS || header.cluster_bits > QCOW_MAX_CLUSTER_BITS) {
+ dev_err(xloop_file_fmt_to_dev(xlo_fmt), "unsupported cluster size: 2^%d\n", header.cluster_bits);
ret = -EINVAL;
goto free_qcow_data;
}
@@ -560,22 +500,19 @@ static int qcow_file_fmt_init(struct xloop_file_fmt *xlo_fmt)
qcow_data->cluster_size = 1 << qcow_data->cluster_bits;
if (header.header_length > qcow_data->cluster_size) {
- dev_err(xloop_file_fmt_to_dev(xlo_fmt), "QCOW header exceeds cluster "
- "size\n");
+ dev_err(xloop_file_fmt_to_dev(xlo_fmt), "QCOW header exceeds cluster size\n");
ret = -EINVAL;
goto free_qcow_data;
}
if (header.backing_file_offset > qcow_data->cluster_size) {
- dev_err(xloop_file_fmt_to_dev(xlo_fmt), "invalid backing file "
- "offset\n");
+ dev_err(xloop_file_fmt_to_dev(xlo_fmt), "invalid backing file offset\n");
ret = -EINVAL;
goto free_qcow_data;
}
if (header.backing_file_offset) {
- dev_err(xloop_file_fmt_to_dev(xlo_fmt), "backing file support not "
- "available\n");
+ dev_err(xloop_file_fmt_to_dev(xlo_fmt), "backing file support not available\n");
ret = -ENOTSUPP;
goto free_qcow_data;
}
@@ -585,69 +522,61 @@ static int qcow_file_fmt_init(struct xloop_file_fmt *xlo_fmt)
qcow_data->compatible_features = header.compatible_features;
qcow_data->autoclear_features = header.autoclear_features;
- /*
- * Handle compression type
- * Older qcow2 images don't contain the compression type header.
- * Distinguish them by the header length and use
- * the only valid (default) compression type in that case
- */
- if (header.header_length > offsetof(struct xloop_file_fmt_qcow_header,
- compression_type)) {
- qcow_data->compression_type = header.compression_type;
- } else {
- qcow_data->compression_type = QCOW_COMPRESSION_TYPE_ZLIB;
- }
-
- ret = __qcow_file_fmt_validate_compression_type(xlo_fmt);
- if (ret) {
- goto free_qcow_data;
- }
+ /*
+ * Handle compression type
+ * Older qcow2 images don't contain the compression type header.
+ * Distinguish them by the header length and use
+ * the only valid (default) compression type in that case
+ */
+ if (header.header_length > offsetof(struct xloop_file_fmt_qcow_header, compression_type))
+ qcow_data->compression_type = header.compression_type;
+ else
+ qcow_data->compression_type = QCOW_COMPRESSION_TYPE_ZLIB;
+
+ ret = __qcow_file_fmt_validate_compression_type(xlo_fmt);
+ if (ret)
+ goto free_qcow_data;
/* check for incompatible features */
if (qcow_data->incompatible_features & QCOW_INCOMPAT_DIRTY) {
- dev_err(xloop_file_fmt_to_dev(xlo_fmt), "image contains inconsistent "
- "refcounts\n");
+ dev_err(xloop_file_fmt_to_dev(xlo_fmt), "image contains inconsistent refcounts\n");
ret = -EACCES;
goto free_qcow_data;
}
if (qcow_data->incompatible_features & QCOW_INCOMPAT_CORRUPT) {
- dev_err(xloop_file_fmt_to_dev(xlo_fmt), "image is corrupt; cannot be "
- "opened read/write\n");
+ dev_err(xloop_file_fmt_to_dev(xlo_fmt), "image is corrupt; cannot be opened read/write\n");
ret = -EACCES;
goto free_qcow_data;
}
if (qcow_data->incompatible_features & QCOW_INCOMPAT_DATA_FILE) {
- dev_err(xloop_file_fmt_to_dev(xlo_fmt), "data-file is required for "
- "this image\n");
+ dev_err(xloop_file_fmt_to_dev(xlo_fmt), "data-file is required for this image\n");
ret = -EINVAL;
goto free_qcow_data;
}
qcow_data->subclusters_per_cluster =
- xloop_file_fmt_qcow_has_subclusters(qcow_data) ?
- QCOW_EXTL2_SUBCLUSTERS_PER_CLUSTER : 1;
- qcow_data->subcluster_size =
- qcow_data->cluster_size / qcow_data->subclusters_per_cluster;
- /*
+ xloop_file_fmt_qcow_has_subclusters(qcow_data) ? QCOW_EXTL2_SUBCLUSTERS_PER_CLUSTER : 1;
+ qcow_data->subcluster_size = qcow_data->cluster_size / qcow_data->subclusters_per_cluster;
+ /*
* check if subcluster_size is non-zero to avoid unknown results of
* __builtin_ctz
*/
ASSERT(qcow_data->subcluster_size != 0);
- qcow_data->subcluster_bits = __builtin_ctz(qcow_data->subcluster_size);
+ qcow_data->subcluster_bits = __builtin_ctz(qcow_data->subcluster_size);
- if (qcow_data->subcluster_size < (1 << QCOW_MIN_CLUSTER_BITS)) {
- dev_err(xloop_file_fmt_to_dev(xlo_fmt), "unsupported subcluster "
- "size: %d\n", qcow_data->subcluster_size);
- ret = -EINVAL;
- goto free_qcow_data;
- }
+ if (qcow_data->subcluster_size < (1 << QCOW_MIN_CLUSTER_BITS)) {
+ dev_err(xloop_file_fmt_to_dev(xlo_fmt), "unsupported subcluster size: %d\n",
+ qcow_data->subcluster_size);
+ ret = -EINVAL;
+ goto free_qcow_data;
+ }
/* Check support for various header values */
if (header.refcount_order > 6) {
- dev_err(xloop_file_fmt_to_dev(xlo_fmt), "reference count entry width "
- "too large; may not exceed 64 bits\n");
+ dev_err(xloop_file_fmt_to_dev(xlo_fmt),
+ "reference count entry width too large; may not exceed 64 bits\n");
ret = -EINVAL;
goto free_qcow_data;
}
@@ -658,23 +587,20 @@ static int qcow_file_fmt_init(struct xloop_file_fmt *xlo_fmt)
qcow_data->crypt_method_header = header.crypt_method;
if (qcow_data->crypt_method_header) {
- dev_err(xloop_file_fmt_to_dev(xlo_fmt), "encryption support not "
- "available\n");
+ dev_err(xloop_file_fmt_to_dev(xlo_fmt), "encryption support not available\n");
ret = -ENOTSUPP;
goto free_qcow_data;
}
- /*
+ /*
* check if xloop_file_fmt_qcow_l2_entry_size(qcow_data) is non-zero to
* avoid unknown results of __builtin_ctz
*/
ASSERT(xloop_file_fmt_qcow_l2_entry_size(qcow_data) != 0);
- qcow_data->l2_bits = qcow_data->cluster_bits -
- __builtin_ctz(xloop_file_fmt_qcow_l2_entry_size(qcow_data));
+ qcow_data->l2_bits = qcow_data->cluster_bits - __builtin_ctz(xloop_file_fmt_qcow_l2_entry_size(qcow_data));
qcow_data->l2_size = 1 << qcow_data->l2_bits;
/* 2^(qcow_data->refcount_order - 3) is the refcount width in bytes */
- qcow_data->refcount_block_bits = qcow_data->cluster_bits -
- (qcow_data->refcount_order - 3);
+ qcow_data->refcount_block_bits = qcow_data->cluster_bits - (qcow_data->refcount_order - 3);
qcow_data->refcount_block_size = 1 << qcow_data->refcount_block_bits;
qcow_data->size = header.size;
qcow_data->csize_shift = (62 - (qcow_data->cluster_bits - 8));
@@ -682,49 +608,42 @@ static int qcow_file_fmt_init(struct xloop_file_fmt *xlo_fmt)
qcow_data->cluster_offset_mask = (1LL << qcow_data->csize_shift) - 1;
qcow_data->refcount_table_offset = header.refcount_table_offset;
- qcow_data->refcount_table_size = header.refcount_table_clusters <<
- (qcow_data->cluster_bits - 3);
+ qcow_data->refcount_table_size = header.refcount_table_clusters << (qcow_data->cluster_bits - 3);
if (header.refcount_table_clusters == 0) {
- dev_err(xloop_file_fmt_to_dev(xlo_fmt), "image does not contain a "
- "reference count table\n");
+ dev_err(xloop_file_fmt_to_dev(xlo_fmt), "image does not contain a reference count table\n");
ret = -EINVAL;
goto free_qcow_data;
}
- ret = __qcow_file_fmt_validate_table(xlo_fmt,
- qcow_data->refcount_table_offset,
- header.refcount_table_clusters, qcow_data->cluster_size,
- QCOW_MAX_REFTABLE_SIZE, "Reference count table");
- if (ret < 0) {
+ ret = __qcow_file_fmt_validate_table(xlo_fmt, qcow_data->refcount_table_offset, header.refcount_table_clusters,
+ qcow_data->cluster_size, QCOW_MAX_REFTABLE_SIZE, "Reference count table");
+ if (ret < 0)
goto free_qcow_data;
- }
- /* The total size in bytes of the snapshot table is checked in
+ /*
+ * The total size in bytes of the snapshot table is checked in
* qcow2_read_snapshots() because the size of each snapshot is
* variable and we don't know it yet.
- * Here we only check the offset and number of snapshots. */
- ret = __qcow_file_fmt_validate_table(xlo_fmt, header.snapshots_offset,
- header.nb_snapshots,
- sizeof(struct xloop_file_fmt_qcow_snapshot_header),
- sizeof(struct xloop_file_fmt_qcow_snapshot_header) *
- QCOW_MAX_SNAPSHOTS, "Snapshot table");
- if (ret < 0) {
+ * Here we only check the offset and number of snapshots.
+ */
+ ret = __qcow_file_fmt_validate_table(xlo_fmt, header.snapshots_offset, header.nb_snapshots,
+ sizeof(struct xloop_file_fmt_qcow_snapshot_header),
+ sizeof(struct xloop_file_fmt_qcow_snapshot_header) * QCOW_MAX_SNAPSHOTS,
+ "Snapshot table");
+ if (ret < 0)
goto free_qcow_data;
- }
/* read the level 1 table */
- ret = __qcow_file_fmt_validate_table(xlo_fmt, header.l1_table_offset,
- header.l1_size, QCOW_L1E_SIZE, QCOW_MAX_L1_SIZE,
- "Active L1 table");
- if (ret < 0) {
+ ret = __qcow_file_fmt_validate_table(xlo_fmt, header.l1_table_offset, header.l1_size, QCOW_L1E_SIZE,
+ QCOW_MAX_L1_SIZE, "Active L1 table");
+ if (ret < 0)
goto free_qcow_data;
- }
+
qcow_data->l1_size = header.l1_size;
qcow_data->l1_table_offset = header.l1_table_offset;
- l1_vm_state_index = xloop_file_fmt_qcow_size_to_l1(qcow_data,
- header.size);
+ l1_vm_state_index = xloop_file_fmt_qcow_size_to_l1(qcow_data, header.size);
if (l1_vm_state_index > INT_MAX) {
dev_err(xloop_file_fmt_to_dev(xlo_fmt), "image is too big\n");
ret = -EFBIG;
@@ -732,8 +651,7 @@ static int qcow_file_fmt_init(struct xloop_file_fmt *xlo_fmt)
}
qcow_data->l1_vm_state_index = l1_vm_state_index;
- /* the L1 table must contain at least enough entries to put header.size
- * bytes */
+ /* the L1 table must contain at least enough entries to put header.size bytes */
if (qcow_data->l1_size < qcow_data->l1_vm_state_index) {
dev_err(xloop_file_fmt_to_dev(xlo_fmt), "L1 table is too small\n");
ret = -EINVAL;
@@ -741,27 +659,20 @@ static int qcow_file_fmt_init(struct xloop_file_fmt *xlo_fmt)
}
if (qcow_data->l1_size > 0) {
- qcow_data->l1_table = vzalloc(round_up(qcow_data->l1_size *
- QCOW_L1E_SIZE, 512));
+ qcow_data->l1_table = vzalloc(round_up(qcow_data->l1_size * QCOW_L1E_SIZE, 512));
if (qcow_data->l1_table == NULL) {
- dev_err(xloop_file_fmt_to_dev(xlo_fmt), "could not allocate "
- "L1 table\n");
ret = -ENOMEM;
goto free_qcow_data;
}
- len = kernel_read(xlo->xlo_backing_file, qcow_data->l1_table,
- qcow_data->l1_size * QCOW_L1E_SIZE,
- &qcow_data->l1_table_offset);
+ len = kernel_read(xlo->xlo_backing_file, qcow_data->l1_table, qcow_data->l1_size * QCOW_L1E_SIZE,
+ &qcow_data->l1_table_offset);
if (len < 0) {
- dev_err(xloop_file_fmt_to_dev(xlo_fmt), "could not read "
- "L1 table\n");
+ dev_err(xloop_file_fmt_to_dev(xlo_fmt), "could not read L1 table\n");
ret = len;
goto free_l1_table;
}
- for (i = 0; i < qcow_data->l1_size; i++) {
- qcow_data->l1_table[i] =
- be64_to_cpu(qcow_data->l1_table[i]);
- }
+ for (i = 0; i < qcow_data->l1_size; i++)
+ qcow_data->l1_table[i] = be64_to_cpu(qcow_data->l1_table[i]);
}
/* Internal snapshots */
@@ -769,8 +680,7 @@ static int qcow_file_fmt_init(struct xloop_file_fmt *xlo_fmt)
qcow_data->nb_snapshots = header.nb_snapshots;
if (qcow_data->nb_snapshots > 0) {
- dev_err(xloop_file_fmt_to_dev(xlo_fmt), "snapshots support not "
- "available\n");
+ dev_err(xloop_file_fmt_to_dev(xlo_fmt), "snapshots support not available\n");
ret = -ENOTSUPP;
goto free_l1_table;
}
@@ -778,9 +688,7 @@ static int qcow_file_fmt_init(struct xloop_file_fmt *xlo_fmt)
/* create cache for L2 */
virtual_disk_size = qcow_data->size;
max_l2_entries = DIV64_U64_ROUND_UP(virtual_disk_size, qcow_data->cluster_size);
- max_l2_cache = round_up(
- max_l2_entries * xloop_file_fmt_qcow_l2_entry_size(qcow_data),
- qcow_data->cluster_size);
+ max_l2_cache = round_up(max_l2_entries * xloop_file_fmt_qcow_l2_entry_size(qcow_data), qcow_data->cluster_size);
/* define the maximum L2 cache size */
l2_cache_max_setting = QCOW_DEFAULT_L2_CACHE_MAX_SIZE;
@@ -789,13 +697,12 @@ static int qcow_file_fmt_init(struct xloop_file_fmt *xlo_fmt)
l2_cache_size = min(max_l2_cache, l2_cache_max_setting);
/* determine the size of a cache entry */
- l2_cache_entry_size = min(qcow_data->cluster_size, (int)PAGE_SIZE);
+ l2_cache_entry_size = min_t(int, qcow_data->cluster_size, PAGE_SIZE);
/* calculate the number of cache tables */
l2_cache_size = div_u64(l2_cache_size, l2_cache_entry_size);
- if (l2_cache_size < QCOW_MIN_L2_CACHE_SIZE) {
+ if (l2_cache_size < QCOW_MIN_L2_CACHE_SIZE)
l2_cache_size = QCOW_MIN_L2_CACHE_SIZE;
- }
if (l2_cache_size > INT_MAX) {
dev_err(xloop_file_fmt_to_dev(xlo_fmt), "L2 cache size too big\n");
@@ -803,11 +710,9 @@ static int qcow_file_fmt_init(struct xloop_file_fmt *xlo_fmt)
goto free_l1_table;
}
- qcow_data->l2_slice_size = div_u64(l2_cache_entry_size,
- xloop_file_fmt_qcow_l2_entry_size(qcow_data));
+ qcow_data->l2_slice_size = div_u64(l2_cache_entry_size, xloop_file_fmt_qcow_l2_entry_size(qcow_data));
- qcow_data->l2_table_cache = xloop_file_fmt_qcow_cache_create(xlo_fmt,
- l2_cache_size, l2_cache_entry_size);
+ qcow_data->l2_table_cache = xloop_file_fmt_qcow_cache_create(xlo_fmt, l2_cache_size, l2_cache_entry_size);
if (!qcow_data->l2_table_cache) {
ret = -ENOMEM;
goto free_l1_table;
@@ -847,18 +752,14 @@ static void qcow_file_fmt_exit(struct xloop_file_fmt *xlo_fmt)
__qcow_file_fmt_compression_exit(xlo_fmt);
- if (qcow_data->l1_table) {
+ if (qcow_data->l1_table)
vfree(qcow_data->l1_table);
- }
- if (qcow_data->l2_table_cache) {
+ if (qcow_data->l2_table_cache)
xloop_file_fmt_qcow_cache_destroy(xlo_fmt);
- }
- if (qcow_data) {
- kfree(qcow_data);
- xlo_fmt->private_data = NULL;
- }
+ kfree(qcow_data);
+ xlo_fmt->private_data = NULL;
}
/*
@@ -874,11 +775,8 @@ static void qcow_file_fmt_exit(struct xloop_file_fmt *xlo_fmt)
* Returns: 0 on success
* -EIO on fail
*/
-static ssize_t __qcow_file_fmt_zlib_decompress(struct xloop_file_fmt *xlo_fmt,
- void *dest,
- size_t dest_size,
- const void *src,
- size_t src_size)
+static ssize_t __qcow_file_fmt_zlib_decompress(struct xloop_file_fmt *xlo_fmt, void *dest, size_t dest_size,
+ const void *src, size_t src_size)
{
struct xloop_file_fmt_qcow_data *qcow_data = xlo_fmt->private_data;
u8 zerostuff = 0;
@@ -901,8 +799,7 @@ static ssize_t __qcow_file_fmt_zlib_decompress(struct xloop_file_fmt *xlo_fmt,
* byte when being used in the (undocumented) raw deflate mode.
* (From USAGI).
*/
- if (ret == Z_OK && !qcow_data->zlib_dstrm->avail_in &&
- qcow_data->zlib_dstrm->avail_out) {
+ if (ret == Z_OK && !qcow_data->zlib_dstrm->avail_in && qcow_data->zlib_dstrm->avail_out) {
qcow_data->zlib_dstrm->next_in = &zerostuff;
qcow_data->zlib_dstrm->avail_in = 1;
ret = zlib_inflate(qcow_data->zlib_dstrm, Z_FINISH);
@@ -930,83 +827,71 @@ out:
* Returns: 0 on success
* -EIO on any error
*/
-static ssize_t __qcow_file_fmt_zstd_decompress(struct xloop_file_fmt *xlo_fmt,
- void *dest,
- size_t dest_size,
- const void *src,
- size_t src_size)
+static ssize_t __qcow_file_fmt_zstd_decompress(struct xloop_file_fmt *xlo_fmt, void *dest, size_t dest_size,
+ const void *src, size_t src_size)
{
struct xloop_file_fmt_qcow_data *qcow_data = xlo_fmt->private_data;
size_t zstd_ret = 0;
- ssize_t ret = 0;
+ ssize_t ret = 0;
- ZSTD_outBuffer output = {
- .dst = dest,
- .size = dest_size,
- .pos = 0
- };
+ ZSTD_outBuffer output = { .dst = dest, .size = dest_size, .pos = 0 };
- ZSTD_inBuffer input = {
- .src = src,
- .size = src_size,
- .pos = 0
- };
+ ZSTD_inBuffer input = { .src = src, .size = src_size, .pos = 0 };
zstd_ret = ZSTD_resetDStream(qcow_data->zstd_dstrm);
- if (ZSTD_isError(zstd_ret)) {
- ret = -EIO;
+ if (ZSTD_isError(zstd_ret)) {
+ ret = -EIO;
goto out;
- }
+ }
+
+ /*
+ * The compressed stream from the input buffer may consist of more
+ * than one zstd frame. So we iterate until we get a fully
+ * uncompressed cluster.
+ * From zstd docs related to ZSTD_decompressStream:
+ * "return : 0 when a frame is completely decoded and fully flushed"
+ * We suppose that this means: each time ZSTD_decompressStream reads
+ * only ONE full frame and returns 0 if and only if that frame
+ * is completely decoded and flushed. Only after returning 0,
+ * ZSTD_decompressStream reads another ONE full frame.
+ */
+ while (output.pos < output.size) {
+ size_t last_in_pos = input.pos;
+ size_t last_out_pos = output.pos;
+
+ zstd_ret = ZSTD_decompressStream(qcow_data->zstd_dstrm, &output, &input);
+ if (ZSTD_isError(zstd_ret)) {
+ ret = -EIO;
+ break;
+ }
+
+ /*
+ * The ZSTD manual is vague about what to do if it reads
+ * the buffer partially, and we don't want to get stuck
+ * in an infinite loop where ZSTD_decompressStream
+ * returns > 0 waiting for another input chunk. So, we add
+ * a check which ensures that the loop makes some progress
+ * on each step.
+ */
+ if (last_in_pos >= input.pos && last_out_pos >= output.pos) {
+ ret = -EIO;
+ break;
+ }
+ }
/*
- * The compressed stream from the input buffer may consist of more
- * than one zstd frame. So we iterate until we get a fully
- * uncompressed cluster.
- * From zstd docs related to ZSTD_decompressStream:
- * "return : 0 when a frame is completely decoded and fully flushed"
- * We suppose that this means: each time ZSTD_decompressStream reads
- * only ONE full frame and returns 0 if and only if that frame
- * is completely decoded and flushed. Only after returning 0,
- * ZSTD_decompressStream reads another ONE full frame.
- */
- while (output.pos < output.size) {
- size_t last_in_pos = input.pos;
- size_t last_out_pos = output.pos;
- zstd_ret = ZSTD_decompressStream(qcow_data->zstd_dstrm, &output, &input);
-
- if (ZSTD_isError(zstd_ret)) {
- ret = -EIO;
- break;
- }
-
- /*
- * The ZSTD manual is vague about what to do if it reads
- * the buffer partially, and we don't want to get stuck
- * in an infinite loop where ZSTD_decompressStream
- * returns > 0 waiting for another input chunk. So, we add
- * a check which ensures that the loop makes some progress
- * on each step.
- */
- if (last_in_pos >= input.pos &&
- last_out_pos >= output.pos) {
- ret = -EIO;
- break;
- }
- }
- /*
- * Make sure that we have the frame fully flushed here
- * if not, we somehow managed to get uncompressed cluster
- * greater then the cluster size, possibly because of its
- * damage.
- */
- if (zstd_ret > 0) {
- ret = -EIO;
- }
+ * Make sure that we have the frame fully flushed here
+ * if not, we somehow managed to get uncompressed cluster
+ * greater then the cluster size, possibly because of its
+ * damage.
+ */
+ if (zstd_ret > 0)
+ ret = -EIO;
out:
- ASSERT(ret == 0 || ret == -EIO);
- return ret;
+ ASSERT(ret == 0 || ret == -EIO);
+ return ret;
}
#endif
@@ -1023,39 +908,31 @@ out:
* Returns: compressed size on success
* a negative error code on failure
*/
-static ssize_t __qcow_file_fmt_buffer_decompress(struct xloop_file_fmt *xlo_fmt,
- void *dest,
- size_t dest_size,
- const void *src,
- size_t src_size)
+static ssize_t __qcow_file_fmt_buffer_decompress(struct xloop_file_fmt *xlo_fmt, void *dest, size_t dest_size,
+ const void *src, size_t src_size)
{
- struct xloop_file_fmt_qcow_data *qcow_data = xlo_fmt->private_data;
- qcow_file_fmt_decompress_fn decompress_fn;
+ struct xloop_file_fmt_qcow_data *qcow_data = xlo_fmt->private_data;
+ qcow_file_fmt_decompress_fn decompress_fn;
- switch (qcow_data->compression_type) {
- case QCOW_COMPRESSION_TYPE_ZLIB:
- decompress_fn = __qcow_file_fmt_zlib_decompress;
- break;
+ switch (qcow_data->compression_type) {
+ case QCOW_COMPRESSION_TYPE_ZLIB:
+ decompress_fn = __qcow_file_fmt_zlib_decompress;
+ break;
#ifdef CONFIG_ZSTD_DECOMPRESS
- case QCOW_COMPRESSION_TYPE_ZSTD:
- decompress_fn = __qcow_file_fmt_zstd_decompress;
- break;
+ case QCOW_COMPRESSION_TYPE_ZSTD:
+ decompress_fn = __qcow_file_fmt_zstd_decompress;
+ break;
#endif
- default:
- return -EINVAL;
- }
+ default:
+ return -EINVAL;
+ }
- return decompress_fn(xlo_fmt, dest, dest_size, src, src_size);
+ return decompress_fn(xlo_fmt, dest, dest_size, src, src_size);
}
-
-static int __qcow_file_fmt_read_compressed(struct xloop_file_fmt *xlo_fmt,
- struct bio_vec *bvec,
- u64 file_cluster_offset,
- u64 offset,
- u64 bytes,
- u64 bytes_done)
+static int __qcow_file_fmt_read_compressed(struct xloop_file_fmt *xlo_fmt, struct bio_vec *bvec,
+ u64 file_cluster_offset, u64 offset, u64 bytes, u64 bytes_done)
{
struct xloop_file_fmt_qcow_data *qcow_data = xlo_fmt->private_data;
struct xloop_device *xlo = xloop_file_fmt_get_xlo(xlo_fmt);
@@ -1065,15 +942,11 @@ static int __qcow_file_fmt_read_compressed(struct xloop_file_fmt *xlo_fmt,
ssize_t len;
void *data;
unsigned long irq_flags;
- int offset_in_cluster = xloop_file_fmt_qcow_offset_into_cluster(
- qcow_data, offset);
+ int offset_in_cluster = xloop_file_fmt_qcow_offset_into_cluster(qcow_data, offset);
coffset = file_cluster_offset & qcow_data->cluster_offset_mask;
- nb_csectors = ((file_cluster_offset >> qcow_data->csize_shift) &
- qcow_data->csize_mask) + 1;
- csize = nb_csectors * QCOW_COMPRESSED_SECTOR_SIZE -
- (coffset & ~QCOW_COMPRESSED_SECTOR_MASK);
-
+ nb_csectors = ((file_cluster_offset >> qcow_data->csize_shift) & qcow_data->csize_mask) + 1;
+ csize = nb_csectors * QCOW_COMPRESSED_SECTOR_SIZE - (coffset & ~QCOW_COMPRESSED_SECTOR_MASK);
if (qcow_data->cmp_last_coffset != coffset) {
in_buf = vmalloc(csize);
@@ -1089,8 +962,8 @@ static int __qcow_file_fmt_read_compressed(struct xloop_file_fmt *xlo_fmt,
goto out_free_in_buf;
}
- if (__qcow_file_fmt_buffer_decompress(xlo_fmt, qcow_data->cmp_out_buf,
- qcow_data->cluster_size, in_buf, csize) < 0) {
+ if (__qcow_file_fmt_buffer_decompress(xlo_fmt, qcow_data->cmp_out_buf, qcow_data->cluster_size, in_buf,
+ csize) < 0) {
qcow_data->cmp_last_coffset = ULLONG_MAX;
ret = -EIO;
goto out_free_in_buf;
@@ -1109,9 +982,7 @@ out_free_in_buf:
return ret;
}
-static int __qcow_file_fmt_read_bvec(struct xloop_file_fmt *xlo_fmt,
- struct bio_vec *bvec,
- loff_t *ppos)
+static int __qcow_file_fmt_read_bvec(struct xloop_file_fmt *xlo_fmt, struct bio_vec *bvec, loff_t *ppos)
{
struct xloop_file_fmt_qcow_data *qcow_data = xlo_fmt->private_data;
struct xloop_device *xlo = xloop_file_fmt_get_xlo(xlo_fmt);
@@ -1130,18 +1001,14 @@ static int __qcow_file_fmt_read_bvec(struct xloop_file_fmt *xlo_fmt,
bytes = bvec->bv_len;
while (bytes != 0) {
-
/* prepare next request */
cur_bytes = bytes;
- ret = xloop_file_fmt_qcow_get_host_offset(xlo_fmt, *ppos,
- &cur_bytes, &host_offset, &type);
- if (ret < 0) {
+ ret = xloop_file_fmt_qcow_get_host_offset(xlo_fmt, *ppos, &cur_bytes, &host_offset, &type);
+ if (ret < 0)
goto fail;
- }
- offset_in_cluster = xloop_file_fmt_qcow_offset_into_cluster(
- qcow_data, *ppos);
+ offset_in_cluster = xloop_file_fmt_qcow_offset_into_cluster(qcow_data, *ppos);
switch (type) {
case QCOW_SUBCLUSTER_ZERO_PLAIN:
@@ -1155,11 +1022,9 @@ static int __qcow_file_fmt_read_bvec(struct xloop_file_fmt *xlo_fmt,
break;
case QCOW_SUBCLUSTER_COMPRESSED:
- ret = __qcow_file_fmt_read_compressed(xlo_fmt, bvec,
- host_offset, *ppos, cur_bytes, bytes_done);
- if (ret < 0) {
+ ret = __qcow_file_fmt_read_compressed(xlo_fmt, bvec, host_offset, *ppos, cur_bytes, bytes_done);
+ if (ret < 0)
goto fail;
- }
break;
@@ -1167,8 +1032,7 @@ static int __qcow_file_fmt_read_bvec(struct xloop_file_fmt *xlo_fmt,
pos_read = host_offset;
data = bvec_kmap_irq(bvec, &irq_flags) + bytes_done;
- len = kernel_read(xlo->xlo_backing_file, data, cur_bytes,
- &pos_read);
+ len = kernel_read(xlo->xlo_backing_file, data, cur_bytes, &pos_read);
flush_dcache_page(bvec->bv_page);
bvec_kunmap_irq(data, &irq_flags);
@@ -1194,8 +1058,7 @@ fail:
return ret;
}
-static int qcow_file_fmt_read(struct xloop_file_fmt *xlo_fmt,
- struct request *rq)
+static int qcow_file_fmt_read(struct xloop_file_fmt *xlo_fmt, struct request *rq)
{
struct bio_vec bvec;
struct req_iterator iter;
@@ -1215,8 +1078,8 @@ static int qcow_file_fmt_read(struct xloop_file_fmt *xlo_fmt,
return ret;
}
-static loff_t qcow_file_fmt_sector_size(struct xloop_file_fmt *xlo_fmt,
- struct file *file, loff_t offset, loff_t sizelimit)
+static loff_t qcow_file_fmt_sector_size(struct xloop_file_fmt *xlo_fmt, struct file *file, loff_t offset,
+ loff_t sizelimit)
{
struct xloop_file_fmt_qcow_header header;
loff_t xloopsize;
@@ -1245,23 +1108,23 @@ static loff_t qcow_file_fmt_sector_size(struct xloop_file_fmt *xlo_fmt,
}
static struct xloop_file_fmt_ops qcow_file_fmt_ops = {
- .init = qcow_file_fmt_init,
- .exit = qcow_file_fmt_exit,
- .read = qcow_file_fmt_read,
- .write = NULL,
- .read_aio = NULL,
- .write_aio = NULL,
+ .init = qcow_file_fmt_init,
+ .exit = qcow_file_fmt_exit,
+ .read = qcow_file_fmt_read,
+ .write = NULL,
+ .read_aio = NULL,
+ .write_aio = NULL,
.write_zeros = NULL,
- .discard = NULL,
- .flush = NULL,
+ .discard = NULL,
+ .flush = NULL,
.sector_size = qcow_file_fmt_sector_size,
};
static struct xloop_file_fmt_driver qcow_file_fmt_driver = {
- .name = "QCOW",
+ .name = "QCOW",
.file_fmt_type = XLO_FILE_FMT_QCOW,
- .ops = &qcow_file_fmt_ops,
- .owner = THIS_MODULE,
+ .ops = &qcow_file_fmt_ops,
+ .owner = THIS_MODULE,
};
static int __init xloop_file_fmt_qcow_init(void)