From nobody Wed Nov 27 11:46:29 2024 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass(p=none dis=none) header.from=redhat.com ARC-Seal: i=1; a=rsa-sha256; t=1699382871; cv=none; d=zohomail.com; s=zohoarc; b=IOWaeeviEUxpWiMVnItvL0Dg1lMJDS2FoR/w8Ix4uYb/xVYcJur75G9JRaWmd8hPjm1tHjn+o/g9HbJn3LdNzEp4N3aqrSfHaD1ZU2SzggG6K08zXSBZ3nAqMELrPJYBNtl7PfbKeOE51RpVrA3NIzArF70ZbGU5Q4/C1WY9f9M= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1699382871; h=Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=7grqvMUm/2+tdpBgnAuIHfwKZ2t032uJUVPpIdY1xXM=; b=QWlffNhrlNjRD2AWWcxpXe9PCcDAg5iAVEyj0IshUzKSuO8+hz5mrFLahgz3WGHcW8T04vKhdMxkbKE16rJwDZ6wywEe50Unvfcx0qIMw3ImjZTG3tAq/Lh+92qT8rB9kWK0ap5M0xyPKNy4Rh1PCrEDJeuJlOuWho8yceyzbBI= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass header.from= (p=none dis=none) Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 169938287161449.646598390361305; Tue, 7 Nov 2023 10:47:51 -0800 (PST) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1r0R6B-0004Qi-TL; Tue, 07 Nov 2023 13:46:51 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1r0R5h-0003vR-MZ for qemu-devel@nongnu.org; Tue, 07 Nov 2023 13:46:23 -0500 Received: from us-smtp-delivery-124.mimecast.com ([170.10.133.124]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1r0R5d-0001Tz-Fc for qemu-devel@nongnu.org; Tue, 07 Nov 2023 13:46:19 -0500 Received: from mimecast-mx02.redhat.com (mimecast-mx02.redhat.com [66.187.233.88]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-46-Oh7t5RkRM9uS4cKuhPu6HQ-1; Tue, 07 Nov 2023 13:46:14 -0500 Received: from smtp.corp.redhat.com (int-mx08.intmail.prod.int.rdu2.redhat.com [10.11.54.8]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mimecast-mx02.redhat.com (Postfix) with ESMTPS id 1337C101A529 for ; Tue, 7 Nov 2023 18:46:14 +0000 (UTC) Received: from merkur.fritz.box (unknown [10.39.194.197]) by smtp.corp.redhat.com (Postfix) with ESMTP id 25174C15983; Tue, 7 Nov 2023 18:46:13 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1699382776; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=7grqvMUm/2+tdpBgnAuIHfwKZ2t032uJUVPpIdY1xXM=; b=g+NlDoBfihR5Xy+1Z9Fe3EwBKKFSzUm5+1cphYggarU/sAnBNik15R0NrYVJxS4lW7XFXE GnDRiAoU5vtSSMbkeK3yJTjN3UgEq6A1FNBx9Sl3hjGUxmmUGooMEDbFnwBZOtZDbZzmFZ +WfBgUSTg21T7i3WuTK1Uksc02OEnxk= X-MC-Unique: Oh7t5RkRM9uS4cKuhPu6HQ-1 From: Kevin Wolf To: qemu-devel@nongnu.org Cc: kwolf@redhat.com Subject: [PULL 08/25] block: Mark bdrv_skip_filters() and callers GRAPH_RDLOCK Date: Tue, 7 Nov 2023 19:45:48 +0100 Message-ID: <20231107184605.236540-9-kwolf@redhat.com> In-Reply-To: <20231107184605.236540-1-kwolf@redhat.com> References: <20231107184605.236540-1-kwolf@redhat.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Scanned-By: MIMEDefang 3.4.1 on 10.11.54.8 Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=170.10.133.124; envelope-from=kwolf@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.001, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, RCVD_IN_MSPIKE_H3=0.001, RCVD_IN_MSPIKE_WL=0.001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001, T_SCC_BODY_TEXT_LINE=-0.01 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity @redhat.com) X-ZM-MESSAGEID: 1699382873206100002 Content-Type: text/plain; charset="utf-8" This adds GRAPH_RDLOCK annotations to declare that callers of bdrv_skip_filters() need to hold a reader lock for the graph because it calls bdrv_filter_child(), which accesses bs->file/backing. Signed-off-by: Kevin Wolf Message-ID: <20231027155333.420094-9-kwolf@redhat.com> Reviewed-by: Eric Blake Signed-off-by: Kevin Wolf --- include/block/block-global-state.h | 8 ++++--- include/block/block_int-io.h | 4 ++-- block/block-backend.c | 1 + block/block-copy.c | 9 +++++++- block/commit.c | 5 ++++- block/mirror.c | 34 +++++++++++++++++++++--------- block/stream.c | 22 ++++++++++++------- blockdev.c | 7 +++--- qemu-img.c | 18 +++++++++++++--- 9 files changed, 77 insertions(+), 31 deletions(-) diff --git a/include/block/block-global-state.h b/include/block/block-globa= l-state.h index 3ae468ea15..b6860ae43b 100644 --- a/include/block/block-global-state.h +++ b/include/block/block-global-state.h @@ -144,9 +144,11 @@ int bdrv_change_backing_file(BlockDriverState *bs, con= st char *backing_file, void bdrv_register(BlockDriver *bdrv); int bdrv_drop_intermediate(BlockDriverState *top, BlockDriverState *base, const char *backing_file_str); -BlockDriverState *bdrv_find_overlay(BlockDriverState *active, - BlockDriverState *bs); -BlockDriverState *bdrv_find_base(BlockDriverState *bs); + +BlockDriverState * GRAPH_RDLOCK +bdrv_find_overlay(BlockDriverState *active, BlockDriverState *bs); + +BlockDriverState * GRAPH_RDLOCK bdrv_find_base(BlockDriverState *bs); bool bdrv_is_backing_chain_frozen(BlockDriverState *bs, BlockDriverState *= base, Error **errp); int bdrv_freeze_backing_chain(BlockDriverState *bs, BlockDriverState *base, diff --git a/include/block/block_int-io.h b/include/block/block_int-io.h index 6800af7590..4e7bf57a5e 100644 --- a/include/block/block_int-io.h +++ b/include/block/block_int-io.h @@ -134,8 +134,8 @@ BdrvChild *bdrv_cow_child(BlockDriverState *bs); BdrvChild *bdrv_filter_child(BlockDriverState *bs); BdrvChild *bdrv_filter_or_cow_child(BlockDriverState *bs); BdrvChild * GRAPH_RDLOCK bdrv_primary_child(BlockDriverState *bs); -BlockDriverState *bdrv_skip_filters(BlockDriverState *bs); -BlockDriverState *bdrv_backing_chain_next(BlockDriverState *bs); +BlockDriverState * GRAPH_RDLOCK bdrv_skip_filters(BlockDriverState *bs); +BlockDriverState * GRAPH_RDLOCK bdrv_backing_chain_next(BlockDriverState *= bs); =20 static inline BlockDriverState *bdrv_cow_bs(BlockDriverState *bs) { diff --git a/block/block-backend.c b/block/block-backend.c index 075a0dfa95..4053134781 100644 --- a/block/block-backend.c +++ b/block/block-backend.c @@ -2730,6 +2730,7 @@ int blk_commit_all(void) { BlockBackend *blk =3D NULL; GLOBAL_STATE_CODE(); + GRAPH_RDLOCK_GUARD_MAINLOOP(); =20 while ((blk =3D blk_all_next(blk)) !=3D NULL) { AioContext *aio_context =3D blk_get_aio_context(blk); diff --git a/block/block-copy.c b/block/block-copy.c index 1c60368d72..6b2be3d204 100644 --- a/block/block-copy.c +++ b/block/block-copy.c @@ -313,7 +313,12 @@ static int64_t block_copy_calculate_cluster_size(Block= DriverState *target, { int ret; BlockDriverInfo bdi; - bool target_does_cow =3D bdrv_backing_chain_next(target); + bool target_does_cow; + + GLOBAL_STATE_CODE(); + GRAPH_RDLOCK_GUARD_MAINLOOP(); + + target_does_cow =3D bdrv_backing_chain_next(target); =20 /* * If there is no backing file on the target, we cannot rely on COW if= our @@ -355,6 +360,8 @@ BlockCopyState *block_copy_state_new(BdrvChild *source,= BdrvChild *target, BdrvDirtyBitmap *copy_bitmap; bool is_fleecing; =20 + GLOBAL_STATE_CODE(); + cluster_size =3D block_copy_calculate_cluster_size(target->bs, errp); if (cluster_size < 0) { return NULL; diff --git a/block/commit.c b/block/commit.c index fc3ad79749..05eb57d9ea 100644 --- a/block/commit.c +++ b/block/commit.c @@ -255,10 +255,13 @@ void commit_start(const char *job_id, BlockDriverStat= e *bs, GLOBAL_STATE_CODE(); =20 assert(top !=3D bs); + bdrv_graph_rdlock_main_loop(); if (bdrv_skip_filters(top) =3D=3D bdrv_skip_filters(base)) { error_setg(errp, "Invalid files for merge: top and base are the sa= me"); + bdrv_graph_rdunlock_main_loop(); return; } + bdrv_graph_rdunlock_main_loop(); =20 base_size =3D bdrv_getlength(base); if (base_size < 0) { @@ -324,6 +327,7 @@ void commit_start(const char *job_id, BlockDriverState = *bs, * this is the responsibility of the interface (i.e. whoever calls * commit_start()). */ + bdrv_graph_wrlock(top); s->base_overlay =3D bdrv_find_overlay(top, base); assert(s->base_overlay); =20 @@ -342,7 +346,6 @@ void commit_start(const char *job_id, BlockDriverState = *bs, */ iter_shared_perms =3D BLK_PERM_WRITE_UNCHANGED | BLK_PERM_WRITE; =20 - bdrv_graph_wrlock(top); for (iter =3D top; iter !=3D base; iter =3D bdrv_filter_or_cow_bs(iter= )) { if (iter =3D=3D filtered_base) { /* diff --git a/block/mirror.c b/block/mirror.c index a03247a31b..75e826dac8 100644 --- a/block/mirror.c +++ b/block/mirror.c @@ -714,7 +714,6 @@ static int mirror_exit_common(Job *job) bdrv_graph_rdlock_main_loop(); bdrv_child_refresh_perms(mirror_top_bs, mirror_top_bs->backing, &error_abort); - bdrv_graph_rdunlock_main_loop(); =20 if (!abort && s->backing_mode =3D=3D MIRROR_SOURCE_BACKING_CHAIN) { BlockDriverState *backing =3D s->is_none_mode ? src : s->base; @@ -737,6 +736,7 @@ static int mirror_exit_common(Job *job) local_err =3D NULL; } } + bdrv_graph_rdunlock_main_loop(); =20 if (s->to_replace) { replace_aio_context =3D bdrv_get_aio_context(s->to_replace); @@ -992,13 +992,13 @@ static int coroutine_fn mirror_run(Job *job, Error **= errp) } else { s->target_cluster_size =3D BDRV_SECTOR_SIZE; } - bdrv_graph_co_rdunlock(); if (backing_filename[0] && !bdrv_backing_chain_next(target_bs) && s->granularity < s->target_cluster_size) { s->buf_size =3D MAX(s->buf_size, s->target_cluster_size); s->cow_bitmap =3D bitmap_new(length); } s->max_iov =3D MIN(bs->bl.max_iov, target_bs->bl.max_iov); + bdrv_graph_co_rdunlock(); =20 s->buf =3D qemu_try_blockalign(bs, s->buf_size); if (s->buf =3D=3D NULL) { @@ -1744,12 +1744,15 @@ static BlockJob *mirror_start_job( buf_size =3D DEFAULT_MIRROR_BUF_SIZE; } =20 + bdrv_graph_rdlock_main_loop(); if (bdrv_skip_filters(bs) =3D=3D bdrv_skip_filters(target)) { error_setg(errp, "Can't mirror node into itself"); + bdrv_graph_rdunlock_main_loop(); return NULL; } =20 target_is_backing =3D bdrv_chain_contains(bs, target); + bdrv_graph_rdunlock_main_loop(); =20 /* In the case of active commit, add dummy driver to provide consistent * reads on the top, while disabling it in the intermediate nodes, and= make @@ -1832,14 +1835,19 @@ static BlockJob *mirror_start_job( } =20 target_shared_perms |=3D BLK_PERM_CONSISTENT_READ | BLK_PERM_WRITE; - } else if (bdrv_chain_contains(bs, bdrv_skip_filters(target))) { - /* - * We may want to allow this in the future, but it would - * require taking some extra care. - */ - error_setg(errp, "Cannot mirror to a filter on top of a node in th= e " - "source's backing chain"); - goto fail; + } else { + bdrv_graph_rdlock_main_loop(); + if (bdrv_chain_contains(bs, bdrv_skip_filters(target))) { + /* + * We may want to allow this in the future, but it would + * require taking some extra care. + */ + error_setg(errp, "Cannot mirror to a filter on top of a node i= n " + "the source's backing chain"); + bdrv_graph_rdunlock_main_loop(); + goto fail; + } + bdrv_graph_rdunlock_main_loop(); } =20 s->target =3D blk_new(s->common.job.aio_context, @@ -1860,6 +1868,7 @@ static BlockJob *mirror_start_job( blk_set_allow_aio_context_change(s->target, true); blk_set_disable_request_queuing(s->target, true); =20 + bdrv_graph_rdlock_main_loop(); s->replaces =3D g_strdup(replaces); s->on_source_error =3D on_source_error; s->on_target_error =3D on_target_error; @@ -1875,6 +1884,7 @@ static BlockJob *mirror_start_job( if (auto_complete) { s->should_complete =3D true; } + bdrv_graph_rdunlock_main_loop(); =20 s->dirty_bitmap =3D bdrv_create_dirty_bitmap(s->mirror_top_bs, granula= rity, NULL, errp); @@ -2007,8 +2017,12 @@ void mirror_start(const char *job_id, BlockDriverSta= te *bs, MirrorSyncMode_str(mode)); return; } + + bdrv_graph_rdlock_main_loop(); is_none_mode =3D mode =3D=3D MIRROR_SYNC_MODE_NONE; base =3D mode =3D=3D MIRROR_SYNC_MODE_TOP ? bdrv_backing_chain_next(bs= ) : NULL; + bdrv_graph_rdunlock_main_loop(); + mirror_start_job(job_id, bs, creation_flags, target, replaces, speed, granularity, buf_size, backing_mode, zero_targ= et, on_source_error, on_target_error, unmap, NULL, NULL, diff --git a/block/stream.c b/block/stream.c index 2781441191..5323a9976d 100644 --- a/block/stream.c +++ b/block/stream.c @@ -53,8 +53,8 @@ static int coroutine_fn stream_populate(BlockBackend *blk, static int stream_prepare(Job *job) { StreamBlockJob *s =3D container_of(job, StreamBlockJob, common.job); - BlockDriverState *unfiltered_bs =3D bdrv_skip_filters(s->target_bs); - BlockDriverState *unfiltered_bs_cow =3D bdrv_cow_bs(unfiltered_bs); + BlockDriverState *unfiltered_bs; + BlockDriverState *unfiltered_bs_cow; BlockDriverState *base; BlockDriverState *unfiltered_base; Error *local_err =3D NULL; @@ -62,6 +62,11 @@ static int stream_prepare(Job *job) =20 GLOBAL_STATE_CODE(); =20 + bdrv_graph_rdlock_main_loop(); + unfiltered_bs =3D bdrv_skip_filters(s->target_bs); + unfiltered_bs_cow =3D bdrv_cow_bs(unfiltered_bs); + bdrv_graph_rdunlock_main_loop(); + /* We should drop filter at this point, as filter hold the backing cha= in */ bdrv_cor_filter_drop(s->cor_filter_bs); s->cor_filter_bs =3D NULL; @@ -142,18 +147,19 @@ static void stream_clean(Job *job) static int coroutine_fn stream_run(Job *job, Error **errp) { StreamBlockJob *s =3D container_of(job, StreamBlockJob, common.job); - BlockDriverState *unfiltered_bs =3D bdrv_skip_filters(s->target_bs); + BlockDriverState *unfiltered_bs; int64_t len; int64_t offset =3D 0; int error =3D 0; int64_t n =3D 0; /* bytes */ =20 - if (unfiltered_bs =3D=3D s->base_overlay) { - /* Nothing to stream */ - return 0; - } - WITH_GRAPH_RDLOCK_GUARD() { + unfiltered_bs =3D bdrv_skip_filters(s->target_bs); + if (unfiltered_bs =3D=3D s->base_overlay) { + /* Nothing to stream */ + return 0; + } + len =3D bdrv_co_getlength(s->target_bs); if (len < 0) { return len; diff --git a/blockdev.c b/blockdev.c index 6cdf48beb1..5f15ea3b1d 100644 --- a/blockdev.c +++ b/blockdev.c @@ -1710,7 +1710,6 @@ static void drive_backup_action(DriveBackup *backup, bdrv_graph_rdunlock_main_loop(); goto out; } - bdrv_graph_rdunlock_main_loop(); =20 flags =3D bs->open_flags | BDRV_O_RDWR; =20 @@ -1735,6 +1734,7 @@ static void drive_backup_action(DriveBackup *backup, flags |=3D BDRV_O_NO_BACKING; set_backing_hd =3D true; } + bdrv_graph_rdunlock_main_loop(); =20 size =3D bdrv_getlength(bs); if (size < 0) { @@ -3054,7 +3054,6 @@ void qmp_drive_mirror(DriveMirror *arg, Error **errp) bdrv_graph_rdunlock_main_loop(); return; } - bdrv_graph_rdunlock_main_loop(); =20 aio_context =3D bdrv_get_aio_context(bs); aio_context_acquire(aio_context); @@ -3076,6 +3075,7 @@ void qmp_drive_mirror(DriveMirror *arg, Error **errp) if (arg->sync =3D=3D MIRROR_SYNC_MODE_NONE) { target_backing_bs =3D bs; } + bdrv_graph_rdunlock_main_loop(); =20 size =3D bdrv_getlength(bs); if (size < 0) { @@ -3450,15 +3450,16 @@ void qmp_change_backing_file(const char *device, goto out; } =20 + bdrv_graph_rdlock_main_loop(); if (bdrv_find_base(image_bs) =3D=3D image_bs) { error_setg(errp, "not allowing backing file change on an image " "without a backing file"); + bdrv_graph_rdunlock_main_loop(); goto out; } =20 /* even though we are not necessarily operating on bs, we need it to * determine if block ops are currently prohibited on the chain */ - bdrv_graph_rdlock_main_loop(); if (bdrv_op_is_blocked(bs, BLOCK_OP_TYPE_CHANGE, errp)) { bdrv_graph_rdunlock_main_loop(); goto out; diff --git a/qemu-img.c b/qemu-img.c index c061fd0634..33f3ab5fba 100644 --- a/qemu-img.c +++ b/qemu-img.c @@ -1050,12 +1050,14 @@ static int img_commit(int argc, char **argv) qemu_progress_init(progress, 1.f); qemu_progress_print(0.f, 100); =20 + bdrv_graph_rdlock_main_loop(); if (base) { base_bs =3D bdrv_find_backing_image(bs, base); if (!base_bs) { error_setg(&local_err, "Did not find '%s' in the backing chain of '%s'", base, filename); + bdrv_graph_rdunlock_main_loop(); goto done; } } else { @@ -1065,9 +1067,11 @@ static int img_commit(int argc, char **argv) base_bs =3D bdrv_backing_chain_next(bs); if (!base_bs) { error_setg(&local_err, "Image does not have a backing file"); + bdrv_graph_rdunlock_main_loop(); goto done; } } + bdrv_graph_rdunlock_main_loop(); =20 cbi =3D (CommonBlockJobCBInfo){ .errp =3D &local_err, @@ -1713,7 +1717,8 @@ static void convert_select_part(ImgConvertState *s, i= nt64_t sector_num, } } =20 -static int convert_iteration_sectors(ImgConvertState *s, int64_t sector_nu= m) +static int coroutine_mixed_fn GRAPH_RDLOCK +convert_iteration_sectors(ImgConvertState *s, int64_t sector_num) { int64_t src_cur_offset; int ret, n, src_cur; @@ -2115,7 +2120,9 @@ static int convert_do_copy(ImgConvertState *s) } =20 while (sector_num < s->total_sectors) { + bdrv_graph_rdlock_main_loop(); n =3D convert_iteration_sectors(s, sector_num); + bdrv_graph_rdunlock_main_loop(); if (n < 0) { return n; } @@ -2757,8 +2764,10 @@ static int img_convert(int argc, char **argv) * s.target_backing_sectors has to be negative, which it will * be automatically). The backing file length is used only * for optimizations, so such a case is not fatal. */ + bdrv_graph_rdlock_main_loop(); s.target_backing_sectors =3D bdrv_nb_sectors(bdrv_backing_chain_next(out_bs)); + bdrv_graph_rdunlock_main_loop(); } else { s.target_backing_sectors =3D -1; } @@ -3145,6 +3154,9 @@ static int get_block_status(BlockDriverState *bs, int= 64_t offset, int64_t map; char *filename =3D NULL; =20 + GLOBAL_STATE_CODE(); + GRAPH_RDLOCK_GUARD_MAINLOOP(); + /* As an optimization, we could cache the current range of unallocated * clusters in each file of the chain, and avoid querying the same * range repeatedly. @@ -3173,9 +3185,7 @@ static int get_block_status(BlockDriverState *bs, int= 64_t offset, has_offset =3D !!(ret & BDRV_BLOCK_OFFSET_VALID); =20 if (file && has_offset) { - bdrv_graph_rdlock_main_loop(); bdrv_refresh_filename(file); - bdrv_graph_rdunlock_main_loop(); filename =3D file->filename; } =20 @@ -3663,7 +3673,9 @@ static int img_rebase(int argc, char **argv) } bs =3D blk_bs(blk); =20 + bdrv_graph_rdlock_main_loop(); unfiltered_bs =3D bdrv_skip_filters(bs); + bdrv_graph_rdunlock_main_loop(); =20 if (compress && !block_driver_can_compress(unfiltered_bs->drv)) { error_report("Compression not supported for this file format"); --=20 2.41.0