mirror of
https://github.com/Motorhead1991/qemu.git
synced 2025-08-03 15:53:54 -06:00
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>
This commit is contained in:
parent
d54f10bba7
commit
21df65b644
4 changed files with 66 additions and 17 deletions
|
@ -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;
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue