Commit 4bc74be9 authored by Paolo Bonzini's avatar Paolo Bonzini Committed by Stefan Hajnoczi
Browse files

block: return get_block_status data and flags for formats

parent 4333bb71
Loading
Loading
Loading
Loading
+7 −1
Original line number Diff line number Diff line
@@ -191,7 +191,13 @@ static int coroutine_fn cow_co_is_allocated(BlockDriverState *bs,
static int64_t coroutine_fn cow_co_get_block_status(BlockDriverState *bs,
        int64_t sector_num, int nb_sectors, int *num_same)
{
    return cow_co_is_allocated(bs, sector_num, nb_sectors, num_same);
    BDRVCowState *s = bs->opaque;
    int ret = cow_co_is_allocated(bs, sector_num, nb_sectors, num_same);
    int64_t offset = s->cow_sectors_offset + (sector_num << BDRV_SECTOR_BITS);
    if (ret < 0) {
        return ret;
    }
    return (ret ? BDRV_BLOCK_DATA : 0) | offset | BDRV_BLOCK_OFFSET_VALID;
}

static int cow_update_bitmap(BlockDriverState *bs, int64_t sector_num,
+8 −1
Original line number Diff line number Diff line
@@ -410,7 +410,14 @@ static int64_t coroutine_fn qcow_co_get_block_status(BlockDriverState *bs,
    if (n > nb_sectors)
        n = nb_sectors;
    *pnum = n;
    return (cluster_offset != 0);
    if (!cluster_offset) {
        return 0;
    }
    if ((cluster_offset & QCOW_OFLAG_COMPRESSED) || s->crypt_method) {
        return BDRV_BLOCK_DATA;
    }
    cluster_offset |= (index_in_cluster << BDRV_SECTOR_BITS);
    return BDRV_BLOCK_DATA | BDRV_BLOCK_OFFSET_VALID | cluster_offset;
}

static int decompress_buffer(uint8_t *out_buf, int out_buf_size,
+14 −2
Original line number Diff line number Diff line
@@ -693,7 +693,8 @@ static int64_t coroutine_fn qcow2_co_get_block_status(BlockDriverState *bs,
{
    BDRVQcowState *s = bs->opaque;
    uint64_t cluster_offset;
    int ret;
    int index_in_cluster, ret;
    int64_t status = 0;

    *pnum = nb_sectors;
    qemu_co_mutex_lock(&s->lock);
@@ -703,7 +704,18 @@ static int64_t coroutine_fn qcow2_co_get_block_status(BlockDriverState *bs,
        return ret;
    }

    return (cluster_offset != 0) || (ret == QCOW2_CLUSTER_ZERO);
    if (cluster_offset != 0 && ret != QCOW2_CLUSTER_COMPRESSED &&
        !s->crypt_method) {
        index_in_cluster = sector_num & (s->cluster_sectors - 1);
        cluster_offset |= (index_in_cluster << BDRV_SECTOR_BITS);
        status |= BDRV_BLOCK_OFFSET_VALID | cluster_offset;
    }
    if (ret == QCOW2_CLUSTER_ZERO) {
        status |= BDRV_BLOCK_ZERO;
    } else if (ret != QCOW2_CLUSTER_UNALLOCATED) {
        status |= BDRV_BLOCK_DATA;
    }
    return status;
}

/* handle reading after the end of the backing file */
+28 −7
Original line number Diff line number Diff line
@@ -652,16 +652,36 @@ static int bdrv_qed_create(const char *filename, QEMUOptionParameter *options)
}

typedef struct {
    BlockDriverState *bs;
    Coroutine *co;
    int is_allocated;
    uint64_t pos;
    int64_t status;
    int *pnum;
} QEDIsAllocatedCB;

static void qed_is_allocated_cb(void *opaque, int ret, uint64_t offset, size_t len)
{
    QEDIsAllocatedCB *cb = opaque;
    BDRVQEDState *s = cb->bs->opaque;
    *cb->pnum = len / BDRV_SECTOR_SIZE;
    cb->is_allocated = (ret == QED_CLUSTER_FOUND || ret == QED_CLUSTER_ZERO);
    switch (ret) {
    case QED_CLUSTER_FOUND:
        offset |= qed_offset_into_cluster(s, cb->pos);
        cb->status = BDRV_BLOCK_DATA | BDRV_BLOCK_OFFSET_VALID | offset;
        break;
    case QED_CLUSTER_ZERO:
        cb->status = BDRV_BLOCK_ZERO;
        break;
    case QED_CLUSTER_L2:
    case QED_CLUSTER_L1:
        cb->status = 0;
        break;
    default:
        assert(ret < 0);
        cb->status = ret;
        break;
    }

    if (cb->co) {
        qemu_coroutine_enter(cb->co, NULL);
    }
@@ -672,25 +692,26 @@ static int64_t coroutine_fn bdrv_qed_co_get_block_status(BlockDriverState *bs,
                                                 int nb_sectors, int *pnum)
{
    BDRVQEDState *s = bs->opaque;
    uint64_t pos = (uint64_t)sector_num * BDRV_SECTOR_SIZE;
    size_t len = (size_t)nb_sectors * BDRV_SECTOR_SIZE;
    QEDIsAllocatedCB cb = {
        .is_allocated = -1,
        .bs = bs,
        .pos = (uint64_t)sector_num * BDRV_SECTOR_SIZE,
        .status = BDRV_BLOCK_OFFSET_MASK,
        .pnum = pnum,
    };
    QEDRequest request = { .l2_table = NULL };

    qed_find_cluster(s, &request, pos, len, qed_is_allocated_cb, &cb);
    qed_find_cluster(s, &request, cb.pos, len, qed_is_allocated_cb, &cb);

    /* Now sleep if the callback wasn't invoked immediately */
    while (cb.is_allocated == -1) {
    while (cb.status == BDRV_BLOCK_OFFSET_MASK) {
        cb.co = qemu_coroutine_self();
        qemu_coroutine_yield();
    }

    qed_unref_l2_cache_entry(request.l2_table);

    return cb.is_allocated;
    return cb.status;
}

static int bdrv_qed_make_empty(BlockDriverState *bs)
+1 −1
Original line number Diff line number Diff line
@@ -2280,7 +2280,7 @@ sd_co_get_block_status(BlockDriverState *bs, int64_t sector_num, int nb_sectors,
                  end = DIV_ROUND_UP((sector_num + nb_sectors) *
                                     BDRV_SECTOR_SIZE, SD_DATA_OBJ_SIZE);
    unsigned long idx;
    int ret = 1;
    int64_t ret = BDRV_BLOCK_DATA;

    for (idx = start; idx < end; idx++) {
        if (inode->data_vdi_id[idx] == 0) {
Loading