Commit-ID: 330a3d0888106524ba0b4faa615f7bcf451a5045 Gitweb: http://git.kernel.org/tip/330a3d0888106524ba0b4faa615f7bcf451a5045 Author: Pekka Enberg <penberg@xxxxxxxxxx> AuthorDate: Sun, 10 Jul 2011 15:36:11 +0300 Committer: Pekka Enberg <penberg@xxxxxxxxxx> CommitDate: Sun, 10 Jul 2011 15:47:34 +0300 kvm tools, qcow: I/O error on compressed sectors We currently don't support compressed sectors in QCOW images so warn the user about it and return a I/O error. Cc: Asias He <asias.hejun@xxxxxxxxx> Cc: Cyrill Gorcunov <gorcunov@xxxxxxxxx> Cc: Ingo Molnar <mingo@xxxxxxx> Cc: Prasad Joshi <prasadjoshi124@xxxxxxxxx> Cc: Sasha Levin <levinsasha928@xxxxxxxxx> Signed-off-by: Pekka Enberg <penberg@xxxxxxxxxx> --- tools/kvm/disk/qcow.c | 35 +++++++++++++++++++++++++++++------ tools/kvm/include/kvm/qcow.h | 10 ++++------ 2 files changed, 33 insertions(+), 12 deletions(-) diff --git a/tools/kvm/disk/qcow.c b/tools/kvm/disk/qcow.c index 13c8bea..bf0ac33 100644 --- a/tools/kvm/disk/qcow.c +++ b/tools/kvm/disk/qcow.c @@ -260,7 +260,14 @@ static ssize_t qcow_read_cluster(struct qcow *q, u64 offset, void *dst, u32 dst_ length = dst_len; mutex_lock(&q->mutex); - l2_table_offset = be64_to_cpu(table->l1_table[l1_idx]) & ~header->oflag_mask; + + l2_table_offset = be64_to_cpu(table->l1_table[l1_idx]); + if (l2_table_offset & QCOW_OFLAG_COMPRESSED) { + pr_warning("compressed sectors are not supported"); + goto out_error; + } + + l2_table_offset &= QCOW_OFFSET_MASK; if (!l2_table_offset) goto zero_cluster; @@ -275,7 +282,13 @@ static ssize_t qcow_read_cluster(struct qcow *q, u64 offset, void *dst, u32 dst_ if (l2_idx >= l2_table_size) goto out_error; - clust_start = be64_to_cpu(l2_table->table[l2_idx]) & ~header->oflag_mask; + clust_start = be64_to_cpu(l2_table->table[l2_idx]); + if (clust_start & QCOW_OFLAG_COMPRESSED) { + pr_warning("compressed sectors are not supported"); + goto out_error; + } + + clust_start &= QCOW_OFFSET_MASK; if (!clust_start) goto zero_cluster; @@ -414,7 +427,13 @@ static ssize_t qcow_write_cluster(struct qcow *q, u64 offset, void *buf, u32 src mutex_lock(&q->mutex); - l2t_off = be64_to_cpu(table->l1_table[l1t_idx]) & ~header->oflag_mask; + l2t_off = be64_to_cpu(table->l1_table[l1t_idx]); + if (l2t_off & QCOW_OFLAG_COMPRESSED) { + pr_warning("compressed sectors are not supported"); + goto error; + } + + l2t_off &= QCOW_OFFSET_MASK; if (l2t_off) { /* read and cache l2 table */ l2t = qcow_read_l2_table(q, l2t_off); @@ -451,7 +470,13 @@ static ssize_t qcow_write_cluster(struct qcow *q, u64 offset, void *buf, u32 src if (!f_sz) goto error; - clust_start = be64_to_cpu(l2t->table[l2t_idx]) & ~header->oflag_mask; + clust_start = be64_to_cpu(l2t->table[l2t_idx]); + if (clust_start & QCOW_OFLAG_COMPRESSED) { + pr_warning("compressed sectors are not supported"); + goto error; + } + + clust_start &= QCOW_OFFSET_MASK; if (!clust_start) { clust_start = ALIGN(f_sz, clust_sz); l2t->table[l2t_idx] = cpu_to_be64(clust_start); @@ -621,7 +646,6 @@ static void *qcow2_read_header(int fd) .l1_size = f_header.l1_size, .cluster_bits = f_header.cluster_bits, .l2_bits = f_header.cluster_bits - 3, - .oflag_mask = QCOW2_OFLAG_MASK, }; return header; @@ -721,7 +745,6 @@ static void *qcow1_read_header(int fd) .l1_size = f_header.size / ((1 << f_header.l2_bits) * (1 << f_header.cluster_bits)), .cluster_bits = f_header.cluster_bits, .l2_bits = f_header.l2_bits, - .oflag_mask = QCOW1_OFLAG_MASK, }; return header; diff --git a/tools/kvm/include/kvm/qcow.h b/tools/kvm/include/kvm/qcow.h index 650d3c2..ec9c77d 100644 --- a/tools/kvm/include/kvm/qcow.h +++ b/tools/kvm/include/kvm/qcow.h @@ -13,13 +13,12 @@ #define QCOW1_VERSION 1 #define QCOW2_VERSION 2 -#define QCOW1_OFLAG_COMPRESSED (1LL << 63) +#define QCOW_OFLAG_COPIED (1ULL << 63) +#define QCOW_OFLAG_COMPRESSED (1ULL << 62) -#define QCOW1_OFLAG_MASK QCOW1_OFLAG_COMPRESSED +#define QCOW_OFLAGS_MASK (QCOW_OFLAG_COPIED|QCOW_OFLAG_COMPRESSED) -#define QCOW2_OFLAG_COPIED (1LL << 63) -#define QCOW2_OFLAG_COMPRESSED (1LL << 62) -#define QCOW2_OFLAG_MASK (QCOW2_OFLAG_COPIED|QCOW2_OFLAG_COMPRESSED) +#define QCOW_OFFSET_MASK (~QCOW_OFLAGS_MASK) #define MAX_CACHE_NODES 32 @@ -54,7 +53,6 @@ struct qcow_header { u32 l1_size; u8 cluster_bits; u8 l2_bits; - u64 oflag_mask; }; struct qcow1_header_disk { -- To unsubscribe from this list: send the line "unsubscribe linux-tip-commits" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html