snapshot-access.c 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135
  1. /*
  2. * snapshot_access block driver
  3. *
  4. * Copyright (c) 2022 Virtuozzo International GmbH.
  5. *
  6. * Author:
  7. * Sementsov-Ogievskiy Vladimir <vsementsov@virtuozzo.com>
  8. *
  9. * This program is free software; you can redistribute it and/or modify
  10. * it under the terms of the GNU General Public License as published by
  11. * the Free Software Foundation; either version 2 of the License, or
  12. * (at your option) any later version.
  13. *
  14. * This program is distributed in the hope that it will be useful,
  15. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  16. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  17. * GNU General Public License for more details.
  18. *
  19. * You should have received a copy of the GNU General Public License
  20. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  21. */
  22. #include "qemu/osdep.h"
  23. #include "system/block-backend.h"
  24. #include "qemu/cutils.h"
  25. #include "block/block_int.h"
  26. static int coroutine_fn GRAPH_RDLOCK
  27. snapshot_access_co_preadv_part(BlockDriverState *bs,
  28. int64_t offset, int64_t bytes,
  29. QEMUIOVector *qiov, size_t qiov_offset,
  30. BdrvRequestFlags flags)
  31. {
  32. if (flags) {
  33. return -ENOTSUP;
  34. }
  35. return bdrv_co_preadv_snapshot(bs->file, offset, bytes, qiov, qiov_offset);
  36. }
  37. static int coroutine_fn GRAPH_RDLOCK
  38. snapshot_access_co_block_status(BlockDriverState *bs,
  39. bool want_zero, int64_t offset,
  40. int64_t bytes, int64_t *pnum,
  41. int64_t *map, BlockDriverState **file)
  42. {
  43. return bdrv_co_snapshot_block_status(bs->file->bs, want_zero, offset,
  44. bytes, pnum, map, file);
  45. }
  46. static int coroutine_fn GRAPH_RDLOCK
  47. snapshot_access_co_pdiscard(BlockDriverState *bs, int64_t offset, int64_t bytes)
  48. {
  49. return bdrv_co_pdiscard_snapshot(bs->file->bs, offset, bytes);
  50. }
  51. static int coroutine_fn
  52. snapshot_access_co_pwrite_zeroes(BlockDriverState *bs,
  53. int64_t offset, int64_t bytes,
  54. BdrvRequestFlags flags)
  55. {
  56. return -ENOTSUP;
  57. }
  58. static coroutine_fn int
  59. snapshot_access_co_pwritev_part(BlockDriverState *bs,
  60. int64_t offset, int64_t bytes,
  61. QEMUIOVector *qiov, size_t qiov_offset,
  62. BdrvRequestFlags flags)
  63. {
  64. return -ENOTSUP;
  65. }
  66. static void GRAPH_RDLOCK snapshot_access_refresh_filename(BlockDriverState *bs)
  67. {
  68. pstrcpy(bs->exact_filename, sizeof(bs->exact_filename),
  69. bs->file->bs->filename);
  70. }
  71. static int snapshot_access_open(BlockDriverState *bs, QDict *options, int flags,
  72. Error **errp)
  73. {
  74. bdrv_open_child(NULL, options, "file", bs, &child_of_bds,
  75. BDRV_CHILD_DATA | BDRV_CHILD_PRIMARY,
  76. false, errp);
  77. GRAPH_RDLOCK_GUARD_MAINLOOP();
  78. if (!bs->file) {
  79. return -EINVAL;
  80. }
  81. bs->total_sectors = bs->file->bs->total_sectors;
  82. return 0;
  83. }
  84. static void snapshot_access_child_perm(BlockDriverState *bs, BdrvChild *c,
  85. BdrvChildRole role,
  86. BlockReopenQueue *reopen_queue,
  87. uint64_t perm, uint64_t shared,
  88. uint64_t *nperm, uint64_t *nshared)
  89. {
  90. /*
  91. * Currently, we don't need any permissions. If bs->file provides
  92. * snapshot-access API, we can use it.
  93. */
  94. *nperm = 0;
  95. *nshared = BLK_PERM_ALL;
  96. }
  97. static BlockDriver bdrv_snapshot_access_drv = {
  98. .format_name = "snapshot-access",
  99. .bdrv_open = snapshot_access_open,
  100. .bdrv_co_preadv_part = snapshot_access_co_preadv_part,
  101. .bdrv_co_pwritev_part = snapshot_access_co_pwritev_part,
  102. .bdrv_co_pwrite_zeroes = snapshot_access_co_pwrite_zeroes,
  103. .bdrv_co_pdiscard = snapshot_access_co_pdiscard,
  104. .bdrv_co_block_status = snapshot_access_co_block_status,
  105. .bdrv_refresh_filename = snapshot_access_refresh_filename,
  106. .bdrv_child_perm = snapshot_access_child_perm,
  107. };
  108. static void snapshot_access_init(void)
  109. {
  110. bdrv_register(&bdrv_snapshot_access_drv);
  111. }
  112. block_init(snapshot_access_init);