diff options
author | Anthony Liguori <aliguori@us.ibm.com> | 2010-12-17 15:58:22 +0000 |
---|---|---|
committer | Kevin Wolf <kwolf@redhat.com> | 2011-04-13 12:06:41 +0200 |
commit | 21df65b6444858ddee3a86d8666571bb41695614 (patch) | |
tree | 142793b8ae8e6fef8b1aa412cf39e2340091fdf9 /block/qed-cluster.c | |
parent | d54f10bba7635b5ad8b750afd2bb2f0f8eb68b45 (diff) |
qed: Add support for zero clusters
Zero clusters are similar to unallocated clusters except instead of reading
their value from a backing file when one is available, the cluster is always
read as zero.
This implements read support only. At this stage, QED will never write a
zero cluster.
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
Signed-off-by: Stefan Hajnoczi <stefanha@linux.vnet.ibm.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
Diffstat (limited to 'block/qed-cluster.c')
-rw-r--r-- | block/qed-cluster.c | 31 |
1 files changed, 21 insertions, 10 deletions
diff --git a/block/qed-cluster.c b/block/qed-cluster.c index 0ec864b14c..3e19ad1766 100644 --- a/block/qed-cluster.c +++ b/block/qed-cluster.c @@ -23,7 +23,8 @@ * @n: Maximum number of clusters * @offset: Set to first cluster offset * - * This function scans tables for contiguous allocated or free clusters. + * This function scans tables for contiguous clusters. A contiguous run of + * clusters may be allocated, unallocated, or zero. */ static unsigned int qed_count_contiguous_clusters(BDRVQEDState *s, QEDTable *table, @@ -38,9 +39,14 @@ static unsigned int qed_count_contiguous_clusters(BDRVQEDState *s, *offset = last; for (i = index + 1; i < end; i++) { - if (last == 0) { - /* Counting free clusters */ - if (table->offsets[i] != 0) { + if (qed_offset_is_unalloc_cluster(last)) { + /* Counting unallocated clusters */ + if (!qed_offset_is_unalloc_cluster(table->offsets[i])) { + break; + } + } else if (qed_offset_is_zero_cluster(last)) { + /* Counting zero clusters */ + if (!qed_offset_is_zero_cluster(table->offsets[i])) { break; } } else { @@ -87,14 +93,19 @@ static void qed_find_cluster_cb(void *opaque, int ret) n = qed_count_contiguous_clusters(s, request->l2_table->table, index, n, &offset); - ret = offset ? QED_CLUSTER_FOUND : QED_CLUSTER_L2; - len = MIN(find_cluster_cb->len, n * s->header.cluster_size - - qed_offset_into_cluster(s, find_cluster_cb->pos)); - - if (offset && !qed_check_cluster_offset(s, offset)) { + if (qed_offset_is_unalloc_cluster(offset)) { + ret = QED_CLUSTER_L2; + } else if (qed_offset_is_zero_cluster(offset)) { + ret = QED_CLUSTER_ZERO; + } else if (qed_check_cluster_offset(s, offset)) { + ret = QED_CLUSTER_FOUND; + } else { ret = -EINVAL; } + len = MIN(find_cluster_cb->len, n * s->header.cluster_size - + qed_offset_into_cluster(s, find_cluster_cb->pos)); + out: find_cluster_cb->cb(find_cluster_cb->opaque, ret, offset, len); qemu_free(find_cluster_cb); @@ -132,7 +143,7 @@ void qed_find_cluster(BDRVQEDState *s, QEDRequest *request, uint64_t pos, len = MIN(len, (((pos >> s->l1_shift) + 1) << s->l1_shift) - pos); l2_offset = s->l1_table->offsets[qed_l1_index(s, pos)]; - if (!l2_offset) { + if (qed_offset_is_unalloc_cluster(l2_offset)) { cb(opaque, QED_CLUSTER_L1, 0, len); return; } |