aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>2022-03-03 20:43:43 +0100
committerHanna Reitz <hreitz@redhat.com>2022-03-07 09:33:31 +0100
commitce14f3b407aef73ed3c6034d2166bb89f4fbd8b5 (patch)
tree8db90e3852334781391471463224a80ab773afd7
parent3b7ca26bdf1eb1f9703048831d442adbb103069b (diff)
downloadqemu-ce14f3b407aef73ed3c6034d2166bb89f4fbd8b5.zip
qemu-ce14f3b407aef73ed3c6034d2166bb89f4fbd8b5.tar.gz
qemu-ce14f3b407aef73ed3c6034d2166bb89f4fbd8b5.tar.bz2
block/io: introduce block driver snapshot-access API
Add new block driver handlers and corresponding generic wrappers. It will be used to allow copy-before-write filter to provide reach fleecing interface in further commit. In future this approach may be used to allow reading qcow2 internal snapshots, for example to export them through NBD. Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com> Reviewed-by: Hanna Reitz <hreitz@redhat.com> Message-Id: <20220303194349.2304213-11-vsementsov@virtuozzo.com> [hreitz: Rebased on block GS/IO split] Signed-off-by: Hanna Reitz <hreitz@redhat.com>
-rw-r--r--block/io.c72
-rw-r--r--include/block/block_int-common.h18
-rw-r--r--include/block/block_int-io.h9
3 files changed, 99 insertions, 0 deletions
diff --git a/block/io.c b/block/io.c
index 8bee484..f0c8da6 100644
--- a/block/io.c
+++ b/block/io.c
@@ -3654,3 +3654,75 @@ void bdrv_cancel_in_flight(BlockDriverState *bs)
bs->drv->bdrv_cancel_in_flight(bs);
}
}
+
+int coroutine_fn
+bdrv_co_preadv_snapshot(BdrvChild *child, int64_t offset, int64_t bytes,
+ QEMUIOVector *qiov, size_t qiov_offset)
+{
+ BlockDriverState *bs = child->bs;
+ BlockDriver *drv = bs->drv;
+ int ret;
+ IO_CODE();
+
+ if (!drv) {
+ return -ENOMEDIUM;
+ }
+
+ if (!drv->bdrv_co_preadv_snapshot) {
+ return -ENOTSUP;
+ }
+
+ bdrv_inc_in_flight(bs);
+ ret = drv->bdrv_co_preadv_snapshot(bs, offset, bytes, qiov, qiov_offset);
+ bdrv_dec_in_flight(bs);
+
+ return ret;
+}
+
+int coroutine_fn
+bdrv_co_snapshot_block_status(BlockDriverState *bs,
+ bool want_zero, int64_t offset, int64_t bytes,
+ int64_t *pnum, int64_t *map,
+ BlockDriverState **file)
+{
+ BlockDriver *drv = bs->drv;
+ int ret;
+ IO_CODE();
+
+ if (!drv) {
+ return -ENOMEDIUM;
+ }
+
+ if (!drv->bdrv_co_snapshot_block_status) {
+ return -ENOTSUP;
+ }
+
+ bdrv_inc_in_flight(bs);
+ ret = drv->bdrv_co_snapshot_block_status(bs, want_zero, offset, bytes,
+ pnum, map, file);
+ bdrv_dec_in_flight(bs);
+
+ return ret;
+}
+
+int coroutine_fn
+bdrv_co_pdiscard_snapshot(BlockDriverState *bs, int64_t offset, int64_t bytes)
+{
+ BlockDriver *drv = bs->drv;
+ int ret;
+ IO_CODE();
+
+ if (!drv) {
+ return -ENOMEDIUM;
+ }
+
+ if (!drv->bdrv_co_pdiscard_snapshot) {
+ return -ENOTSUP;
+ }
+
+ bdrv_inc_in_flight(bs);
+ ret = drv->bdrv_co_pdiscard_snapshot(bs, offset, bytes);
+ bdrv_dec_in_flight(bs);
+
+ return ret;
+}
diff --git a/include/block/block_int-common.h b/include/block/block_int-common.h
index 5a04c77..4ba04d0 100644
--- a/include/block/block_int-common.h
+++ b/include/block/block_int-common.h
@@ -598,6 +598,24 @@ struct BlockDriver {
int64_t *map, BlockDriverState **file);
/*
+ * Snapshot-access API.
+ *
+ * Block-driver may provide snapshot-access API: special functions to access
+ * some internal "snapshot". The functions are similar with normal
+ * read/block_status/discard handler, but don't have any specific handling
+ * in generic block-layer: no serializing, no alignment, no tracked
+ * requests. So, block-driver that realizes these APIs is fully responsible
+ * for synchronization between snapshot-access API and normal IO requests.
+ */
+ int coroutine_fn (*bdrv_co_preadv_snapshot)(BlockDriverState *bs,
+ int64_t offset, int64_t bytes, QEMUIOVector *qiov, size_t qiov_offset);
+ int coroutine_fn (*bdrv_co_snapshot_block_status)(BlockDriverState *bs,
+ bool want_zero, int64_t offset, int64_t bytes, int64_t *pnum,
+ int64_t *map, BlockDriverState **file);
+ int coroutine_fn (*bdrv_co_pdiscard_snapshot)(BlockDriverState *bs,
+ int64_t offset, int64_t bytes);
+
+ /*
* Invalidate any cached meta-data.
*/
void coroutine_fn (*bdrv_co_invalidate_cache)(BlockDriverState *bs,
diff --git a/include/block/block_int-io.h b/include/block/block_int-io.h
index 3da5f01..bb45420 100644
--- a/include/block/block_int-io.h
+++ b/include/block/block_int-io.h
@@ -33,6 +33,15 @@
* the I/O API.
*/
+int coroutine_fn bdrv_co_preadv_snapshot(BdrvChild *child,
+ int64_t offset, int64_t bytes, QEMUIOVector *qiov, size_t qiov_offset);
+int coroutine_fn bdrv_co_snapshot_block_status(BlockDriverState *bs,
+ bool want_zero, int64_t offset, int64_t bytes, int64_t *pnum,
+ int64_t *map, BlockDriverState **file);
+int coroutine_fn bdrv_co_pdiscard_snapshot(BlockDriverState *bs,
+ int64_t offset, int64_t bytes);
+
+
int coroutine_fn bdrv_co_preadv(BdrvChild *child,
int64_t offset, int64_t bytes, QEMUIOVector *qiov,
BdrvRequestFlags flags);