Exemplo n.º 1
0
/**
 * 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);
}
Exemplo n.º 2
0
int qed_read_l2_table_sync(BDRVQEDState *s, QEDRequest *request, uint64_t offset)
{
    int ret = -EINPROGRESS;

    qed_read_l2_table(s, request, offset, qed_sync_cb, &ret);
    while (ret == -EINPROGRESS) {
        qemu_aio_wait();
    }

    return ret;
}
Exemplo n.º 3
0
int qed_read_l2_table_sync(BDRVQEDState *s, QEDRequest *request, uint64_t offset)
{
    int ret = -EINPROGRESS;

    qed_read_l2_table(s, request, offset, qed_sync_cb, &ret);
    while (ret == -EINPROGRESS) {
        aio_poll(bdrv_get_aio_context(s->bs), true);
    }

    return ret;
}