Loading block/cow.c +7 −1 Original line number Diff line number Diff line Loading @@ -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, Loading block/qcow.c +8 −1 Original line number Diff line number Diff line Loading @@ -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, Loading block/qcow2.c +14 −2 Original line number Diff line number Diff line Loading @@ -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); Loading @@ -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 */ Loading block/qed.c +28 −7 Original line number Diff line number Diff line Loading @@ -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); } Loading @@ -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) Loading block/sheepdog.c +1 −1 Original line number Diff line number Diff line Loading @@ -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 Loading
block/cow.c +7 −1 Original line number Diff line number Diff line Loading @@ -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, Loading
block/qcow.c +8 −1 Original line number Diff line number Diff line Loading @@ -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, Loading
block/qcow2.c +14 −2 Original line number Diff line number Diff line Loading @@ -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); Loading @@ -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 */ Loading
block/qed.c +28 −7 Original line number Diff line number Diff line Loading @@ -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); } Loading @@ -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) Loading
block/sheepdog.c +1 −1 Original line number Diff line number Diff line Loading @@ -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