123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135 |
- /*
- * snapshot_access block driver
- *
- * Copyright (c) 2022 Virtuozzo International GmbH.
- *
- * Author:
- * Sementsov-Ogievskiy Vladimir <vsementsov@virtuozzo.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
- #include "qemu/osdep.h"
- #include "system/block-backend.h"
- #include "qemu/cutils.h"
- #include "block/block_int.h"
- static int coroutine_fn GRAPH_RDLOCK
- snapshot_access_co_preadv_part(BlockDriverState *bs,
- int64_t offset, int64_t bytes,
- QEMUIOVector *qiov, size_t qiov_offset,
- BdrvRequestFlags flags)
- {
- if (flags) {
- return -ENOTSUP;
- }
- return bdrv_co_preadv_snapshot(bs->file, offset, bytes, qiov, qiov_offset);
- }
- static int coroutine_fn GRAPH_RDLOCK
- snapshot_access_co_block_status(BlockDriverState *bs,
- bool want_zero, int64_t offset,
- int64_t bytes, int64_t *pnum,
- int64_t *map, BlockDriverState **file)
- {
- return bdrv_co_snapshot_block_status(bs->file->bs, want_zero, offset,
- bytes, pnum, map, file);
- }
- static int coroutine_fn GRAPH_RDLOCK
- snapshot_access_co_pdiscard(BlockDriverState *bs, int64_t offset, int64_t bytes)
- {
- return bdrv_co_pdiscard_snapshot(bs->file->bs, offset, bytes);
- }
- static int coroutine_fn
- snapshot_access_co_pwrite_zeroes(BlockDriverState *bs,
- int64_t offset, int64_t bytes,
- BdrvRequestFlags flags)
- {
- return -ENOTSUP;
- }
- static coroutine_fn int
- snapshot_access_co_pwritev_part(BlockDriverState *bs,
- int64_t offset, int64_t bytes,
- QEMUIOVector *qiov, size_t qiov_offset,
- BdrvRequestFlags flags)
- {
- return -ENOTSUP;
- }
- static void GRAPH_RDLOCK snapshot_access_refresh_filename(BlockDriverState *bs)
- {
- pstrcpy(bs->exact_filename, sizeof(bs->exact_filename),
- bs->file->bs->filename);
- }
- static int snapshot_access_open(BlockDriverState *bs, QDict *options, int flags,
- Error **errp)
- {
- bdrv_open_child(NULL, options, "file", bs, &child_of_bds,
- BDRV_CHILD_DATA | BDRV_CHILD_PRIMARY,
- false, errp);
- GRAPH_RDLOCK_GUARD_MAINLOOP();
- if (!bs->file) {
- return -EINVAL;
- }
- bs->total_sectors = bs->file->bs->total_sectors;
- return 0;
- }
- static void snapshot_access_child_perm(BlockDriverState *bs, BdrvChild *c,
- BdrvChildRole role,
- BlockReopenQueue *reopen_queue,
- uint64_t perm, uint64_t shared,
- uint64_t *nperm, uint64_t *nshared)
- {
- /*
- * Currently, we don't need any permissions. If bs->file provides
- * snapshot-access API, we can use it.
- */
- *nperm = 0;
- *nshared = BLK_PERM_ALL;
- }
- static BlockDriver bdrv_snapshot_access_drv = {
- .format_name = "snapshot-access",
- .bdrv_open = snapshot_access_open,
- .bdrv_co_preadv_part = snapshot_access_co_preadv_part,
- .bdrv_co_pwritev_part = snapshot_access_co_pwritev_part,
- .bdrv_co_pwrite_zeroes = snapshot_access_co_pwrite_zeroes,
- .bdrv_co_pdiscard = snapshot_access_co_pdiscard,
- .bdrv_co_block_status = snapshot_access_co_block_status,
- .bdrv_refresh_filename = snapshot_access_refresh_filename,
- .bdrv_child_perm = snapshot_access_child_perm,
- };
- static void snapshot_access_init(void)
- {
- bdrv_register(&bdrv_snapshot_access_drv);
- }
- block_init(snapshot_access_init);
|