Przeglądaj źródła

block: Mark bdrv_cow_child() and callers GRAPH_RDLOCK

This adds GRAPH_RDLOCK annotations to declare that callers of
bdrv_cow_child() need to hold a reader lock for the graph because it
accesses bs->backing.

Signed-off-by: Kevin Wolf <kwolf@redhat.com>
Message-ID: <20231027155333.420094-13-kwolf@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
Kevin Wolf 1 rok temu
rodzic
commit
78a9c76eef
3 zmienionych plików z 12 dodań i 6 usunięć
  1. 1 1
      block/stream.c
  2. 3 2
      include/block/block_int-io.h
  3. 8 3
      qemu-img.c

+ 1 - 1
block/stream.c

@@ -90,7 +90,7 @@ static int stream_prepare(Job *job)
     unfiltered_base = bdrv_skip_filters(base);
     unfiltered_base = bdrv_skip_filters(base);
     bdrv_graph_rdunlock_main_loop();
     bdrv_graph_rdunlock_main_loop();
 
 
-    if (bdrv_cow_child(unfiltered_bs)) {
+    if (unfiltered_bs_cow) {
         const char *base_id = NULL, *base_fmt = NULL;
         const char *base_id = NULL, *base_fmt = NULL;
         if (unfiltered_base) {
         if (unfiltered_base) {
             base_id = s->backing_file_str ?: unfiltered_base->filename;
             base_id = s->backing_file_str ?: unfiltered_base->filename;

+ 3 - 2
include/block/block_int-io.h

@@ -130,14 +130,15 @@ bdrv_co_refresh_total_sectors(BlockDriverState *bs, int64_t hint);
 int co_wrapper_mixed_bdrv_rdlock
 int co_wrapper_mixed_bdrv_rdlock
 bdrv_refresh_total_sectors(BlockDriverState *bs, int64_t hint);
 bdrv_refresh_total_sectors(BlockDriverState *bs, int64_t hint);
 
 
-BdrvChild *bdrv_cow_child(BlockDriverState *bs);
+BdrvChild * GRAPH_RDLOCK bdrv_cow_child(BlockDriverState *bs);
 BdrvChild * GRAPH_RDLOCK bdrv_filter_child(BlockDriverState *bs);
 BdrvChild * GRAPH_RDLOCK bdrv_filter_child(BlockDriverState *bs);
 BdrvChild * GRAPH_RDLOCK bdrv_filter_or_cow_child(BlockDriverState *bs);
 BdrvChild * GRAPH_RDLOCK bdrv_filter_or_cow_child(BlockDriverState *bs);
 BdrvChild * GRAPH_RDLOCK bdrv_primary_child(BlockDriverState *bs);
 BdrvChild * GRAPH_RDLOCK bdrv_primary_child(BlockDriverState *bs);
 BlockDriverState * GRAPH_RDLOCK bdrv_skip_filters(BlockDriverState *bs);
 BlockDriverState * GRAPH_RDLOCK bdrv_skip_filters(BlockDriverState *bs);
 BlockDriverState * GRAPH_RDLOCK bdrv_backing_chain_next(BlockDriverState *bs);
 BlockDriverState * GRAPH_RDLOCK bdrv_backing_chain_next(BlockDriverState *bs);
 
 
-static inline BlockDriverState *bdrv_cow_bs(BlockDriverState *bs)
+static inline BlockDriverState * GRAPH_RDLOCK
+bdrv_cow_bs(BlockDriverState *bs)
 {
 {
     IO_CODE();
     IO_CODE();
     return child_bs(bdrv_cow_child(bs));
     return child_bs(bdrv_cow_child(bs));

+ 8 - 3
qemu-img.c

@@ -3541,7 +3541,7 @@ static int img_rebase(int argc, char **argv)
     uint8_t *buf_old = NULL;
     uint8_t *buf_old = NULL;
     uint8_t *buf_new = NULL;
     uint8_t *buf_new = NULL;
     BlockDriverState *bs = NULL, *prefix_chain_bs = NULL;
     BlockDriverState *bs = NULL, *prefix_chain_bs = NULL;
-    BlockDriverState *unfiltered_bs;
+    BlockDriverState *unfiltered_bs, *unfiltered_bs_cow;
     BlockDriverInfo bdi = {0};
     BlockDriverInfo bdi = {0};
     char *filename;
     char *filename;
     const char *fmt, *cache, *src_cache, *out_basefmt, *out_baseimg;
     const char *fmt, *cache, *src_cache, *out_basefmt, *out_baseimg;
@@ -3675,6 +3675,7 @@ static int img_rebase(int argc, char **argv)
 
 
     bdrv_graph_rdlock_main_loop();
     bdrv_graph_rdlock_main_loop();
     unfiltered_bs = bdrv_skip_filters(bs);
     unfiltered_bs = bdrv_skip_filters(bs);
+    unfiltered_bs_cow = bdrv_cow_bs(unfiltered_bs);
     bdrv_graph_rdunlock_main_loop();
     bdrv_graph_rdunlock_main_loop();
 
 
     if (compress && !block_driver_can_compress(unfiltered_bs->drv)) {
     if (compress && !block_driver_can_compress(unfiltered_bs->drv)) {
@@ -3710,7 +3711,11 @@ static int img_rebase(int argc, char **argv)
     /* For safe rebasing we need to compare old and new backing file */
     /* For safe rebasing we need to compare old and new backing file */
     if (!unsafe) {
     if (!unsafe) {
         QDict *options = NULL;
         QDict *options = NULL;
-        BlockDriverState *base_bs = bdrv_cow_bs(unfiltered_bs);
+        BlockDriverState *base_bs;
+
+        bdrv_graph_rdlock_main_loop();
+        base_bs = bdrv_cow_bs(unfiltered_bs);
+        bdrv_graph_rdunlock_main_loop();
 
 
         if (base_bs) {
         if (base_bs) {
             blk_old_backing = blk_new(qemu_get_aio_context(),
             blk_old_backing = blk_new(qemu_get_aio_context(),
@@ -3876,7 +3881,7 @@ static int img_rebase(int argc, char **argv)
                  * If cluster wasn't changed since prefix_chain, we don't need
                  * If cluster wasn't changed since prefix_chain, we don't need
                  * to take action
                  * to take action
                  */
                  */
-                ret = bdrv_is_allocated_above(bdrv_cow_bs(unfiltered_bs),
+                ret = bdrv_is_allocated_above(unfiltered_bs_cow,
                                               prefix_chain_bs, false,
                                               prefix_chain_bs, false,
                                               offset, n, &n);
                                               offset, n, &n);
                 if (ret < 0) {
                 if (ret < 0) {