aboutsummaryrefslogtreecommitdiff
path: root/block/io.c
diff options
context:
space:
mode:
authorPeter Maydell <peter.maydell@linaro.org>2020-11-01 19:05:43 +0000
committerPeter Maydell <peter.maydell@linaro.org>2020-11-01 19:05:43 +0000
commit6f2ef80b0ce87d258b4736471a81747da2a7a881 (patch)
treec6c021403cff99fd92391546edbd62c415600f6a /block/io.c
parent700d20b49e303549b32d3a7a3efbfcee8c7a4f6c (diff)
parentdbc7b01492371e4a54b92d2b6d968f9b863cc794 (diff)
Merge remote-tracking branch 'remotes/ericb/tags/pull-nbd-2020-10-27-v2' into staging
nbd patches for 2020-10-27 - Tweak the new block-export-add QMP command - Allow multiple -B options for qemu-nbd - Add qemu:allocation-depth metadata context as qemu-nbd -A - Improve iotest use of NBD # gpg: Signature made Fri 30 Oct 2020 20:22:42 GMT # gpg: using RSA key 71C2CC22B1C4602927D2F3AAA7A16B4A2527436A # gpg: Good signature from "Eric Blake <eblake@redhat.com>" [full] # gpg: aka "Eric Blake (Free Software Programmer) <ebb9@byu.net>" [full] # gpg: aka "[jpeg image of size 6874]" [full] # Primary key fingerprint: 71C2 CC22 B1C4 6029 27D2 F3AA A7A1 6B4A 2527 436A * remotes/ericb/tags/pull-nbd-2020-10-27-v2: nbd: Add 'qemu-nbd -A' to expose allocation depth nbd: Add new qemu:allocation-depth metadata context block: Return depth level during bdrv_is_allocated_above nbd: Allow export of multiple bitmaps for one device nbd: Refactor counting of metadata contexts nbd: Simplify qemu bitmap context name nbd: Update qapi to support exporting multiple bitmaps nbd: Utilize QAPI_CLONE for type conversion qapi: Add QAPI_LIST_PREPEND() macro block: Simplify QAPI_LIST_ADD iotests/291: Stop NBD server iotests/291: Filter irrelevant parts of img-info Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Diffstat (limited to 'block/io.c')
-rw-r--r--block/io.c31
1 files changed, 23 insertions, 8 deletions
diff --git a/block/io.c b/block/io.c
index 9918f2499c..ec5e152bb7 100644
--- a/block/io.c
+++ b/block/io.c
@@ -2362,20 +2362,28 @@ bdrv_co_common_block_status_above(BlockDriverState *bs,
int64_t bytes,
int64_t *pnum,
int64_t *map,
- BlockDriverState **file)
+ BlockDriverState **file,
+ int *depth)
{
int ret;
BlockDriverState *p;
int64_t eof = 0;
+ int dummy;
assert(!include_base || base); /* Can't include NULL base */
+ if (!depth) {
+ depth = &dummy;
+ }
+ *depth = 0;
+
if (!include_base && bs == base) {
*pnum = bytes;
return 0;
}
ret = bdrv_co_block_status(bs, want_zero, offset, bytes, pnum, map, file);
+ ++*depth;
if (ret < 0 || *pnum == 0 || ret & BDRV_BLOCK_ALLOCATED || bs == base) {
return ret;
}
@@ -2392,6 +2400,7 @@ bdrv_co_common_block_status_above(BlockDriverState *bs,
{
ret = bdrv_co_block_status(p, want_zero, offset, bytes, pnum, map,
file);
+ ++*depth;
if (ret < 0) {
return ret;
}
@@ -2450,7 +2459,7 @@ int bdrv_block_status_above(BlockDriverState *bs, BlockDriverState *base,
int64_t *map, BlockDriverState **file)
{
return bdrv_common_block_status_above(bs, base, false, true, offset, bytes,
- pnum, map, file);
+ pnum, map, file, NULL);
}
int bdrv_block_status(BlockDriverState *bs, int64_t offset, int64_t bytes,
@@ -2478,7 +2487,7 @@ int coroutine_fn bdrv_co_is_zero_fast(BlockDriverState *bs, int64_t offset,
}
ret = bdrv_common_block_status_above(bs, NULL, false, false, offset,
- bytes, &pnum, NULL, NULL);
+ bytes, &pnum, NULL, NULL, NULL);
if (ret < 0) {
return ret;
@@ -2495,7 +2504,7 @@ int coroutine_fn bdrv_is_allocated(BlockDriverState *bs, int64_t offset,
ret = bdrv_common_block_status_above(bs, bs, true, false, offset,
bytes, pnum ? pnum : &dummy, NULL,
- NULL);
+ NULL, NULL);
if (ret < 0) {
return ret;
}
@@ -2505,8 +2514,9 @@ int coroutine_fn bdrv_is_allocated(BlockDriverState *bs, int64_t offset,
/*
* Given an image chain: ... -> [BASE] -> [INTER1] -> [INTER2] -> [TOP]
*
- * Return 1 if (a prefix of) the given range is allocated in any image
- * between BASE and TOP (BASE is only included if include_base is set).
+ * Return a positive depth if (a prefix of) the given range is allocated
+ * in any image between BASE and TOP (BASE is only included if include_base
+ * is set). Depth 1 is TOP, 2 is the first backing layer, and so forth.
* BASE can be NULL to check if the given offset is allocated in any
* image of the chain. Return 0 otherwise, or negative errno on
* failure.
@@ -2523,13 +2533,18 @@ int bdrv_is_allocated_above(BlockDriverState *top,
bool include_base, int64_t offset,
int64_t bytes, int64_t *pnum)
{
+ int depth;
int ret = bdrv_common_block_status_above(top, base, include_base, false,
- offset, bytes, pnum, NULL, NULL);
+ offset, bytes, pnum, NULL, NULL,
+ &depth);
if (ret < 0) {
return ret;
}
- return !!(ret & BDRV_BLOCK_ALLOCATED);
+ if (ret & BDRV_BLOCK_ALLOCATED) {
+ return depth;
+ }
+ return 0;
}
int coroutine_fn