diff options
author | Kevin Wolf <kwolf@redhat.com> | 2012-03-14 19:15:03 +0100 |
---|---|---|
committer | Kevin Wolf <kwolf@redhat.com> | 2012-04-20 15:57:27 +0200 |
commit | 68d000a39074fe3888680491444a7fde2354cd84 (patch) | |
tree | 8ac53ab1e3685e049cdceeb17ee0342da44a7bed /block/qcow2.h | |
parent | 90b277593df873d3a2480f002e2eb5fe1f8e5277 (diff) |
qcow2: Ignore reserved bits in get_cluster_offset
With this change, reading from a qcow2 image ignores all reserved bits
that are set in an L1 or L2 table entry.
Now get_cluster_offset() assigns *cluster_offset only the offset without
any other flags. The cluster type is not longer encoded in the offset,
but a positive return value in case of success.
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
Diffstat (limited to 'block/qcow2.h')
-rw-r--r-- | block/qcow2.h | 21 |
1 files changed, 21 insertions, 0 deletions
diff --git a/block/qcow2.h b/block/qcow2.h index ddb976a759..a22d7fafbe 100644 --- a/block/qcow2.h +++ b/block/qcow2.h @@ -165,6 +165,16 @@ typedef struct QCowL2Meta QLIST_ENTRY(QCowL2Meta) next_in_flight; } QCowL2Meta; +enum { + QCOW2_CLUSTER_UNALLOCATED, + QCOW2_CLUSTER_NORMAL, + QCOW2_CLUSTER_COMPRESSED, +}; + +#define L1E_OFFSET_MASK 0x00ffffffffffff00ULL +#define L2E_OFFSET_MASK 0x00ffffffffffff00ULL +#define L2E_COMPRESSED_OFFSET_SIZE_MASK 0x3fffffffffffffffULL + static inline int size_to_clusters(BDRVQcowState *s, int64_t size) { return (size + (s->cluster_size - 1)) >> s->cluster_bits; @@ -182,6 +192,17 @@ static inline int64_t align_offset(int64_t offset, int n) return offset; } +static inline int qcow2_get_cluster_type(uint64_t l2_entry) +{ + if (l2_entry & QCOW_OFLAG_COMPRESSED) { + return QCOW2_CLUSTER_COMPRESSED; + } else if (!(l2_entry & L2E_OFFSET_MASK)) { + return QCOW2_CLUSTER_UNALLOCATED; + } else { + return QCOW2_CLUSTER_NORMAL; + } +} + // FIXME Need qcow2_ prefix to global functions |