|
@@ -2255,36 +2255,6 @@ typedef struct BdrvCoBlockStatusData {
|
|
BlockDriverState **file;
|
|
BlockDriverState **file;
|
|
} BdrvCoBlockStatusData;
|
|
} BdrvCoBlockStatusData;
|
|
|
|
|
|
-int coroutine_fn bdrv_co_block_status_from_file(BlockDriverState *bs,
|
|
|
|
- bool want_zero,
|
|
|
|
- int64_t offset,
|
|
|
|
- int64_t bytes,
|
|
|
|
- int64_t *pnum,
|
|
|
|
- int64_t *map,
|
|
|
|
- BlockDriverState **file)
|
|
|
|
-{
|
|
|
|
- assert(bs->file && bs->file->bs);
|
|
|
|
- *pnum = bytes;
|
|
|
|
- *map = offset;
|
|
|
|
- *file = bs->file->bs;
|
|
|
|
- return BDRV_BLOCK_RAW | BDRV_BLOCK_OFFSET_VALID;
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-int coroutine_fn bdrv_co_block_status_from_backing(BlockDriverState *bs,
|
|
|
|
- bool want_zero,
|
|
|
|
- int64_t offset,
|
|
|
|
- int64_t bytes,
|
|
|
|
- int64_t *pnum,
|
|
|
|
- int64_t *map,
|
|
|
|
- BlockDriverState **file)
|
|
|
|
-{
|
|
|
|
- assert(bs->backing && bs->backing->bs);
|
|
|
|
- *pnum = bytes;
|
|
|
|
- *map = offset;
|
|
|
|
- *file = bs->backing->bs;
|
|
|
|
- return BDRV_BLOCK_RAW | BDRV_BLOCK_OFFSET_VALID;
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
/*
|
|
/*
|
|
* Returns the allocation status of the specified sectors.
|
|
* Returns the allocation status of the specified sectors.
|
|
* Drivers not implementing the functionality are assumed to not support
|
|
* Drivers not implementing the functionality are assumed to not support
|
|
@@ -2325,6 +2295,7 @@ static int coroutine_fn bdrv_co_block_status(BlockDriverState *bs,
|
|
BlockDriverState *local_file = NULL;
|
|
BlockDriverState *local_file = NULL;
|
|
int64_t aligned_offset, aligned_bytes;
|
|
int64_t aligned_offset, aligned_bytes;
|
|
uint32_t align;
|
|
uint32_t align;
|
|
|
|
+ bool has_filtered_child;
|
|
|
|
|
|
assert(pnum);
|
|
assert(pnum);
|
|
*pnum = 0;
|
|
*pnum = 0;
|
|
@@ -2350,7 +2321,8 @@ static int coroutine_fn bdrv_co_block_status(BlockDriverState *bs,
|
|
|
|
|
|
/* Must be non-NULL or bdrv_getlength() would have failed */
|
|
/* Must be non-NULL or bdrv_getlength() would have failed */
|
|
assert(bs->drv);
|
|
assert(bs->drv);
|
|
- if (!bs->drv->bdrv_co_block_status) {
|
|
|
|
|
|
+ has_filtered_child = bdrv_filter_child(bs);
|
|
|
|
+ if (!bs->drv->bdrv_co_block_status && !has_filtered_child) {
|
|
*pnum = bytes;
|
|
*pnum = bytes;
|
|
ret = BDRV_BLOCK_DATA | BDRV_BLOCK_ALLOCATED;
|
|
ret = BDRV_BLOCK_DATA | BDRV_BLOCK_ALLOCATED;
|
|
if (offset + bytes == total_size) {
|
|
if (offset + bytes == total_size) {
|
|
@@ -2371,9 +2343,20 @@ static int coroutine_fn bdrv_co_block_status(BlockDriverState *bs,
|
|
aligned_offset = QEMU_ALIGN_DOWN(offset, align);
|
|
aligned_offset = QEMU_ALIGN_DOWN(offset, align);
|
|
aligned_bytes = ROUND_UP(offset + bytes, align) - aligned_offset;
|
|
aligned_bytes = ROUND_UP(offset + bytes, align) - aligned_offset;
|
|
|
|
|
|
- ret = bs->drv->bdrv_co_block_status(bs, want_zero, aligned_offset,
|
|
|
|
- aligned_bytes, pnum, &local_map,
|
|
|
|
- &local_file);
|
|
|
|
|
|
+ if (bs->drv->bdrv_co_block_status) {
|
|
|
|
+ ret = bs->drv->bdrv_co_block_status(bs, want_zero, aligned_offset,
|
|
|
|
+ aligned_bytes, pnum, &local_map,
|
|
|
|
+ &local_file);
|
|
|
|
+ } else {
|
|
|
|
+ /* Default code for filters */
|
|
|
|
+
|
|
|
|
+ local_file = bdrv_filter_bs(bs);
|
|
|
|
+ assert(local_file);
|
|
|
|
+
|
|
|
|
+ *pnum = aligned_bytes;
|
|
|
|
+ local_map = aligned_offset;
|
|
|
|
+ ret = BDRV_BLOCK_RAW | BDRV_BLOCK_OFFSET_VALID;
|
|
|
|
+ }
|
|
if (ret < 0) {
|
|
if (ret < 0) {
|
|
*pnum = 0;
|
|
*pnum = 0;
|
|
goto out;
|
|
goto out;
|