diff options
Diffstat (limited to 'qemu/block/qed-cluster.c')
-rw-r--r-- | qemu/block/qed-cluster.c | 166 |
1 files changed, 0 insertions, 166 deletions
diff --git a/qemu/block/qed-cluster.c b/qemu/block/qed-cluster.c deleted file mode 100644 index c24e75616..000000000 --- a/qemu/block/qed-cluster.c +++ /dev/null @@ -1,166 +0,0 @@ -/* - * QEMU Enhanced Disk Format Cluster functions - * - * Copyright IBM, Corp. 2010 - * - * Authors: - * Stefan Hajnoczi <stefanha@linux.vnet.ibm.com> - * Anthony Liguori <aliguori@us.ibm.com> - * - * This work is licensed under the terms of the GNU LGPL, version 2 or later. - * See the COPYING.LIB file in the top-level directory. - * - */ - -#include "qemu/osdep.h" -#include "qed.h" - -/** - * Count the number of contiguous data clusters - * - * @s: QED state - * @table: L2 table - * @index: First cluster index - * @n: Maximum number of clusters - * @offset: Set to first cluster offset - * - * 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, - unsigned int index, - unsigned int n, - uint64_t *offset) -{ - unsigned int end = MIN(index + n, s->table_nelems); - uint64_t last = table->offsets[index]; - unsigned int i; - - *offset = last; - - for (i = index + 1; i < end; i++) { - 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 { - /* Counting allocated clusters */ - if (table->offsets[i] != last + s->header.cluster_size) { - break; - } - last = table->offsets[i]; - } - } - return i - index; -} - -typedef struct { - BDRVQEDState *s; - uint64_t pos; - size_t len; - - QEDRequest *request; - - /* User callback */ - QEDFindClusterFunc *cb; - void *opaque; -} QEDFindClusterCB; - -static void qed_find_cluster_cb(void *opaque, int ret) -{ - QEDFindClusterCB *find_cluster_cb = opaque; - BDRVQEDState *s = find_cluster_cb->s; - QEDRequest *request = find_cluster_cb->request; - uint64_t offset = 0; - size_t len = 0; - unsigned int index; - unsigned int n; - - if (ret) { - goto out; - } - - index = qed_l2_index(s, find_cluster_cb->pos); - n = qed_bytes_to_clusters(s, - qed_offset_into_cluster(s, find_cluster_cb->pos) + - find_cluster_cb->len); - n = qed_count_contiguous_clusters(s, request->l2_table->table, - index, n, &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); - g_free(find_cluster_cb); -} - -/** - * Find the offset of a data cluster - * - * @s: QED state - * @request: L2 cache entry - * @pos: Byte position in device - * @len: Number of bytes - * @cb: Completion function - * @opaque: User data for completion function - * - * This function translates a position in the block device to an offset in the - * image file. It invokes the cb completion callback to report back the - * translated offset or unallocated range in the image file. - * - * If the L2 table exists, request->l2_table points to the L2 table cache entry - * and the caller must free the reference when they are finished. The cache - * entry is exposed in this way to avoid callers having to read the L2 table - * again later during request processing. If request->l2_table is non-NULL it - * will be unreferenced before taking on the new cache entry. - */ -void qed_find_cluster(BDRVQEDState *s, QEDRequest *request, uint64_t pos, - size_t len, QEDFindClusterFunc *cb, void *opaque) -{ - QEDFindClusterCB *find_cluster_cb; - uint64_t l2_offset; - - /* Limit length to L2 boundary. Requests are broken up at the L2 boundary - * so that a request acts on one L2 table at a time. - */ - len = MIN(len, (((pos >> s->l1_shift) + 1) << s->l1_shift) - pos); - - l2_offset = s->l1_table->offsets[qed_l1_index(s, pos)]; - if (qed_offset_is_unalloc_cluster(l2_offset)) { - cb(opaque, QED_CLUSTER_L1, 0, len); - return; - } - if (!qed_check_table_offset(s, l2_offset)) { - cb(opaque, -EINVAL, 0, 0); - return; - } - - find_cluster_cb = g_malloc(sizeof(*find_cluster_cb)); - find_cluster_cb->s = s; - find_cluster_cb->pos = pos; - find_cluster_cb->len = len; - find_cluster_cb->cb = cb; - find_cluster_cb->opaque = opaque; - find_cluster_cb->request = request; - - qed_read_l2_table(s, request, l2_offset, - qed_find_cluster_cb, find_cluster_cb); -} |