1 | The following changes since commit 79b677d658d3d35e1e776826ac4abb28cdce69b8: | 1 | The following changes since commit 86f4c7e05b1c44dbe1b329a51f311f10aef6ff34: |
---|---|---|---|
2 | 2 | ||
3 | Merge tag 'net-pull-request' of https://github.com/jasowang/qemu into staging (2023-02-21 11:28:31 +0000) | 3 | Merge remote-tracking branch 'remotes/pmaydell/tags/pull-target-arm-20180302' into staging (2018-03-02 14:37:10 +0000) |
4 | 4 | ||
5 | are available in the Git repository at: | 5 | are available in the git repository at: |
6 | 6 | ||
7 | https://repo.or.cz/qemu/kevin.git tags/for-upstream | 7 | git://repo.or.cz/qemu/kevin.git tags/for-upstream |
8 | 8 | ||
9 | for you to fetch changes up to 0f385a2420d2c3f8ae7ed65fbe2712027664059e: | 9 | for you to fetch changes up to bfe1a14c180ec44c033be12b9151252ffda69292: |
10 | 10 | ||
11 | block/rbd: Add support for layered encryption (2023-02-23 19:49:35 +0100) | 11 | block: Fix NULL dereference on empty drive error (2018-03-05 18:45:32 +0100) |
12 | 12 | ||
13 | ---------------------------------------------------------------- | 13 | ---------------------------------------------------------------- |
14 | Block layer patches | 14 | Block layer patches |
15 | 15 | ||
16 | - Lock the graph, part 2 (BlockDriver callbacks) | 16 | ---------------------------------------------------------------- |
17 | - virtio-scsi: fix SCSIDevice hot unplug with IOThread | 17 | Alberto Garcia (3): |
18 | - rbd: Add support for layered encryption | 18 | specs/qcow2: Fix documentation of the compressed cluster descriptor |
19 | docs: document how to use the l2-cache-entry-size parameter | ||
20 | qcow2: Replace align_offset() with ROUND_UP() | ||
19 | 21 | ||
20 | ---------------------------------------------------------------- | 22 | Anton Nefedov (2): |
21 | Emanuele Giuseppe Esposito (5): | 23 | block: fix write with zero flag set and iovector provided |
22 | block/qed: add missing graph rdlock in qed_need_check_timer_entry | 24 | iotest 033: add misaligned write-zeroes test via truncate |
23 | block: Mark bdrv_co_flush() and callers GRAPH_RDLOCK | ||
24 | block: Mark bdrv_co_pdiscard() and callers GRAPH_RDLOCK | ||
25 | block: Mark bdrv_co_copy_range() GRAPH_RDLOCK | ||
26 | block: Mark bdrv_co_is_inserted() and callers GRAPH_RDLOCK | ||
27 | 25 | ||
28 | Kevin Wolf (18): | 26 | Eric Blake (21): |
29 | block: Make bdrv_can_set_read_only() static | 27 | block: Add .bdrv_co_block_status() callback |
30 | mirror: Fix access of uninitialised fields during start | 28 | nvme: Drop pointless .bdrv_co_get_block_status() |
31 | block: Mark bdrv_co_truncate() and callers GRAPH_RDLOCK | 29 | block: Switch passthrough drivers to .bdrv_co_block_status() |
32 | block: Mark bdrv_co_block_status() and callers GRAPH_RDLOCK | 30 | file-posix: Switch to .bdrv_co_block_status() |
33 | block: Mark bdrv_co_ioctl() and callers GRAPH_RDLOCK | 31 | gluster: Switch to .bdrv_co_block_status() |
34 | block: Mark bdrv_co_pwrite_zeroes() and callers GRAPH_RDLOCK | 32 | iscsi: Switch cluster_sectors to byte-based |
35 | block: Mark read/write in block/io.c GRAPH_RDLOCK | 33 | iscsi: Switch iscsi_allocmap_update() to byte-based |
36 | block: Mark public read/write functions GRAPH_RDLOCK | 34 | iscsi: Switch to .bdrv_co_block_status() |
37 | block: Mark bdrv_co_pwrite_sync() and callers GRAPH_RDLOCK | 35 | null: Switch to .bdrv_co_block_status() |
38 | block: Mark bdrv_co_do_pwrite_zeroes() GRAPH_RDLOCK | 36 | parallels: Switch to .bdrv_co_block_status() |
39 | block: Mark preadv_snapshot/snapshot_block_status GRAPH_RDLOCK | 37 | qcow: Switch to .bdrv_co_block_status() |
40 | block: Mark bdrv_co_create() and callers GRAPH_RDLOCK | 38 | qcow2: Switch to .bdrv_co_block_status() |
41 | block: Mark bdrv_co_io_(un)plug() and callers GRAPH_RDLOCK | 39 | qed: Switch to .bdrv_co_block_status() |
42 | block: Mark bdrv_co_eject/lock_medium() and callers GRAPH_RDLOCK | 40 | raw: Switch to .bdrv_co_block_status() |
43 | block: Mark bdrv_(un)register_buf() GRAPH_RDLOCK | 41 | sheepdog: Switch to .bdrv_co_block_status() |
44 | block: Mark bdrv_co_delete_file() and callers GRAPH_RDLOCK | 42 | vdi: Avoid bitrot of debugging code |
45 | block: Mark bdrv_*_dirty_bitmap() and callers GRAPH_RDLOCK | 43 | vdi: Switch to .bdrv_co_block_status() |
46 | block: Mark bdrv_co_refresh_total_sectors() and callers GRAPH_RDLOCK | 44 | vmdk: Switch to .bdrv_co_block_status() |
45 | vpc: Switch to .bdrv_co_block_status() | ||
46 | vvfat: Switch to .bdrv_co_block_status() | ||
47 | block: Drop unused .bdrv_co_get_block_status() | ||
47 | 48 | ||
48 | Or Ozeri (3): | 49 | Kevin Wolf (3): |
49 | block/rbd: Remove redundant stack variable passphrase_len | 50 | block: test blk_aio_flush() with blk->root == NULL |
50 | block/rbd: Add luks-any encryption opening option | 51 | Merge remote-tracking branch 'mreitz/tags/pull-block-2018-03-02' into queue-block |
51 | block/rbd: Add support for layered encryption | 52 | block: Fix NULL dereference on empty drive error |
52 | 53 | ||
53 | Stefan Hajnoczi (3): | 54 | Max Reitz (4): |
54 | scsi: protect req->aiocb with AioContext lock | 55 | qemu-img: Make resize error message more general |
55 | dma-helpers: prevent dma_blk_cb() vs dma_aio_cancel() race | 56 | block/ssh: Pull ssh_grow_file() from ssh_create() |
56 | virtio-scsi: reset SCSI devices from main loop thread | 57 | block/ssh: Make ssh_grow_file() blocking |
58 | block/ssh: Add basic .bdrv_truncate() | ||
57 | 59 | ||
58 | qapi/block-core.json | 27 +++++- | 60 | Stefan Hajnoczi (6): |
59 | block/coroutines.h | 2 +- | 61 | aio: rename aio_context_in_iothread() to in_aio_context_home_thread() |
60 | block/qcow2.h | 27 ++++-- | 62 | block: extract AIO_WAIT_WHILE() from BlockDriverState |
61 | block/qed.h | 45 +++++---- | 63 | block: add BlockBackend->in_flight counter |
62 | include/block/block-copy.h | 6 +- | 64 | Revert "IDE: Do not flush empty CDROM drives" |
63 | include/block/block-global-state.h | 14 +-- | 65 | block: rename .bdrv_create() to .bdrv_co_create_opts() |
64 | include/block/block-io.h | 110 ++++++++++++---------- | 66 | qcow2: make qcow2_co_create2() a coroutine_fn |
65 | include/block/block_int-common.h | 173 ++++++++++++++++++---------------- | 67 | |
66 | include/block/block_int-io.h | 53 ++++++----- | 68 | qapi/block-core.json | 6 +- |
67 | include/block/dirty-bitmap.h | 12 +-- | 69 | docs/interop/qcow2.txt | 16 ++++- |
68 | include/hw/virtio/virtio-scsi.h | 11 ++- | 70 | docs/qcow2-cache.txt | 46 ++++++++++++- |
69 | include/sysemu/block-backend-io.h | 7 +- | 71 | block/qcow2.h | 6 -- |
70 | block.c | 12 ++- | 72 | include/block/aio-wait.h | 116 ++++++++++++++++++++++++++++++++ |
71 | block/backup.c | 3 + | 73 | include/block/aio.h | 7 +- |
72 | block/blkdebug.c | 19 ++-- | 74 | include/block/block.h | 54 ++++----------- |
73 | block/blklogwrites.c | 35 ++++--- | 75 | include/block/block_int.h | 61 ++++++++++------- |
74 | block/blkreplay.c | 24 +++-- | 76 | block.c | 11 ++- |
75 | block/blkverify.c | 5 +- | 77 | block/blkdebug.c | 20 +++--- |
76 | block/block-backend.c | 39 +++++--- | 78 | block/block-backend.c | 65 +++++++++++++++--- |
77 | block/block-copy.c | 32 ++++--- | 79 | block/commit.c | 2 +- |
78 | block/bochs.c | 2 +- | 80 | block/crypto.c | 8 +-- |
79 | block/commit.c | 5 +- | 81 | block/file-posix.c | 79 +++++++++++----------- |
80 | block/copy-before-write.c | 33 ++++--- | 82 | block/file-win32.c | 5 +- |
81 | block/copy-on-read.c | 44 +++++---- | 83 | block/gluster.c | 83 ++++++++++++----------- |
82 | block/create.c | 9 +- | 84 | block/io.c | 98 +++++++++++---------------- |
83 | block/crypto.c | 16 ++-- | 85 | block/iscsi.c | 164 ++++++++++++++++++++++++--------------------- |
84 | block/dirty-bitmap.c | 2 + | 86 | block/mirror.c | 2 +- |
85 | block/file-posix.c | 27 +++--- | 87 | block/nfs.c | 5 +- |
86 | block/file-win32.c | 7 +- | 88 | block/null.c | 23 ++++--- |
87 | block/filter-compress.c | 36 ++++--- | 89 | block/nvme.c | 14 ---- |
88 | block/io.c | 108 +++++++++++++-------- | 90 | block/parallels.c | 28 +++++--- |
89 | block/iscsi.c | 28 +++--- | 91 | block/qcow.c | 32 +++++---- |
90 | block/mirror.c | 59 ++++++++---- | 92 | block/qcow2-bitmap.c | 4 +- |
91 | block/parallels.c | 33 +++---- | 93 | block/qcow2-cluster.c | 4 +- |
92 | block/preallocate.c | 38 ++++---- | 94 | block/qcow2-refcount.c | 4 +- |
93 | block/qcow.c | 46 +++++---- | 95 | block/qcow2-snapshot.c | 10 +-- |
94 | block/qcow2-cluster.c | 17 ++-- | 96 | block/qcow2.c | 60 +++++++++-------- |
95 | block/qcow2.c | 136 +++++++++++++++------------ | 97 | block/qed.c | 82 ++++++++--------------- |
96 | block/qed-check.c | 3 +- | 98 | block/raw-format.c | 21 +++--- |
97 | block/qed-table.c | 10 +- | 99 | block/rbd.c | 6 +- |
98 | block/qed.c | 101 ++++++++++---------- | 100 | block/sheepdog.c | 36 +++++----- |
99 | block/quorum.c | 62 +++++++----- | 101 | block/ssh.c | 66 +++++++++++++++--- |
100 | block/raw-format.c | 76 ++++++++------- | 102 | block/throttle.c | 2 +- |
101 | block/rbd.c | 188 ++++++++++++++++++++++++++++++++++--- | 103 | block/vdi.c | 50 +++++++------- |
102 | block/replication.c | 18 ++-- | 104 | block/vhdx.c | 5 +- |
103 | block/snapshot-access.c | 8 +- | 105 | block/vmdk.c | 43 +++++------- |
104 | block/stream.c | 40 ++++---- | 106 | block/vpc.c | 50 +++++++------- |
105 | block/throttle.c | 36 ++++--- | 107 | block/vvfat.c | 16 ++--- |
106 | block/vdi.c | 11 +-- | 108 | hw/ide/core.c | 10 +-- |
107 | block/vhdx.c | 18 ++-- | 109 | qemu-img.c | 2 +- |
108 | block/vmdk.c | 132 ++++++++++++-------------- | 110 | tests/test-block-backend.c | 82 +++++++++++++++++++++++ |
109 | block/vpc.c | 11 +-- | 111 | util/aio-wait.c | 40 +++++++++++ |
110 | hw/scsi/scsi-disk.c | 23 +++-- | 112 | tests/Makefile.include | 2 + |
111 | hw/scsi/scsi-generic.c | 11 ++- | 113 | tests/qemu-iotests/033 | 29 ++++++++ |
112 | hw/scsi/virtio-scsi.c | 169 ++++++++++++++++++++++++++------- | 114 | tests/qemu-iotests/033.out | 13 ++++ |
113 | qemu-img.c | 8 +- | 115 | util/Makefile.objs | 2 +- |
114 | softmmu/dma-helpers.c | 12 ++- | 116 | 48 files changed, 980 insertions(+), 610 deletions(-) |
115 | tests/unit/test-bdrv-drain.c | 20 ++-- | 117 | create mode 100644 include/block/aio-wait.h |
116 | tests/unit/test-block-iothread.c | 3 +- | 118 | create mode 100644 tests/test-block-backend.c |
117 | 59 files changed, 1355 insertions(+), 907 deletions(-) | 119 | create mode 100644 util/aio-wait.c |
120 | diff view generated by jsdifflib |
Deleted patch | |||
---|---|---|---|
1 | It is never called outside of block.c. | ||
2 | 1 | ||
3 | Signed-off-by: Kevin Wolf <kwolf@redhat.com> | ||
4 | Message-Id: <20230203152202.49054-2-kwolf@redhat.com> | ||
5 | Reviewed-by: Emanuele Giuseppe Esposito <eesposit@redhat.com> | ||
6 | Reviewed-by: Vladimir Sementsov-Ogievskiy <vsementsov@yandex-team.ru> | ||
7 | Signed-off-by: Kevin Wolf <kwolf@redhat.com> | ||
8 | --- | ||
9 | include/block/block-io.h | 2 -- | ||
10 | block.c | 4 ++-- | ||
11 | 2 files changed, 2 insertions(+), 4 deletions(-) | ||
12 | |||
13 | diff --git a/include/block/block-io.h b/include/block/block-io.h | ||
14 | index XXXXXXX..XXXXXXX 100644 | ||
15 | --- a/include/block/block-io.h | ||
16 | +++ b/include/block/block-io.h | ||
17 | @@ -XXX,XX +XXX,XX @@ int bdrv_is_allocated_above(BlockDriverState *top, BlockDriverState *base, | ||
18 | int coroutine_fn bdrv_co_is_zero_fast(BlockDriverState *bs, int64_t offset, | ||
19 | int64_t bytes); | ||
20 | |||
21 | -int bdrv_can_set_read_only(BlockDriverState *bs, bool read_only, | ||
22 | - bool ignore_allow_rdw, Error **errp); | ||
23 | int bdrv_apply_auto_read_only(BlockDriverState *bs, const char *errmsg, | ||
24 | Error **errp); | ||
25 | bool bdrv_is_read_only(BlockDriverState *bs); | ||
26 | diff --git a/block.c b/block.c | ||
27 | index XXXXXXX..XXXXXXX 100644 | ||
28 | --- a/block.c | ||
29 | +++ b/block.c | ||
30 | @@ -XXX,XX +XXX,XX @@ bool bdrv_is_read_only(BlockDriverState *bs) | ||
31 | return !(bs->open_flags & BDRV_O_RDWR); | ||
32 | } | ||
33 | |||
34 | -int bdrv_can_set_read_only(BlockDriverState *bs, bool read_only, | ||
35 | - bool ignore_allow_rdw, Error **errp) | ||
36 | +static int bdrv_can_set_read_only(BlockDriverState *bs, bool read_only, | ||
37 | + bool ignore_allow_rdw, Error **errp) | ||
38 | { | ||
39 | IO_CODE(); | ||
40 | |||
41 | -- | ||
42 | 2.39.2 | diff view generated by jsdifflib |
Deleted patch | |||
---|---|---|---|
1 | bdrv_mirror_top_pwritev() accesses the job object when active mirroring | ||
2 | is enabled. It disables this code during early initialisation while | ||
3 | s->job isn't set yet. | ||
4 | 1 | ||
5 | However, s->job is still set way too early when the job object isn't | ||
6 | fully initialised. For example, &s->ops_in_flight isn't initialised yet | ||
7 | and the in_flight bitmap doesn't exist yet. This causes crashes when a | ||
8 | write request comes in too early. | ||
9 | |||
10 | Move the assignment of s->job to when the mirror job is actually fully | ||
11 | initialised to make sure that the mirror_top driver doesn't access it | ||
12 | too early. | ||
13 | |||
14 | Signed-off-by: Kevin Wolf <kwolf@redhat.com> | ||
15 | Message-Id: <20230203152202.49054-3-kwolf@redhat.com> | ||
16 | Reviewed-by: Emanuele Giuseppe Esposito <eesposit@redhat.com> | ||
17 | Reviewed-by: Vladimir Sementsov-Ogievskiy <vsementsov@yandex-team.ru> | ||
18 | Signed-off-by: Kevin Wolf <kwolf@redhat.com> | ||
19 | --- | ||
20 | block/mirror.c | 8 +++++++- | ||
21 | 1 file changed, 7 insertions(+), 1 deletion(-) | ||
22 | |||
23 | diff --git a/block/mirror.c b/block/mirror.c | ||
24 | index XXXXXXX..XXXXXXX 100644 | ||
25 | --- a/block/mirror.c | ||
26 | +++ b/block/mirror.c | ||
27 | @@ -XXX,XX +XXX,XX @@ static int coroutine_fn mirror_run(Job *job, Error **errp) | ||
28 | { | ||
29 | MirrorBlockJob *s = container_of(job, MirrorBlockJob, common.job); | ||
30 | BlockDriverState *bs = s->mirror_top_bs->backing->bs; | ||
31 | + MirrorBDSOpaque *mirror_top_opaque = s->mirror_top_bs->opaque; | ||
32 | BlockDriverState *target_bs = blk_bs(s->target); | ||
33 | bool need_drain = true; | ||
34 | BlockDeviceIoStatus iostatus; | ||
35 | @@ -XXX,XX +XXX,XX @@ static int coroutine_fn mirror_run(Job *job, Error **errp) | ||
36 | } | ||
37 | } | ||
38 | |||
39 | + /* | ||
40 | + * Only now the job is fully initialised and mirror_top_bs should start | ||
41 | + * accessing it. | ||
42 | + */ | ||
43 | + mirror_top_opaque->job = s; | ||
44 | + | ||
45 | assert(!s->dbi); | ||
46 | s->dbi = bdrv_dirty_iter_new(s->dirty_bitmap); | ||
47 | for (;;) { | ||
48 | @@ -XXX,XX +XXX,XX @@ static BlockJob *mirror_start_job( | ||
49 | if (!s) { | ||
50 | goto fail; | ||
51 | } | ||
52 | - bs_opaque->job = s; | ||
53 | |||
54 | /* The block job now has a reference to this node */ | ||
55 | bdrv_unref(mirror_top_bs); | ||
56 | -- | ||
57 | 2.39.2 | diff view generated by jsdifflib |
Deleted patch | |||
---|---|---|---|
1 | This adds GRAPH_RDLOCK annotations to declare that callers of | ||
2 | bdrv_co_truncate() need to hold a reader lock for the graph. | ||
3 | 1 | ||
4 | For some places, we know that they will hold the lock, but we don't have | ||
5 | the GRAPH_RDLOCK annotations yet. In this case, add assume_graph_lock() | ||
6 | with a FIXME comment. These places will be removed once everything is | ||
7 | properly annotated. | ||
8 | |||
9 | Signed-off-by: Kevin Wolf <kwolf@redhat.com> | ||
10 | Message-Id: <20230203152202.49054-4-kwolf@redhat.com> | ||
11 | Reviewed-by: Emanuele Giuseppe Esposito <eesposit@redhat.com> | ||
12 | Signed-off-by: Kevin Wolf <kwolf@redhat.com> | ||
13 | --- | ||
14 | include/block/block-io.h | 6 +++--- | ||
15 | include/block/block_int-common.h | 7 ++++--- | ||
16 | block/block-backend.c | 1 + | ||
17 | block/crypto.c | 2 +- | ||
18 | block/io.c | 1 + | ||
19 | block/parallels.c | 14 ++++++++------ | ||
20 | block/preallocate.c | 2 +- | ||
21 | block/qcow.c | 17 ++++++++++++----- | ||
22 | block/qcow2.c | 14 ++++++++------ | ||
23 | block/raw-format.c | 6 +++--- | ||
24 | block/vmdk.c | 2 ++ | ||
25 | 11 files changed, 44 insertions(+), 28 deletions(-) | ||
26 | |||
27 | diff --git a/include/block/block-io.h b/include/block/block-io.h | ||
28 | index XXXXXXX..XXXXXXX 100644 | ||
29 | --- a/include/block/block-io.h | ||
30 | +++ b/include/block/block-io.h | ||
31 | @@ -XXX,XX +XXX,XX @@ int coroutine_fn bdrv_co_pwrite_sync(BdrvChild *child, int64_t offset, | ||
32 | int coroutine_fn bdrv_co_pwrite_zeroes(BdrvChild *child, int64_t offset, | ||
33 | int64_t bytes, BdrvRequestFlags flags); | ||
34 | |||
35 | -int coroutine_fn bdrv_co_truncate(BdrvChild *child, int64_t offset, bool exact, | ||
36 | - PreallocMode prealloc, BdrvRequestFlags flags, | ||
37 | - Error **errp); | ||
38 | +int coroutine_fn GRAPH_RDLOCK | ||
39 | +bdrv_co_truncate(BdrvChild *child, int64_t offset, bool exact, | ||
40 | + PreallocMode prealloc, BdrvRequestFlags flags, Error **errp); | ||
41 | |||
42 | int64_t coroutine_fn bdrv_co_nb_sectors(BlockDriverState *bs); | ||
43 | int64_t co_wrapper_mixed bdrv_nb_sectors(BlockDriverState *bs); | ||
44 | diff --git a/include/block/block_int-common.h b/include/block/block_int-common.h | ||
45 | index XXXXXXX..XXXXXXX 100644 | ||
46 | --- a/include/block/block_int-common.h | ||
47 | +++ b/include/block/block_int-common.h | ||
48 | @@ -XXX,XX +XXX,XX @@ struct BlockDriver { | ||
49 | * If @exact is true and this function fails but would succeed | ||
50 | * with @exact = false, it should return -ENOTSUP. | ||
51 | */ | ||
52 | - int coroutine_fn (*bdrv_co_truncate)(BlockDriverState *bs, int64_t offset, | ||
53 | - bool exact, PreallocMode prealloc, | ||
54 | - BdrvRequestFlags flags, Error **errp); | ||
55 | + int coroutine_fn GRAPH_RDLOCK_PTR (*bdrv_co_truncate)( | ||
56 | + BlockDriverState *bs, int64_t offset, bool exact, | ||
57 | + PreallocMode prealloc, BdrvRequestFlags flags, Error **errp); | ||
58 | + | ||
59 | int64_t coroutine_fn (*bdrv_co_getlength)(BlockDriverState *bs); | ||
60 | int64_t coroutine_fn (*bdrv_co_get_allocated_file_size)( | ||
61 | BlockDriverState *bs); | ||
62 | diff --git a/block/block-backend.c b/block/block-backend.c | ||
63 | index XXXXXXX..XXXXXXX 100644 | ||
64 | --- a/block/block-backend.c | ||
65 | +++ b/block/block-backend.c | ||
66 | @@ -XXX,XX +XXX,XX @@ int coroutine_fn blk_co_truncate(BlockBackend *blk, int64_t offset, bool exact, | ||
67 | Error **errp) | ||
68 | { | ||
69 | IO_OR_GS_CODE(); | ||
70 | + GRAPH_RDLOCK_GUARD(); | ||
71 | if (!blk_is_available(blk)) { | ||
72 | error_setg(errp, "No medium inserted"); | ||
73 | return -ENOMEDIUM; | ||
74 | diff --git a/block/crypto.c b/block/crypto.c | ||
75 | index XXXXXXX..XXXXXXX 100644 | ||
76 | --- a/block/crypto.c | ||
77 | +++ b/block/crypto.c | ||
78 | @@ -XXX,XX +XXX,XX @@ block_crypto_co_create_generic(BlockDriverState *bs, int64_t size, | ||
79 | return ret; | ||
80 | } | ||
81 | |||
82 | -static int coroutine_fn | ||
83 | +static int coroutine_fn GRAPH_RDLOCK | ||
84 | block_crypto_co_truncate(BlockDriverState *bs, int64_t offset, bool exact, | ||
85 | PreallocMode prealloc, BdrvRequestFlags flags, | ||
86 | Error **errp) | ||
87 | diff --git a/block/io.c b/block/io.c | ||
88 | index XXXXXXX..XXXXXXX 100644 | ||
89 | --- a/block/io.c | ||
90 | +++ b/block/io.c | ||
91 | @@ -XXX,XX +XXX,XX @@ int coroutine_fn bdrv_co_truncate(BdrvChild *child, int64_t offset, bool exact, | ||
92 | int64_t old_size, new_bytes; | ||
93 | int ret; | ||
94 | IO_CODE(); | ||
95 | + assert_bdrv_graph_readable(); | ||
96 | |||
97 | /* if bs->drv == NULL, bs is closed, so there's nothing to do here */ | ||
98 | if (!drv) { | ||
99 | diff --git a/block/parallels.c b/block/parallels.c | ||
100 | index XXXXXXX..XXXXXXX 100644 | ||
101 | --- a/block/parallels.c | ||
102 | +++ b/block/parallels.c | ||
103 | @@ -XXX,XX +XXX,XX @@ static int64_t block_status(BDRVParallelsState *s, int64_t sector_num, | ||
104 | return start_off; | ||
105 | } | ||
106 | |||
107 | -static coroutine_fn int64_t allocate_clusters(BlockDriverState *bs, | ||
108 | - int64_t sector_num, | ||
109 | - int nb_sectors, int *pnum) | ||
110 | +static int64_t coroutine_fn GRAPH_RDLOCK | ||
111 | +allocate_clusters(BlockDriverState *bs, int64_t sector_num, | ||
112 | + int nb_sectors, int *pnum) | ||
113 | { | ||
114 | int ret = 0; | ||
115 | BDRVParallelsState *s = bs->opaque; | ||
116 | @@ -XXX,XX +XXX,XX @@ static coroutine_fn int parallels_co_writev(BlockDriverState *bs, | ||
117 | QEMUIOVector hd_qiov; | ||
118 | int ret = 0; | ||
119 | |||
120 | + assume_graph_lock(); /* FIXME */ | ||
121 | + | ||
122 | qemu_iovec_init(&hd_qiov, qiov->niov); | ||
123 | |||
124 | while (nb_sectors > 0) { | ||
125 | @@ -XXX,XX +XXX,XX @@ static coroutine_fn int parallels_co_readv(BlockDriverState *bs, | ||
126 | } | ||
127 | |||
128 | |||
129 | -static int coroutine_fn parallels_co_check(BlockDriverState *bs, | ||
130 | - BdrvCheckResult *res, | ||
131 | - BdrvCheckMode fix) | ||
132 | +static int coroutine_fn GRAPH_RDLOCK | ||
133 | +parallels_co_check(BlockDriverState *bs, BdrvCheckResult *res, | ||
134 | + BdrvCheckMode fix) | ||
135 | { | ||
136 | BDRVParallelsState *s = bs->opaque; | ||
137 | int64_t size, prev_off, high_off; | ||
138 | diff --git a/block/preallocate.c b/block/preallocate.c | ||
139 | index XXXXXXX..XXXXXXX 100644 | ||
140 | --- a/block/preallocate.c | ||
141 | +++ b/block/preallocate.c | ||
142 | @@ -XXX,XX +XXX,XX @@ static coroutine_fn int preallocate_co_pwritev_part(BlockDriverState *bs, | ||
143 | flags); | ||
144 | } | ||
145 | |||
146 | -static int coroutine_fn | ||
147 | +static int coroutine_fn GRAPH_RDLOCK | ||
148 | preallocate_co_truncate(BlockDriverState *bs, int64_t offset, | ||
149 | bool exact, PreallocMode prealloc, | ||
150 | BdrvRequestFlags flags, Error **errp) | ||
151 | diff --git a/block/qcow.c b/block/qcow.c | ||
152 | index XXXXXXX..XXXXXXX 100644 | ||
153 | --- a/block/qcow.c | ||
154 | +++ b/block/qcow.c | ||
155 | @@ -XXX,XX +XXX,XX @@ static int qcow_reopen_prepare(BDRVReopenState *state, | ||
156 | * return 0 if not allocated, 1 if *result is assigned, and negative | ||
157 | * errno on failure. | ||
158 | */ | ||
159 | -static int coroutine_fn get_cluster_offset(BlockDriverState *bs, | ||
160 | - uint64_t offset, int allocate, | ||
161 | - int compressed_size, | ||
162 | - int n_start, int n_end, | ||
163 | - uint64_t *result) | ||
164 | +static int coroutine_fn GRAPH_RDLOCK | ||
165 | +get_cluster_offset(BlockDriverState *bs, uint64_t offset, int allocate, | ||
166 | + int compressed_size, int n_start, int n_end, | ||
167 | + uint64_t *result) | ||
168 | { | ||
169 | BDRVQcowState *s = bs->opaque; | ||
170 | int min_index, i, j, l1_index, l2_index, ret; | ||
171 | @@ -XXX,XX +XXX,XX @@ static int coroutine_fn qcow_co_block_status(BlockDriverState *bs, | ||
172 | int64_t n; | ||
173 | uint64_t cluster_offset; | ||
174 | |||
175 | + assume_graph_lock(); /* FIXME */ | ||
176 | + | ||
177 | qemu_co_mutex_lock(&s->lock); | ||
178 | ret = get_cluster_offset(bs, offset, 0, 0, 0, 0, &cluster_offset); | ||
179 | qemu_co_mutex_unlock(&s->lock); | ||
180 | @@ -XXX,XX +XXX,XX @@ static coroutine_fn int qcow_co_preadv(BlockDriverState *bs, int64_t offset, | ||
181 | uint8_t *buf; | ||
182 | void *orig_buf; | ||
183 | |||
184 | + assume_graph_lock(); /* FIXME */ | ||
185 | + | ||
186 | if (qiov->niov > 1) { | ||
187 | buf = orig_buf = qemu_try_blockalign(bs, qiov->size); | ||
188 | if (buf == NULL) { | ||
189 | @@ -XXX,XX +XXX,XX @@ static coroutine_fn int qcow_co_pwritev(BlockDriverState *bs, int64_t offset, | ||
190 | uint8_t *buf; | ||
191 | void *orig_buf; | ||
192 | |||
193 | + assume_graph_lock(); /* FIXME */ | ||
194 | + | ||
195 | s->cluster_cache_offset = -1; /* disable compressed cache */ | ||
196 | |||
197 | /* We must always copy the iov when encrypting, so we | ||
198 | @@ -XXX,XX +XXX,XX @@ qcow_co_pwritev_compressed(BlockDriverState *bs, int64_t offset, int64_t bytes, | ||
199 | uint8_t *buf, *out_buf; | ||
200 | uint64_t cluster_offset; | ||
201 | |||
202 | + assume_graph_lock(); /* FIXME */ | ||
203 | + | ||
204 | buf = qemu_blockalign(bs, s->cluster_size); | ||
205 | if (bytes != s->cluster_size) { | ||
206 | if (bytes > s->cluster_size || | ||
207 | diff --git a/block/qcow2.c b/block/qcow2.c | ||
208 | index XXXXXXX..XXXXXXX 100644 | ||
209 | --- a/block/qcow2.c | ||
210 | +++ b/block/qcow2.c | ||
211 | @@ -XXX,XX +XXX,XX @@ static int qcow2_set_up_encryption(BlockDriverState *bs, | ||
212 | * | ||
213 | * Returns: 0 on success, -errno on failure. | ||
214 | */ | ||
215 | -static int coroutine_fn preallocate_co(BlockDriverState *bs, uint64_t offset, | ||
216 | - uint64_t new_length, PreallocMode mode, | ||
217 | - Error **errp) | ||
218 | +static int coroutine_fn GRAPH_RDLOCK | ||
219 | +preallocate_co(BlockDriverState *bs, uint64_t offset, uint64_t new_length, | ||
220 | + PreallocMode mode, Error **errp) | ||
221 | { | ||
222 | BDRVQcow2State *s = bs->opaque; | ||
223 | uint64_t bytes; | ||
224 | @@ -XXX,XX +XXX,XX @@ fail: | ||
225 | return ret; | ||
226 | } | ||
227 | |||
228 | -static int coroutine_fn qcow2_co_truncate(BlockDriverState *bs, int64_t offset, | ||
229 | - bool exact, PreallocMode prealloc, | ||
230 | - BdrvRequestFlags flags, Error **errp) | ||
231 | +static int coroutine_fn GRAPH_RDLOCK | ||
232 | +qcow2_co_truncate(BlockDriverState *bs, int64_t offset, bool exact, | ||
233 | + PreallocMode prealloc, BdrvRequestFlags flags, Error **errp) | ||
234 | { | ||
235 | BDRVQcow2State *s = bs->opaque; | ||
236 | uint64_t old_length; | ||
237 | @@ -XXX,XX +XXX,XX @@ qcow2_co_pwritev_compressed_part(BlockDriverState *bs, | ||
238 | AioTaskPool *aio = NULL; | ||
239 | int ret = 0; | ||
240 | |||
241 | + assume_graph_lock(); /* FIXME */ | ||
242 | + | ||
243 | if (has_data_file(bs)) { | ||
244 | return -ENOTSUP; | ||
245 | } | ||
246 | diff --git a/block/raw-format.c b/block/raw-format.c | ||
247 | index XXXXXXX..XXXXXXX 100644 | ||
248 | --- a/block/raw-format.c | ||
249 | +++ b/block/raw-format.c | ||
250 | @@ -XXX,XX +XXX,XX @@ static void raw_refresh_limits(BlockDriverState *bs, Error **errp) | ||
251 | } | ||
252 | } | ||
253 | |||
254 | -static int coroutine_fn raw_co_truncate(BlockDriverState *bs, int64_t offset, | ||
255 | - bool exact, PreallocMode prealloc, | ||
256 | - BdrvRequestFlags flags, Error **errp) | ||
257 | +static int coroutine_fn GRAPH_RDLOCK | ||
258 | +raw_co_truncate(BlockDriverState *bs, int64_t offset, bool exact, | ||
259 | + PreallocMode prealloc, BdrvRequestFlags flags, Error **errp) | ||
260 | { | ||
261 | BDRVRawState *s = bs->opaque; | ||
262 | |||
263 | diff --git a/block/vmdk.c b/block/vmdk.c | ||
264 | index XXXXXXX..XXXXXXX 100644 | ||
265 | --- a/block/vmdk.c | ||
266 | +++ b/block/vmdk.c | ||
267 | @@ -XXX,XX +XXX,XX @@ static int coroutine_fn | ||
268 | vmdk_co_pwritev_compressed(BlockDriverState *bs, int64_t offset, int64_t bytes, | ||
269 | QEMUIOVector *qiov) | ||
270 | { | ||
271 | + assume_graph_lock(); /* FIXME */ | ||
272 | + | ||
273 | if (bytes == 0) { | ||
274 | /* The caller will write bytes 0 to signal EOF. | ||
275 | * When receive it, we align EOF to a sector boundary. */ | ||
276 | -- | ||
277 | 2.39.2 | diff view generated by jsdifflib |
Deleted patch | |||
---|---|---|---|
1 | This adds GRAPH_RDLOCK annotations to declare that callers of | ||
2 | bdrv_co_block_status() need to hold a reader lock for the graph. | ||
3 | 1 | ||
4 | For some places, we know that they will hold the lock, but we don't have | ||
5 | the GRAPH_RDLOCK annotations yet. In this case, add assume_graph_lock() | ||
6 | with a FIXME comment. These places will be removed once everything is | ||
7 | properly annotated. | ||
8 | |||
9 | Signed-off-by: Emanuele Giuseppe Esposito <eesposit@redhat.com> | ||
10 | Signed-off-by: Kevin Wolf <kwolf@redhat.com> | ||
11 | Message-Id: <20230203152202.49054-5-kwolf@redhat.com> | ||
12 | Reviewed-by: Emanuele Giuseppe Esposito <eesposit@redhat.com> | ||
13 | Signed-off-by: Kevin Wolf <kwolf@redhat.com> | ||
14 | --- | ||
15 | block/coroutines.h | 2 +- | ||
16 | include/block/block-copy.h | 6 +++--- | ||
17 | include/block/block-io.h | 22 +++++++++++----------- | ||
18 | include/block/block_int-common.h | 3 ++- | ||
19 | block/backup.c | 3 +++ | ||
20 | block/block-backend.c | 2 ++ | ||
21 | block/block-copy.c | 19 +++++++++++-------- | ||
22 | block/io.c | 13 ++++++++----- | ||
23 | block/mirror.c | 14 +++++++++----- | ||
24 | block/qcow.c | 11 ++++------- | ||
25 | block/quorum.c | 9 ++++----- | ||
26 | block/stream.c | 32 ++++++++++++++++++-------------- | ||
27 | qemu-img.c | 4 +++- | ||
28 | tests/unit/test-block-iothread.c | 3 ++- | ||
29 | 14 files changed, 81 insertions(+), 62 deletions(-) | ||
30 | |||
31 | diff --git a/block/coroutines.h b/block/coroutines.h | ||
32 | index XXXXXXX..XXXXXXX 100644 | ||
33 | --- a/block/coroutines.h | ||
34 | +++ b/block/coroutines.h | ||
35 | @@ -XXX,XX +XXX,XX @@ bdrv_co_check(BlockDriverState *bs, BdrvCheckResult *res, BdrvCheckMode fix); | ||
36 | int coroutine_fn GRAPH_RDLOCK | ||
37 | bdrv_co_invalidate_cache(BlockDriverState *bs, Error **errp); | ||
38 | |||
39 | -int coroutine_fn | ||
40 | +int coroutine_fn GRAPH_RDLOCK | ||
41 | bdrv_co_common_block_status_above(BlockDriverState *bs, | ||
42 | BlockDriverState *base, | ||
43 | bool include_base, | ||
44 | diff --git a/include/block/block-copy.h b/include/block/block-copy.h | ||
45 | index XXXXXXX..XXXXXXX 100644 | ||
46 | --- a/include/block/block-copy.h | ||
47 | +++ b/include/block/block-copy.h | ||
48 | @@ -XXX,XX +XXX,XX @@ void block_copy_set_progress_meter(BlockCopyState *s, ProgressMeter *pm); | ||
49 | void block_copy_state_free(BlockCopyState *s); | ||
50 | |||
51 | void block_copy_reset(BlockCopyState *s, int64_t offset, int64_t bytes); | ||
52 | -int64_t coroutine_fn block_copy_reset_unallocated(BlockCopyState *s, | ||
53 | - int64_t offset, | ||
54 | - int64_t *count); | ||
55 | + | ||
56 | +int64_t coroutine_fn GRAPH_RDLOCK | ||
57 | +block_copy_reset_unallocated(BlockCopyState *s, int64_t offset, int64_t *count); | ||
58 | |||
59 | int coroutine_fn block_copy(BlockCopyState *s, int64_t offset, int64_t bytes, | ||
60 | bool ignore_ratelimit, uint64_t timeout_ns, | ||
61 | diff --git a/include/block/block-io.h b/include/block/block-io.h | ||
62 | index XXXXXXX..XXXXXXX 100644 | ||
63 | --- a/include/block/block-io.h | ||
64 | +++ b/include/block/block-io.h | ||
65 | @@ -XXX,XX +XXX,XX @@ int bdrv_block_status(BlockDriverState *bs, int64_t offset, | ||
66 | int64_t bytes, int64_t *pnum, int64_t *map, | ||
67 | BlockDriverState **file); | ||
68 | |||
69 | -int coroutine_fn bdrv_co_block_status_above(BlockDriverState *bs, | ||
70 | - BlockDriverState *base, | ||
71 | - int64_t offset, int64_t bytes, | ||
72 | - int64_t *pnum, int64_t *map, | ||
73 | - BlockDriverState **file); | ||
74 | +int coroutine_fn GRAPH_RDLOCK | ||
75 | +bdrv_co_block_status_above(BlockDriverState *bs, BlockDriverState *base, | ||
76 | + int64_t offset, int64_t bytes, int64_t *pnum, | ||
77 | + int64_t *map, BlockDriverState **file); | ||
78 | int bdrv_block_status_above(BlockDriverState *bs, BlockDriverState *base, | ||
79 | int64_t offset, int64_t bytes, int64_t *pnum, | ||
80 | int64_t *map, BlockDriverState **file); | ||
81 | |||
82 | -int coroutine_fn bdrv_co_is_allocated(BlockDriverState *bs, int64_t offset, | ||
83 | - int64_t bytes, int64_t *pnum); | ||
84 | +int coroutine_fn GRAPH_RDLOCK | ||
85 | +bdrv_co_is_allocated(BlockDriverState *bs, int64_t offset, int64_t bytes, | ||
86 | + int64_t *pnum); | ||
87 | int bdrv_is_allocated(BlockDriverState *bs, int64_t offset, int64_t bytes, | ||
88 | int64_t *pnum); | ||
89 | |||
90 | -int coroutine_fn bdrv_co_is_allocated_above(BlockDriverState *top, | ||
91 | - BlockDriverState *base, | ||
92 | - bool include_base, int64_t offset, | ||
93 | - int64_t bytes, int64_t *pnum); | ||
94 | +int coroutine_fn GRAPH_RDLOCK | ||
95 | +bdrv_co_is_allocated_above(BlockDriverState *top, BlockDriverState *base, | ||
96 | + bool include_base, int64_t offset, int64_t bytes, | ||
97 | + int64_t *pnum); | ||
98 | int bdrv_is_allocated_above(BlockDriverState *top, BlockDriverState *base, | ||
99 | bool include_base, int64_t offset, int64_t bytes, | ||
100 | int64_t *pnum); | ||
101 | diff --git a/include/block/block_int-common.h b/include/block/block_int-common.h | ||
102 | index XXXXXXX..XXXXXXX 100644 | ||
103 | --- a/include/block/block_int-common.h | ||
104 | +++ b/include/block/block_int-common.h | ||
105 | @@ -XXX,XX +XXX,XX @@ struct BlockDriver { | ||
106 | * *pnum value for the block-status cache on protocol nodes, prior | ||
107 | * to clamping *pnum for return to its caller. | ||
108 | */ | ||
109 | - int coroutine_fn (*bdrv_co_block_status)(BlockDriverState *bs, | ||
110 | + int coroutine_fn GRAPH_RDLOCK_PTR (*bdrv_co_block_status)( | ||
111 | + BlockDriverState *bs, | ||
112 | bool want_zero, int64_t offset, int64_t bytes, int64_t *pnum, | ||
113 | int64_t *map, BlockDriverState **file); | ||
114 | |||
115 | diff --git a/block/backup.c b/block/backup.c | ||
116 | index XXXXXXX..XXXXXXX 100644 | ||
117 | --- a/block/backup.c | ||
118 | +++ b/block/backup.c | ||
119 | @@ -XXX,XX +XXX,XX @@ static int coroutine_fn backup_run(Job *job, Error **errp) | ||
120 | return -ECANCELED; | ||
121 | } | ||
122 | |||
123 | + /* rdlock protects the subsequent call to bdrv_is_allocated() */ | ||
124 | + bdrv_graph_co_rdlock(); | ||
125 | ret = block_copy_reset_unallocated(s->bcs, offset, &count); | ||
126 | + bdrv_graph_co_rdunlock(); | ||
127 | if (ret < 0) { | ||
128 | return ret; | ||
129 | } | ||
130 | diff --git a/block/block-backend.c b/block/block-backend.c | ||
131 | index XXXXXXX..XXXXXXX 100644 | ||
132 | --- a/block/block-backend.c | ||
133 | +++ b/block/block-backend.c | ||
134 | @@ -XXX,XX +XXX,XX @@ int coroutine_fn blk_co_block_status_above(BlockBackend *blk, | ||
135 | BlockDriverState **file) | ||
136 | { | ||
137 | IO_CODE(); | ||
138 | + GRAPH_RDLOCK_GUARD(); | ||
139 | return bdrv_co_block_status_above(blk_bs(blk), base, offset, bytes, pnum, | ||
140 | map, file); | ||
141 | } | ||
142 | @@ -XXX,XX +XXX,XX @@ int coroutine_fn blk_co_is_allocated_above(BlockBackend *blk, | ||
143 | int64_t bytes, int64_t *pnum) | ||
144 | { | ||
145 | IO_CODE(); | ||
146 | + GRAPH_RDLOCK_GUARD(); | ||
147 | return bdrv_co_is_allocated_above(blk_bs(blk), base, include_base, offset, | ||
148 | bytes, pnum); | ||
149 | } | ||
150 | diff --git a/block/block-copy.c b/block/block-copy.c | ||
151 | index XXXXXXX..XXXXXXX 100644 | ||
152 | --- a/block/block-copy.c | ||
153 | +++ b/block/block-copy.c | ||
154 | @@ -XXX,XX +XXX,XX @@ static coroutine_fn int block_copy_task_entry(AioTask *task) | ||
155 | return ret; | ||
156 | } | ||
157 | |||
158 | -static coroutine_fn int block_copy_block_status(BlockCopyState *s, | ||
159 | - int64_t offset, | ||
160 | - int64_t bytes, int64_t *pnum) | ||
161 | +static coroutine_fn GRAPH_RDLOCK | ||
162 | +int block_copy_block_status(BlockCopyState *s, int64_t offset, int64_t bytes, | ||
163 | + int64_t *pnum) | ||
164 | { | ||
165 | int64_t num; | ||
166 | BlockDriverState *base; | ||
167 | @@ -XXX,XX +XXX,XX @@ static coroutine_fn int block_copy_block_status(BlockCopyState *s, | ||
168 | * Check if the cluster starting at offset is allocated or not. | ||
169 | * return via pnum the number of contiguous clusters sharing this allocation. | ||
170 | */ | ||
171 | -static int coroutine_fn block_copy_is_cluster_allocated(BlockCopyState *s, | ||
172 | - int64_t offset, | ||
173 | - int64_t *pnum) | ||
174 | +static int coroutine_fn GRAPH_RDLOCK | ||
175 | +block_copy_is_cluster_allocated(BlockCopyState *s, int64_t offset, | ||
176 | + int64_t *pnum) | ||
177 | { | ||
178 | BlockDriverState *bs = s->source->bs; | ||
179 | int64_t count, total_count = 0; | ||
180 | @@ -XXX,XX +XXX,XX @@ static int coroutine_fn block_copy_is_cluster_allocated(BlockCopyState *s, | ||
181 | assert(QEMU_IS_ALIGNED(offset, s->cluster_size)); | ||
182 | |||
183 | while (true) { | ||
184 | + /* protected in backup_run() */ | ||
185 | ret = bdrv_co_is_allocated(bs, offset, bytes, &count); | ||
186 | if (ret < 0) { | ||
187 | return ret; | ||
188 | @@ -XXX,XX +XXX,XX @@ int64_t coroutine_fn block_copy_reset_unallocated(BlockCopyState *s, | ||
189 | * Returns 1 if dirty clusters found and successfully copied, 0 if no dirty | ||
190 | * clusters found and -errno on failure. | ||
191 | */ | ||
192 | -static int coroutine_fn | ||
193 | +static int coroutine_fn GRAPH_RDLOCK | ||
194 | block_copy_dirty_clusters(BlockCopyCallState *call_state) | ||
195 | { | ||
196 | BlockCopyState *s = call_state->s; | ||
197 | @@ -XXX,XX +XXX,XX @@ void block_copy_kick(BlockCopyCallState *call_state) | ||
198 | * it means that some I/O operation failed in context of _this_ block_copy call, | ||
199 | * not some parallel operation. | ||
200 | */ | ||
201 | -static int coroutine_fn block_copy_common(BlockCopyCallState *call_state) | ||
202 | +static int coroutine_fn GRAPH_RDLOCK | ||
203 | +block_copy_common(BlockCopyCallState *call_state) | ||
204 | { | ||
205 | int ret; | ||
206 | BlockCopyState *s = call_state->s; | ||
207 | @@ -XXX,XX +XXX,XX @@ static int coroutine_fn block_copy_common(BlockCopyCallState *call_state) | ||
208 | |||
209 | static void coroutine_fn block_copy_async_co_entry(void *opaque) | ||
210 | { | ||
211 | + GRAPH_RDLOCK_GUARD(); | ||
212 | block_copy_common(opaque); | ||
213 | } | ||
214 | |||
215 | diff --git a/block/io.c b/block/io.c | ||
216 | index XXXXXXX..XXXXXXX 100644 | ||
217 | --- a/block/io.c | ||
218 | +++ b/block/io.c | ||
219 | @@ -XXX,XX +XXX,XX @@ int bdrv_flush_all(void) | ||
220 | * BDRV_BLOCK_OFFSET_VALID bit is set, 'map' and 'file' (if non-NULL) are | ||
221 | * set to the host mapping and BDS corresponding to the guest offset. | ||
222 | */ | ||
223 | -static int coroutine_fn bdrv_co_block_status(BlockDriverState *bs, | ||
224 | - bool want_zero, | ||
225 | - int64_t offset, int64_t bytes, | ||
226 | - int64_t *pnum, int64_t *map, | ||
227 | - BlockDriverState **file) | ||
228 | +static int coroutine_fn GRAPH_RDLOCK | ||
229 | +bdrv_co_block_status(BlockDriverState *bs, bool want_zero, | ||
230 | + int64_t offset, int64_t bytes, | ||
231 | + int64_t *pnum, int64_t *map, BlockDriverState **file) | ||
232 | { | ||
233 | int64_t total_size; | ||
234 | int64_t n; /* bytes */ | ||
235 | @@ -XXX,XX +XXX,XX @@ static int coroutine_fn bdrv_co_block_status(BlockDriverState *bs, | ||
236 | bool has_filtered_child; | ||
237 | |||
238 | assert(pnum); | ||
239 | + assert_bdrv_graph_readable(); | ||
240 | *pnum = 0; | ||
241 | total_size = bdrv_getlength(bs); | ||
242 | if (total_size < 0) { | ||
243 | @@ -XXX,XX +XXX,XX @@ bdrv_co_common_block_status_above(BlockDriverState *bs, | ||
244 | IO_CODE(); | ||
245 | |||
246 | assert(!include_base || base); /* Can't include NULL base */ | ||
247 | + assert_bdrv_graph_readable(); | ||
248 | |||
249 | if (!depth) { | ||
250 | depth = &dummy; | ||
251 | @@ -XXX,XX +XXX,XX @@ int coroutine_fn bdrv_co_is_zero_fast(BlockDriverState *bs, int64_t offset, | ||
252 | int64_t pnum = bytes; | ||
253 | IO_CODE(); | ||
254 | |||
255 | + assume_graph_lock(); /* FIXME */ | ||
256 | + | ||
257 | if (!bytes) { | ||
258 | return 1; | ||
259 | } | ||
260 | diff --git a/block/mirror.c b/block/mirror.c | ||
261 | index XXXXXXX..XXXXXXX 100644 | ||
262 | --- a/block/mirror.c | ||
263 | +++ b/block/mirror.c | ||
264 | @@ -XXX,XX +XXX,XX @@ static uint64_t coroutine_fn mirror_iteration(MirrorBlockJob *s) | ||
265 | MirrorMethod mirror_method = MIRROR_METHOD_COPY; | ||
266 | |||
267 | assert(!(offset % s->granularity)); | ||
268 | - ret = bdrv_block_status_above(source, NULL, offset, | ||
269 | - nb_chunks * s->granularity, | ||
270 | - &io_bytes, NULL, NULL); | ||
271 | + WITH_GRAPH_RDLOCK_GUARD() { | ||
272 | + ret = bdrv_block_status_above(source, NULL, offset, | ||
273 | + nb_chunks * s->granularity, | ||
274 | + &io_bytes, NULL, NULL); | ||
275 | + } | ||
276 | if (ret < 0) { | ||
277 | io_bytes = MIN(nb_chunks * s->granularity, max_io_bytes); | ||
278 | } else if (ret & BDRV_BLOCK_DATA) { | ||
279 | @@ -XXX,XX +XXX,XX @@ static int coroutine_fn mirror_dirty_init(MirrorBlockJob *s) | ||
280 | return 0; | ||
281 | } | ||
282 | |||
283 | - ret = bdrv_is_allocated_above(bs, s->base_overlay, true, offset, bytes, | ||
284 | - &count); | ||
285 | + WITH_GRAPH_RDLOCK_GUARD() { | ||
286 | + ret = bdrv_is_allocated_above(bs, s->base_overlay, true, offset, | ||
287 | + bytes, &count); | ||
288 | + } | ||
289 | if (ret < 0) { | ||
290 | return ret; | ||
291 | } | ||
292 | diff --git a/block/qcow.c b/block/qcow.c | ||
293 | index XXXXXXX..XXXXXXX 100644 | ||
294 | --- a/block/qcow.c | ||
295 | +++ b/block/qcow.c | ||
296 | @@ -XXX,XX +XXX,XX @@ get_cluster_offset(BlockDriverState *bs, uint64_t offset, int allocate, | ||
297 | return 1; | ||
298 | } | ||
299 | |||
300 | -static int coroutine_fn qcow_co_block_status(BlockDriverState *bs, | ||
301 | - bool want_zero, | ||
302 | - int64_t offset, int64_t bytes, | ||
303 | - int64_t *pnum, int64_t *map, | ||
304 | - BlockDriverState **file) | ||
305 | +static int coroutine_fn GRAPH_RDLOCK | ||
306 | +qcow_co_block_status(BlockDriverState *bs, bool want_zero, | ||
307 | + int64_t offset, int64_t bytes, int64_t *pnum, | ||
308 | + int64_t *map, BlockDriverState **file) | ||
309 | { | ||
310 | BDRVQcowState *s = bs->opaque; | ||
311 | int index_in_cluster, ret; | ||
312 | int64_t n; | ||
313 | uint64_t cluster_offset; | ||
314 | |||
315 | - assume_graph_lock(); /* FIXME */ | ||
316 | - | ||
317 | qemu_co_mutex_lock(&s->lock); | ||
318 | ret = get_cluster_offset(bs, offset, 0, 0, 0, 0, &cluster_offset); | ||
319 | qemu_co_mutex_unlock(&s->lock); | ||
320 | diff --git a/block/quorum.c b/block/quorum.c | ||
321 | index XXXXXXX..XXXXXXX 100644 | ||
322 | --- a/block/quorum.c | ||
323 | +++ b/block/quorum.c | ||
324 | @@ -XXX,XX +XXX,XX @@ static void quorum_child_perm(BlockDriverState *bs, BdrvChild *c, | ||
325 | * return BDRV_BLOCK_ZERO if *all* children agree that a certain | ||
326 | * region contains zeroes, and BDRV_BLOCK_DATA otherwise. | ||
327 | */ | ||
328 | -static int coroutine_fn quorum_co_block_status(BlockDriverState *bs, | ||
329 | - bool want_zero, | ||
330 | - int64_t offset, int64_t count, | ||
331 | - int64_t *pnum, int64_t *map, | ||
332 | - BlockDriverState **file) | ||
333 | +static int coroutine_fn GRAPH_RDLOCK | ||
334 | +quorum_co_block_status(BlockDriverState *bs, bool want_zero, | ||
335 | + int64_t offset, int64_t count, | ||
336 | + int64_t *pnum, int64_t *map, BlockDriverState **file) | ||
337 | { | ||
338 | BDRVQuorumState *s = bs->opaque; | ||
339 | int i, ret; | ||
340 | diff --git a/block/stream.c b/block/stream.c | ||
341 | index XXXXXXX..XXXXXXX 100644 | ||
342 | --- a/block/stream.c | ||
343 | +++ b/block/stream.c | ||
344 | @@ -XXX,XX +XXX,XX @@ static int coroutine_fn stream_run(Job *job, Error **errp) | ||
345 | |||
346 | copy = false; | ||
347 | |||
348 | - ret = bdrv_is_allocated(unfiltered_bs, offset, STREAM_CHUNK, &n); | ||
349 | - if (ret == 1) { | ||
350 | - /* Allocated in the top, no need to copy. */ | ||
351 | - } else if (ret >= 0) { | ||
352 | - /* Copy if allocated in the intermediate images. Limit to the | ||
353 | - * known-unallocated area [offset, offset+n*BDRV_SECTOR_SIZE). */ | ||
354 | - ret = bdrv_is_allocated_above(bdrv_cow_bs(unfiltered_bs), | ||
355 | - s->base_overlay, true, | ||
356 | - offset, n, &n); | ||
357 | - /* Finish early if end of backing file has been reached */ | ||
358 | - if (ret == 0 && n == 0) { | ||
359 | - n = len - offset; | ||
360 | + WITH_GRAPH_RDLOCK_GUARD() { | ||
361 | + ret = bdrv_is_allocated(unfiltered_bs, offset, STREAM_CHUNK, &n); | ||
362 | + if (ret == 1) { | ||
363 | + /* Allocated in the top, no need to copy. */ | ||
364 | + } else if (ret >= 0) { | ||
365 | + /* | ||
366 | + * Copy if allocated in the intermediate images. Limit to the | ||
367 | + * known-unallocated area [offset, offset+n*BDRV_SECTOR_SIZE). | ||
368 | + */ | ||
369 | + ret = bdrv_is_allocated_above(bdrv_cow_bs(unfiltered_bs), | ||
370 | + s->base_overlay, true, | ||
371 | + offset, n, &n); | ||
372 | + /* Finish early if end of backing file has been reached */ | ||
373 | + if (ret == 0 && n == 0) { | ||
374 | + n = len - offset; | ||
375 | + } | ||
376 | + | ||
377 | + copy = (ret > 0); | ||
378 | } | ||
379 | - | ||
380 | - copy = (ret > 0); | ||
381 | } | ||
382 | trace_stream_one_iteration(s, offset, n, ret); | ||
383 | if (copy) { | ||
384 | diff --git a/qemu-img.c b/qemu-img.c | ||
385 | index XXXXXXX..XXXXXXX 100644 | ||
386 | --- a/qemu-img.c | ||
387 | +++ b/qemu-img.c | ||
388 | @@ -XXX,XX +XXX,XX @@ static void coroutine_fn convert_co_do_copy(void *opaque) | ||
389 | qemu_co_mutex_unlock(&s->lock); | ||
390 | break; | ||
391 | } | ||
392 | - n = convert_iteration_sectors(s, s->sector_num); | ||
393 | + WITH_GRAPH_RDLOCK_GUARD() { | ||
394 | + n = convert_iteration_sectors(s, s->sector_num); | ||
395 | + } | ||
396 | if (n < 0) { | ||
397 | qemu_co_mutex_unlock(&s->lock); | ||
398 | s->ret = n; | ||
399 | diff --git a/tests/unit/test-block-iothread.c b/tests/unit/test-block-iothread.c | ||
400 | index XXXXXXX..XXXXXXX 100644 | ||
401 | --- a/tests/unit/test-block-iothread.c | ||
402 | +++ b/tests/unit/test-block-iothread.c | ||
403 | @@ -XXX,XX +XXX,XX @@ static void test_sync_op_blk_truncate(BlockBackend *blk) | ||
404 | g_assert_cmpint(ret, ==, -EINVAL); | ||
405 | } | ||
406 | |||
407 | -static void test_sync_op_block_status(BdrvChild *c) | ||
408 | +/* Disable TSA to make bdrv_test.bdrv_co_block_status writable */ | ||
409 | +static void TSA_NO_TSA test_sync_op_block_status(BdrvChild *c) | ||
410 | { | ||
411 | int ret; | ||
412 | int64_t n; | ||
413 | -- | ||
414 | 2.39.2 | diff view generated by jsdifflib |
Deleted patch | |||
---|---|---|---|
1 | This adds GRAPH_RDLOCK annotations to declare that callers of | ||
2 | bdrv_co_ioctl() need to hold a reader lock for the graph. | ||
3 | 1 | ||
4 | Signed-off-by: Kevin Wolf <kwolf@redhat.com> | ||
5 | Message-Id: <20230203152202.49054-6-kwolf@redhat.com> | ||
6 | Reviewed-by: Emanuele Giuseppe Esposito <eesposit@redhat.com> | ||
7 | Signed-off-by: Kevin Wolf <kwolf@redhat.com> | ||
8 | --- | ||
9 | include/block/block-io.h | 3 ++- | ||
10 | include/block/block_int-common.h | 9 +++++---- | ||
11 | block/block-backend.c | 1 + | ||
12 | block/io.c | 1 + | ||
13 | block/raw-format.c | 4 ++-- | ||
14 | 5 files changed, 11 insertions(+), 7 deletions(-) | ||
15 | |||
16 | diff --git a/include/block/block-io.h b/include/block/block-io.h | ||
17 | index XXXXXXX..XXXXXXX 100644 | ||
18 | --- a/include/block/block-io.h | ||
19 | +++ b/include/block/block-io.h | ||
20 | @@ -XXX,XX +XXX,XX @@ void bdrv_aio_cancel(BlockAIOCB *acb); | ||
21 | void bdrv_aio_cancel_async(BlockAIOCB *acb); | ||
22 | |||
23 | /* sg packet commands */ | ||
24 | -int coroutine_fn bdrv_co_ioctl(BlockDriverState *bs, int req, void *buf); | ||
25 | +int coroutine_fn GRAPH_RDLOCK | ||
26 | +bdrv_co_ioctl(BlockDriverState *bs, int req, void *buf); | ||
27 | |||
28 | /* Ensure contents are flushed to disk. */ | ||
29 | int coroutine_fn bdrv_co_flush(BlockDriverState *bs); | ||
30 | diff --git a/include/block/block_int-common.h b/include/block/block_int-common.h | ||
31 | index XXXXXXX..XXXXXXX 100644 | ||
32 | --- a/include/block/block_int-common.h | ||
33 | +++ b/include/block/block_int-common.h | ||
34 | @@ -XXX,XX +XXX,XX @@ struct BlockDriver { | ||
35 | void coroutine_fn (*bdrv_co_lock_medium)(BlockDriverState *bs, bool locked); | ||
36 | |||
37 | /* to control generic scsi devices */ | ||
38 | - BlockAIOCB *(*bdrv_aio_ioctl)(BlockDriverState *bs, | ||
39 | - unsigned long int req, void *buf, | ||
40 | + BlockAIOCB *coroutine_fn GRAPH_RDLOCK_PTR (*bdrv_aio_ioctl)( | ||
41 | + BlockDriverState *bs, unsigned long int req, void *buf, | ||
42 | BlockCompletionFunc *cb, void *opaque); | ||
43 | - int coroutine_fn (*bdrv_co_ioctl)(BlockDriverState *bs, | ||
44 | - unsigned long int req, void *buf); | ||
45 | + | ||
46 | + int coroutine_fn GRAPH_RDLOCK_PTR (*bdrv_co_ioctl)( | ||
47 | + BlockDriverState *bs, unsigned long int req, void *buf); | ||
48 | |||
49 | /* | ||
50 | * Returns 0 for completed check, -errno for internal errors. | ||
51 | diff --git a/block/block-backend.c b/block/block-backend.c | ||
52 | index XXXXXXX..XXXXXXX 100644 | ||
53 | --- a/block/block-backend.c | ||
54 | +++ b/block/block-backend.c | ||
55 | @@ -XXX,XX +XXX,XX @@ blk_co_do_ioctl(BlockBackend *blk, unsigned long int req, void *buf) | ||
56 | IO_CODE(); | ||
57 | |||
58 | blk_wait_while_drained(blk); | ||
59 | + GRAPH_RDLOCK_GUARD(); | ||
60 | |||
61 | if (!blk_is_available(blk)) { | ||
62 | return -ENOMEDIUM; | ||
63 | diff --git a/block/io.c b/block/io.c | ||
64 | index XXXXXXX..XXXXXXX 100644 | ||
65 | --- a/block/io.c | ||
66 | +++ b/block/io.c | ||
67 | @@ -XXX,XX +XXX,XX @@ int coroutine_fn bdrv_co_ioctl(BlockDriverState *bs, int req, void *buf) | ||
68 | }; | ||
69 | BlockAIOCB *acb; | ||
70 | IO_CODE(); | ||
71 | + assert_bdrv_graph_readable(); | ||
72 | |||
73 | bdrv_inc_in_flight(bs); | ||
74 | if (!drv || (!drv->bdrv_aio_ioctl && !drv->bdrv_co_ioctl)) { | ||
75 | diff --git a/block/raw-format.c b/block/raw-format.c | ||
76 | index XXXXXXX..XXXXXXX 100644 | ||
77 | --- a/block/raw-format.c | ||
78 | +++ b/block/raw-format.c | ||
79 | @@ -XXX,XX +XXX,XX @@ static void coroutine_fn raw_co_lock_medium(BlockDriverState *bs, bool locked) | ||
80 | bdrv_co_lock_medium(bs->file->bs, locked); | ||
81 | } | ||
82 | |||
83 | -static int coroutine_fn raw_co_ioctl(BlockDriverState *bs, | ||
84 | - unsigned long int req, void *buf) | ||
85 | +static int coroutine_fn GRAPH_RDLOCK | ||
86 | +raw_co_ioctl(BlockDriverState *bs, unsigned long int req, void *buf) | ||
87 | { | ||
88 | BDRVRawState *s = bs->opaque; | ||
89 | if (s->offset || s->has_size) { | ||
90 | -- | ||
91 | 2.39.2 | diff view generated by jsdifflib |
Deleted patch | |||
---|---|---|---|
1 | From: Emanuele Giuseppe Esposito <eesposit@redhat.com> | ||
2 | 1 | ||
3 | This function is called in two different places: | ||
4 | - timer callback, which does not take the graph rdlock. | ||
5 | - bdrv_qed_drain_begin(), which is .bdrv_drain_begin() | ||
6 | callback documented as function that does not take the lock. | ||
7 | |||
8 | Since it calls recursive functions that traverse the | ||
9 | graph, we need to protect them with the graph rdlock. | ||
10 | |||
11 | Signed-off-by: Emanuele Giuseppe Esposito <eesposit@redhat.com> | ||
12 | Signed-off-by: Kevin Wolf <kwolf@redhat.com> | ||
13 | Message-Id: <20230203152202.49054-7-kwolf@redhat.com> | ||
14 | Reviewed-by: Emanuele Giuseppe Esposito <eesposit@redhat.com> | ||
15 | Signed-off-by: Kevin Wolf <kwolf@redhat.com> | ||
16 | --- | ||
17 | block/qed.c | 4 +++- | ||
18 | 1 file changed, 3 insertions(+), 1 deletion(-) | ||
19 | |||
20 | diff --git a/block/qed.c b/block/qed.c | ||
21 | index XXXXXXX..XXXXXXX 100644 | ||
22 | --- a/block/qed.c | ||
23 | +++ b/block/qed.c | ||
24 | @@ -XXX,XX +XXX,XX @@ static void coroutine_fn qed_unplug_allocating_write_reqs(BDRVQEDState *s) | ||
25 | qemu_co_mutex_unlock(&s->table_lock); | ||
26 | } | ||
27 | |||
28 | -static void coroutine_fn qed_need_check_timer(BDRVQEDState *s) | ||
29 | +static void coroutine_fn GRAPH_RDLOCK qed_need_check_timer(BDRVQEDState *s) | ||
30 | { | ||
31 | int ret; | ||
32 | |||
33 | trace_qed_need_check_timer_cb(s); | ||
34 | + assert_bdrv_graph_readable(); | ||
35 | |||
36 | if (!qed_plug_allocating_write_reqs(s)) { | ||
37 | return; | ||
38 | @@ -XXX,XX +XXX,XX @@ static void coroutine_fn qed_need_check_timer(BDRVQEDState *s) | ||
39 | static void coroutine_fn qed_need_check_timer_entry(void *opaque) | ||
40 | { | ||
41 | BDRVQEDState *s = opaque; | ||
42 | + GRAPH_RDLOCK_GUARD(); | ||
43 | |||
44 | qed_need_check_timer(opaque); | ||
45 | bdrv_dec_in_flight(s->bs); | ||
46 | -- | ||
47 | 2.39.2 | diff view generated by jsdifflib |
Deleted patch | |||
---|---|---|---|
1 | From: Emanuele Giuseppe Esposito <eesposit@redhat.com> | ||
2 | 1 | ||
3 | This adds GRAPH_RDLOCK annotations to declare that callers of | ||
4 | bdrv_co_flush() need to hold a reader lock for the graph. | ||
5 | |||
6 | For some places, we know that they will hold the lock, but we don't have | ||
7 | the GRAPH_RDLOCK annotations yet. In this case, add assume_graph_lock() | ||
8 | with a FIXME comment. These places will be removed once everything is | ||
9 | properly annotated. | ||
10 | |||
11 | Signed-off-by: Emanuele Giuseppe Esposito <eesposit@redhat.com> | ||
12 | Signed-off-by: Kevin Wolf <kwolf@redhat.com> | ||
13 | Message-Id: <20230203152202.49054-8-kwolf@redhat.com> | ||
14 | Reviewed-by: Emanuele Giuseppe Esposito <eesposit@redhat.com> | ||
15 | Signed-off-by: Kevin Wolf <kwolf@redhat.com> | ||
16 | --- | ||
17 | block/qcow2.h | 5 +++- | ||
18 | block/qed.h | 29 +++++++++++++-------- | ||
19 | include/block/block-io.h | 2 +- | ||
20 | include/block/block_int-common.h | 12 +++++---- | ||
21 | block/blkdebug.c | 2 +- | ||
22 | block/blklogwrites.c | 21 ++++++++++----- | ||
23 | block/blkreplay.c | 2 +- | ||
24 | block/blkverify.c | 2 +- | ||
25 | block/block-backend.c | 3 ++- | ||
26 | block/copy-before-write.c | 2 +- | ||
27 | block/file-posix.c | 4 +-- | ||
28 | block/io.c | 7 +++++ | ||
29 | block/mirror.c | 2 +- | ||
30 | block/preallocate.c | 2 +- | ||
31 | block/qed-check.c | 3 ++- | ||
32 | block/qed-table.c | 6 ++--- | ||
33 | block/qed.c | 44 +++++++++++++++++++------------- | ||
34 | block/quorum.c | 2 +- | ||
35 | block/throttle.c | 2 +- | ||
36 | block/vmdk.c | 6 +++-- | ||
37 | 20 files changed, 98 insertions(+), 60 deletions(-) | ||
38 | |||
39 | diff --git a/block/qcow2.h b/block/qcow2.h | ||
40 | index XXXXXXX..XXXXXXX 100644 | ||
41 | --- a/block/qcow2.h | ||
42 | +++ b/block/qcow2.h | ||
43 | @@ -XXX,XX +XXX,XX @@ int coroutine_fn qcow2_detect_metadata_preallocation(BlockDriverState *bs); | ||
44 | /* qcow2-cluster.c functions */ | ||
45 | int qcow2_grow_l1_table(BlockDriverState *bs, uint64_t min_size, | ||
46 | bool exact_size); | ||
47 | -int coroutine_fn qcow2_shrink_l1_table(BlockDriverState *bs, uint64_t max_size); | ||
48 | + | ||
49 | +int coroutine_fn GRAPH_RDLOCK | ||
50 | +qcow2_shrink_l1_table(BlockDriverState *bs, uint64_t max_size); | ||
51 | + | ||
52 | int qcow2_write_l1_entry(BlockDriverState *bs, int l1_index); | ||
53 | int qcow2_encrypt_sectors(BDRVQcow2State *s, int64_t sector_num, | ||
54 | uint8_t *buf, int nb_sectors, bool enc, Error **errp); | ||
55 | diff --git a/block/qed.h b/block/qed.h | ||
56 | index XXXXXXX..XXXXXXX 100644 | ||
57 | --- a/block/qed.h | ||
58 | +++ b/block/qed.h | ||
59 | @@ -XXX,XX +XXX,XX @@ void qed_commit_l2_cache_entry(L2TableCache *l2_cache, CachedL2Table *l2_table); | ||
60 | * Table I/O functions | ||
61 | */ | ||
62 | int coroutine_fn qed_read_l1_table_sync(BDRVQEDState *s); | ||
63 | -int coroutine_fn qed_write_l1_table(BDRVQEDState *s, unsigned int index, | ||
64 | - unsigned int n); | ||
65 | -int coroutine_fn qed_write_l1_table_sync(BDRVQEDState *s, unsigned int index, | ||
66 | - unsigned int n); | ||
67 | + | ||
68 | +int coroutine_fn GRAPH_RDLOCK | ||
69 | +qed_write_l1_table(BDRVQEDState *s, unsigned int index, unsigned int n); | ||
70 | + | ||
71 | +int coroutine_fn GRAPH_RDLOCK | ||
72 | +qed_write_l1_table_sync(BDRVQEDState *s, unsigned int index, unsigned int n); | ||
73 | + | ||
74 | int coroutine_fn qed_read_l2_table_sync(BDRVQEDState *s, QEDRequest *request, | ||
75 | uint64_t offset); | ||
76 | int coroutine_fn qed_read_l2_table(BDRVQEDState *s, QEDRequest *request, | ||
77 | uint64_t offset); | ||
78 | -int coroutine_fn qed_write_l2_table(BDRVQEDState *s, QEDRequest *request, | ||
79 | - unsigned int index, unsigned int n, | ||
80 | - bool flush); | ||
81 | -int coroutine_fn qed_write_l2_table_sync(BDRVQEDState *s, QEDRequest *request, | ||
82 | - unsigned int index, unsigned int n, | ||
83 | - bool flush); | ||
84 | + | ||
85 | +int coroutine_fn GRAPH_RDLOCK | ||
86 | +qed_write_l2_table(BDRVQEDState *s, QEDRequest *request, unsigned int index, | ||
87 | + unsigned int n, bool flush); | ||
88 | + | ||
89 | +int coroutine_fn GRAPH_RDLOCK | ||
90 | +qed_write_l2_table_sync(BDRVQEDState *s, QEDRequest *request, | ||
91 | + unsigned int index, unsigned int n, bool flush); | ||
92 | |||
93 | /** | ||
94 | * Cluster functions | ||
95 | @@ -XXX,XX +XXX,XX @@ int coroutine_fn qed_find_cluster(BDRVQEDState *s, QEDRequest *request, | ||
96 | /** | ||
97 | * Consistency check | ||
98 | */ | ||
99 | -int coroutine_fn qed_check(BDRVQEDState *s, BdrvCheckResult *result, bool fix); | ||
100 | +int coroutine_fn GRAPH_RDLOCK | ||
101 | +qed_check(BDRVQEDState *s, BdrvCheckResult *result, bool fix); | ||
102 | + | ||
103 | |||
104 | QEDTable *qed_alloc_table(BDRVQEDState *s); | ||
105 | |||
106 | diff --git a/include/block/block-io.h b/include/block/block-io.h | ||
107 | index XXXXXXX..XXXXXXX 100644 | ||
108 | --- a/include/block/block-io.h | ||
109 | +++ b/include/block/block-io.h | ||
110 | @@ -XXX,XX +XXX,XX @@ int coroutine_fn GRAPH_RDLOCK | ||
111 | bdrv_co_ioctl(BlockDriverState *bs, int req, void *buf); | ||
112 | |||
113 | /* Ensure contents are flushed to disk. */ | ||
114 | -int coroutine_fn bdrv_co_flush(BlockDriverState *bs); | ||
115 | +int coroutine_fn GRAPH_RDLOCK bdrv_co_flush(BlockDriverState *bs); | ||
116 | |||
117 | int coroutine_fn bdrv_co_pdiscard(BdrvChild *child, int64_t offset, | ||
118 | int64_t bytes); | ||
119 | diff --git a/include/block/block_int-common.h b/include/block/block_int-common.h | ||
120 | index XXXXXXX..XXXXXXX 100644 | ||
121 | --- a/include/block/block_int-common.h | ||
122 | +++ b/include/block/block_int-common.h | ||
123 | @@ -XXX,XX +XXX,XX @@ struct BlockDriver { | ||
124 | BlockAIOCB *(*bdrv_aio_pwritev)(BlockDriverState *bs, | ||
125 | int64_t offset, int64_t bytes, QEMUIOVector *qiov, | ||
126 | BdrvRequestFlags flags, BlockCompletionFunc *cb, void *opaque); | ||
127 | - BlockAIOCB *(*bdrv_aio_flush)(BlockDriverState *bs, | ||
128 | - BlockCompletionFunc *cb, void *opaque); | ||
129 | + BlockAIOCB * GRAPH_RDLOCK_PTR (*bdrv_aio_flush)( | ||
130 | + BlockDriverState *bs, BlockCompletionFunc *cb, void *opaque); | ||
131 | BlockAIOCB *(*bdrv_aio_pdiscard)(BlockDriverState *bs, | ||
132 | int64_t offset, int bytes, | ||
133 | BlockCompletionFunc *cb, void *opaque); | ||
134 | @@ -XXX,XX +XXX,XX @@ struct BlockDriver { | ||
135 | * layers, if needed. This function is needed for deterministic | ||
136 | * synchronization of the flush finishing callback. | ||
137 | */ | ||
138 | - int coroutine_fn (*bdrv_co_flush)(BlockDriverState *bs); | ||
139 | + int coroutine_fn GRAPH_RDLOCK_PTR (*bdrv_co_flush)(BlockDriverState *bs); | ||
140 | |||
141 | /* Delete a created file. */ | ||
142 | int coroutine_fn (*bdrv_co_delete_file)(BlockDriverState *bs, | ||
143 | @@ -XXX,XX +XXX,XX @@ struct BlockDriver { | ||
144 | * Flushes all data that was already written to the OS all the way down to | ||
145 | * the disk (for example file-posix.c calls fsync()). | ||
146 | */ | ||
147 | - int coroutine_fn (*bdrv_co_flush_to_disk)(BlockDriverState *bs); | ||
148 | + int coroutine_fn GRAPH_RDLOCK_PTR (*bdrv_co_flush_to_disk)( | ||
149 | + BlockDriverState *bs); | ||
150 | |||
151 | /* | ||
152 | * Flushes all internal caches to the OS. The data may still sit in a | ||
153 | * writeback cache of the host OS, but it will survive a crash of the qemu | ||
154 | * process. | ||
155 | */ | ||
156 | - int coroutine_fn (*bdrv_co_flush_to_os)(BlockDriverState *bs); | ||
157 | + int coroutine_fn GRAPH_RDLOCK_PTR (*bdrv_co_flush_to_os)( | ||
158 | + BlockDriverState *bs); | ||
159 | |||
160 | /* | ||
161 | * Truncate @bs to @offset bytes using the given @prealloc mode | ||
162 | diff --git a/block/blkdebug.c b/block/blkdebug.c | ||
163 | index XXXXXXX..XXXXXXX 100644 | ||
164 | --- a/block/blkdebug.c | ||
165 | +++ b/block/blkdebug.c | ||
166 | @@ -XXX,XX +XXX,XX @@ blkdebug_co_pwritev(BlockDriverState *bs, int64_t offset, int64_t bytes, | ||
167 | return bdrv_co_pwritev(bs->file, offset, bytes, qiov, flags); | ||
168 | } | ||
169 | |||
170 | -static int coroutine_fn blkdebug_co_flush(BlockDriverState *bs) | ||
171 | +static int GRAPH_RDLOCK coroutine_fn blkdebug_co_flush(BlockDriverState *bs) | ||
172 | { | ||
173 | int err = rule_check(bs, 0, 0, BLKDEBUG_IO_TYPE_FLUSH); | ||
174 | |||
175 | diff --git a/block/blklogwrites.c b/block/blklogwrites.c | ||
176 | index XXXXXXX..XXXXXXX 100644 | ||
177 | --- a/block/blklogwrites.c | ||
178 | +++ b/block/blklogwrites.c | ||
179 | @@ -XXX,XX +XXX,XX @@ typedef struct BlkLogWritesFileReq { | ||
180 | uint64_t bytes; | ||
181 | int file_flags; | ||
182 | QEMUIOVector *qiov; | ||
183 | - int (*func)(struct BlkLogWritesFileReq *r); | ||
184 | + int GRAPH_RDLOCK_PTR (*func)(struct BlkLogWritesFileReq *r); | ||
185 | int file_ret; | ||
186 | } BlkLogWritesFileReq; | ||
187 | |||
188 | @@ -XXX,XX +XXX,XX @@ typedef struct { | ||
189 | int log_ret; | ||
190 | } BlkLogWritesLogReq; | ||
191 | |||
192 | -static void coroutine_fn blk_log_writes_co_do_log(BlkLogWritesLogReq *lr) | ||
193 | +static void coroutine_fn GRAPH_RDLOCK | ||
194 | +blk_log_writes_co_do_log(BlkLogWritesLogReq *lr) | ||
195 | { | ||
196 | BDRVBlkLogWritesState *s = lr->bs->opaque; | ||
197 | uint64_t cur_log_offset = s->cur_log_sector << s->sectorbits; | ||
198 | @@ -XXX,XX +XXX,XX @@ static void coroutine_fn blk_log_writes_co_do_log(BlkLogWritesLogReq *lr) | ||
199 | } | ||
200 | } | ||
201 | |||
202 | -static void coroutine_fn blk_log_writes_co_do_file(BlkLogWritesFileReq *fr) | ||
203 | +static void coroutine_fn GRAPH_RDLOCK | ||
204 | +blk_log_writes_co_do_file(BlkLogWritesFileReq *fr) | ||
205 | { | ||
206 | fr->file_ret = fr->func(fr); | ||
207 | } | ||
208 | |||
209 | -static int coroutine_fn | ||
210 | +static int coroutine_fn GRAPH_RDLOCK | ||
211 | blk_log_writes_co_log(BlockDriverState *bs, uint64_t offset, uint64_t bytes, | ||
212 | QEMUIOVector *qiov, int flags, | ||
213 | - int (*file_func)(BlkLogWritesFileReq *r), | ||
214 | + int /*GRAPH_RDLOCK*/ (*file_func)(BlkLogWritesFileReq *r), | ||
215 | uint64_t entry_flags, bool is_zero_write) | ||
216 | { | ||
217 | QEMUIOVector log_qiov; | ||
218 | @@ -XXX,XX +XXX,XX @@ blk_log_writes_co_do_file_pwrite_zeroes(BlkLogWritesFileReq *fr) | ||
219 | fr->file_flags); | ||
220 | } | ||
221 | |||
222 | -static int coroutine_fn blk_log_writes_co_do_file_flush(BlkLogWritesFileReq *fr) | ||
223 | +static int coroutine_fn GRAPH_RDLOCK | ||
224 | +blk_log_writes_co_do_file_flush(BlkLogWritesFileReq *fr) | ||
225 | { | ||
226 | return bdrv_co_flush(fr->bs->file->bs); | ||
227 | } | ||
228 | @@ -XXX,XX +XXX,XX @@ static int coroutine_fn | ||
229 | blk_log_writes_co_pwritev(BlockDriverState *bs, int64_t offset, int64_t bytes, | ||
230 | QEMUIOVector *qiov, BdrvRequestFlags flags) | ||
231 | { | ||
232 | + assume_graph_lock(); /* FIXME */ | ||
233 | return blk_log_writes_co_log(bs, offset, bytes, qiov, flags, | ||
234 | blk_log_writes_co_do_file_pwritev, 0, false); | ||
235 | } | ||
236 | @@ -XXX,XX +XXX,XX @@ static int coroutine_fn | ||
237 | blk_log_writes_co_pwrite_zeroes(BlockDriverState *bs, int64_t offset, | ||
238 | int64_t bytes, BdrvRequestFlags flags) | ||
239 | { | ||
240 | + assume_graph_lock(); /* FIXME */ | ||
241 | return blk_log_writes_co_log(bs, offset, bytes, NULL, flags, | ||
242 | blk_log_writes_co_do_file_pwrite_zeroes, 0, | ||
243 | true); | ||
244 | } | ||
245 | |||
246 | -static int coroutine_fn blk_log_writes_co_flush_to_disk(BlockDriverState *bs) | ||
247 | +static int coroutine_fn GRAPH_RDLOCK | ||
248 | +blk_log_writes_co_flush_to_disk(BlockDriverState *bs) | ||
249 | { | ||
250 | return blk_log_writes_co_log(bs, 0, 0, NULL, 0, | ||
251 | blk_log_writes_co_do_file_flush, | ||
252 | @@ -XXX,XX +XXX,XX @@ static int coroutine_fn blk_log_writes_co_flush_to_disk(BlockDriverState *bs) | ||
253 | static int coroutine_fn | ||
254 | blk_log_writes_co_pdiscard(BlockDriverState *bs, int64_t offset, int64_t bytes) | ||
255 | { | ||
256 | + assume_graph_lock(); /* FIXME */ | ||
257 | return blk_log_writes_co_log(bs, offset, bytes, NULL, 0, | ||
258 | blk_log_writes_co_do_file_pdiscard, | ||
259 | LOG_DISCARD_FLAG, false); | ||
260 | diff --git a/block/blkreplay.c b/block/blkreplay.c | ||
261 | index XXXXXXX..XXXXXXX 100644 | ||
262 | --- a/block/blkreplay.c | ||
263 | +++ b/block/blkreplay.c | ||
264 | @@ -XXX,XX +XXX,XX @@ static int coroutine_fn blkreplay_co_pdiscard(BlockDriverState *bs, | ||
265 | return ret; | ||
266 | } | ||
267 | |||
268 | -static int coroutine_fn blkreplay_co_flush(BlockDriverState *bs) | ||
269 | +static int coroutine_fn GRAPH_RDLOCK blkreplay_co_flush(BlockDriverState *bs) | ||
270 | { | ||
271 | uint64_t reqid = blkreplay_next_id(); | ||
272 | int ret = bdrv_co_flush(bs->file->bs); | ||
273 | diff --git a/block/blkverify.c b/block/blkverify.c | ||
274 | index XXXXXXX..XXXXXXX 100644 | ||
275 | --- a/block/blkverify.c | ||
276 | +++ b/block/blkverify.c | ||
277 | @@ -XXX,XX +XXX,XX @@ blkverify_co_pwritev(BlockDriverState *bs, int64_t offset, int64_t bytes, | ||
278 | return blkverify_co_prwv(bs, &r, offset, bytes, qiov, qiov, flags, true); | ||
279 | } | ||
280 | |||
281 | -static int coroutine_fn blkverify_co_flush(BlockDriverState *bs) | ||
282 | +static int coroutine_fn GRAPH_RDLOCK blkverify_co_flush(BlockDriverState *bs) | ||
283 | { | ||
284 | BDRVBlkverifyState *s = bs->opaque; | ||
285 | |||
286 | diff --git a/block/block-backend.c b/block/block-backend.c | ||
287 | index XXXXXXX..XXXXXXX 100644 | ||
288 | --- a/block/block-backend.c | ||
289 | +++ b/block/block-backend.c | ||
290 | @@ -XXX,XX +XXX,XX @@ int coroutine_fn blk_co_pdiscard(BlockBackend *blk, int64_t offset, | ||
291 | /* To be called between exactly one pair of blk_inc/dec_in_flight() */ | ||
292 | static int coroutine_fn blk_co_do_flush(BlockBackend *blk) | ||
293 | { | ||
294 | - blk_wait_while_drained(blk); | ||
295 | IO_CODE(); | ||
296 | + blk_wait_while_drained(blk); | ||
297 | + GRAPH_RDLOCK_GUARD(); | ||
298 | |||
299 | if (!blk_is_available(blk)) { | ||
300 | return -ENOMEDIUM; | ||
301 | diff --git a/block/copy-before-write.c b/block/copy-before-write.c | ||
302 | index XXXXXXX..XXXXXXX 100644 | ||
303 | --- a/block/copy-before-write.c | ||
304 | +++ b/block/copy-before-write.c | ||
305 | @@ -XXX,XX +XXX,XX @@ static coroutine_fn int cbw_co_pwritev(BlockDriverState *bs, | ||
306 | return bdrv_co_pwritev(bs->file, offset, bytes, qiov, flags); | ||
307 | } | ||
308 | |||
309 | -static int coroutine_fn cbw_co_flush(BlockDriverState *bs) | ||
310 | +static int coroutine_fn GRAPH_RDLOCK cbw_co_flush(BlockDriverState *bs) | ||
311 | { | ||
312 | if (!bs->file) { | ||
313 | return 0; | ||
314 | diff --git a/block/file-posix.c b/block/file-posix.c | ||
315 | index XXXXXXX..XXXXXXX 100644 | ||
316 | --- a/block/file-posix.c | ||
317 | +++ b/block/file-posix.c | ||
318 | @@ -XXX,XX +XXX,XX @@ static void coroutine_fn check_cache_dropped(BlockDriverState *bs, Error **errp) | ||
319 | } | ||
320 | #endif /* __linux__ */ | ||
321 | |||
322 | -static void coroutine_fn raw_co_invalidate_cache(BlockDriverState *bs, | ||
323 | - Error **errp) | ||
324 | +static void coroutine_fn GRAPH_RDLOCK | ||
325 | +raw_co_invalidate_cache(BlockDriverState *bs, Error **errp) | ||
326 | { | ||
327 | BDRVRawState *s = bs->opaque; | ||
328 | int ret; | ||
329 | diff --git a/block/io.c b/block/io.c | ||
330 | index XXXXXXX..XXXXXXX 100644 | ||
331 | --- a/block/io.c | ||
332 | +++ b/block/io.c | ||
333 | @@ -XXX,XX +XXX,XX @@ int coroutine_fn bdrv_co_pwrite_sync(BdrvChild *child, int64_t offset, | ||
334 | int ret; | ||
335 | IO_CODE(); | ||
336 | |||
337 | + assume_graph_lock(); /* FIXME */ | ||
338 | + | ||
339 | ret = bdrv_co_pwrite(child, offset, bytes, buf, flags); | ||
340 | if (ret < 0) { | ||
341 | return ret; | ||
342 | @@ -XXX,XX +XXX,XX @@ static int coroutine_fn bdrv_driver_pwritev(BlockDriverState *bs, | ||
343 | QEMUIOVector local_qiov; | ||
344 | int ret; | ||
345 | |||
346 | + assume_graph_lock(); /* FIXME */ | ||
347 | + | ||
348 | bdrv_check_qiov_request(offset, bytes, qiov, qiov_offset, &error_abort); | ||
349 | |||
350 | if (!drv) { | ||
351 | @@ -XXX,XX +XXX,XX @@ static int coroutine_fn bdrv_co_do_pwrite_zeroes(BlockDriverState *bs, | ||
352 | int head = 0; | ||
353 | int tail = 0; | ||
354 | |||
355 | + assume_graph_lock(); /* FIXME */ | ||
356 | + | ||
357 | int64_t max_write_zeroes = MIN_NON_ZERO(bs->bl.max_pwrite_zeroes, | ||
358 | INT64_MAX); | ||
359 | int alignment = MAX(bs->bl.pwrite_zeroes_alignment, | ||
360 | @@ -XXX,XX +XXX,XX @@ int coroutine_fn bdrv_co_flush(BlockDriverState *bs) | ||
361 | int ret = 0; | ||
362 | IO_CODE(); | ||
363 | |||
364 | + assert_bdrv_graph_readable(); | ||
365 | bdrv_inc_in_flight(bs); | ||
366 | |||
367 | if (!bdrv_co_is_inserted(bs) || bdrv_is_read_only(bs) || | ||
368 | diff --git a/block/mirror.c b/block/mirror.c | ||
369 | index XXXXXXX..XXXXXXX 100644 | ||
370 | --- a/block/mirror.c | ||
371 | +++ b/block/mirror.c | ||
372 | @@ -XXX,XX +XXX,XX @@ static int coroutine_fn bdrv_mirror_top_pwritev(BlockDriverState *bs, | ||
373 | return ret; | ||
374 | } | ||
375 | |||
376 | -static int coroutine_fn bdrv_mirror_top_flush(BlockDriverState *bs) | ||
377 | +static int coroutine_fn GRAPH_RDLOCK bdrv_mirror_top_flush(BlockDriverState *bs) | ||
378 | { | ||
379 | if (bs->backing == NULL) { | ||
380 | /* we can be here after failed bdrv_append in mirror_start_job */ | ||
381 | diff --git a/block/preallocate.c b/block/preallocate.c | ||
382 | index XXXXXXX..XXXXXXX 100644 | ||
383 | --- a/block/preallocate.c | ||
384 | +++ b/block/preallocate.c | ||
385 | @@ -XXX,XX +XXX,XX @@ preallocate_co_truncate(BlockDriverState *bs, int64_t offset, | ||
386 | return 0; | ||
387 | } | ||
388 | |||
389 | -static int coroutine_fn preallocate_co_flush(BlockDriverState *bs) | ||
390 | +static int coroutine_fn GRAPH_RDLOCK preallocate_co_flush(BlockDriverState *bs) | ||
391 | { | ||
392 | return bdrv_co_flush(bs->file->bs); | ||
393 | } | ||
394 | diff --git a/block/qed-check.c b/block/qed-check.c | ||
395 | index XXXXXXX..XXXXXXX 100644 | ||
396 | --- a/block/qed-check.c | ||
397 | +++ b/block/qed-check.c | ||
398 | @@ -XXX,XX +XXX,XX @@ static unsigned int qed_check_l2_table(QEDCheck *check, QEDTable *table) | ||
399 | /** | ||
400 | * Descend tables and check each cluster is referenced once only | ||
401 | */ | ||
402 | -static int coroutine_fn qed_check_l1_table(QEDCheck *check, QEDTable *table) | ||
403 | +static int coroutine_fn GRAPH_RDLOCK | ||
404 | +qed_check_l1_table(QEDCheck *check, QEDTable *table) | ||
405 | { | ||
406 | BDRVQEDState *s = check->s; | ||
407 | unsigned int i, num_invalid_l1 = 0; | ||
408 | diff --git a/block/qed-table.c b/block/qed-table.c | ||
409 | index XXXXXXX..XXXXXXX 100644 | ||
410 | --- a/block/qed-table.c | ||
411 | +++ b/block/qed-table.c | ||
412 | @@ -XXX,XX +XXX,XX @@ out: | ||
413 | * | ||
414 | * Called with table_lock held. | ||
415 | */ | ||
416 | -static int coroutine_fn qed_write_table(BDRVQEDState *s, uint64_t offset, | ||
417 | - QEDTable *table, unsigned int index, | ||
418 | - unsigned int n, bool flush) | ||
419 | +static int coroutine_fn GRAPH_RDLOCK | ||
420 | +qed_write_table(BDRVQEDState *s, uint64_t offset, QEDTable *table, | ||
421 | + unsigned int index, unsigned int n, bool flush) | ||
422 | { | ||
423 | unsigned int sector_mask = BDRV_SECTOR_SIZE / sizeof(uint64_t) - 1; | ||
424 | unsigned int start, end, i; | ||
425 | diff --git a/block/qed.c b/block/qed.c | ||
426 | index XXXXXXX..XXXXXXX 100644 | ||
427 | --- a/block/qed.c | ||
428 | +++ b/block/qed.c | ||
429 | @@ -XXX,XX +XXX,XX @@ static void bdrv_qed_init_state(BlockDriverState *bs) | ||
430 | } | ||
431 | |||
432 | /* Called with table_lock held. */ | ||
433 | -static int coroutine_fn bdrv_qed_do_open(BlockDriverState *bs, QDict *options, | ||
434 | - int flags, Error **errp) | ||
435 | +static int coroutine_fn GRAPH_RDLOCK | ||
436 | +bdrv_qed_do_open(BlockDriverState *bs, QDict *options, int flags, Error **errp) | ||
437 | { | ||
438 | BDRVQEDState *s = bs->opaque; | ||
439 | QEDHeader le_header; | ||
440 | @@ -XXX,XX +XXX,XX @@ typedef struct QEDOpenCo { | ||
441 | int ret; | ||
442 | } QEDOpenCo; | ||
443 | |||
444 | -static void coroutine_fn bdrv_qed_open_entry(void *opaque) | ||
445 | +static void coroutine_fn GRAPH_RDLOCK bdrv_qed_open_entry(void *opaque) | ||
446 | { | ||
447 | QEDOpenCo *qoc = opaque; | ||
448 | BDRVQEDState *s = qoc->bs->opaque; | ||
449 | @@ -XXX,XX +XXX,XX @@ static int bdrv_qed_open(BlockDriverState *bs, QDict *options, int flags, | ||
450 | }; | ||
451 | int ret; | ||
452 | |||
453 | + assume_graph_lock(); /* FIXME */ | ||
454 | + | ||
455 | ret = bdrv_open_file_child(NULL, options, "file", bs, errp); | ||
456 | if (ret < 0) { | ||
457 | return ret; | ||
458 | @@ -XXX,XX +XXX,XX @@ static void coroutine_fn qed_aio_complete(QEDAIOCB *acb) | ||
459 | * | ||
460 | * Called with table_lock held. | ||
461 | */ | ||
462 | -static int coroutine_fn qed_aio_write_l1_update(QEDAIOCB *acb) | ||
463 | +static int coroutine_fn GRAPH_RDLOCK qed_aio_write_l1_update(QEDAIOCB *acb) | ||
464 | { | ||
465 | BDRVQEDState *s = acb_to_s(acb); | ||
466 | CachedL2Table *l2_table = acb->request.l2_table; | ||
467 | @@ -XXX,XX +XXX,XX @@ static int coroutine_fn qed_aio_write_l1_update(QEDAIOCB *acb) | ||
468 | * | ||
469 | * Called with table_lock held. | ||
470 | */ | ||
471 | -static int coroutine_fn qed_aio_write_l2_update(QEDAIOCB *acb, uint64_t offset) | ||
472 | +static int coroutine_fn GRAPH_RDLOCK | ||
473 | +qed_aio_write_l2_update(QEDAIOCB *acb, uint64_t offset) | ||
474 | { | ||
475 | BDRVQEDState *s = acb_to_s(acb); | ||
476 | bool need_alloc = acb->find_cluster_ret == QED_CLUSTER_L1; | ||
477 | @@ -XXX,XX +XXX,XX @@ static int coroutine_fn qed_aio_write_main(QEDAIOCB *acb) | ||
478 | * | ||
479 | * Called with table_lock held. | ||
480 | */ | ||
481 | -static int coroutine_fn qed_aio_write_cow(QEDAIOCB *acb) | ||
482 | +static int coroutine_fn GRAPH_RDLOCK qed_aio_write_cow(QEDAIOCB *acb) | ||
483 | { | ||
484 | BDRVQEDState *s = acb_to_s(acb); | ||
485 | uint64_t start, len, offset; | ||
486 | @@ -XXX,XX +XXX,XX @@ static bool qed_should_set_need_check(BDRVQEDState *s) | ||
487 | * | ||
488 | * Called with table_lock held. | ||
489 | */ | ||
490 | -static int coroutine_fn qed_aio_write_alloc(QEDAIOCB *acb, size_t len) | ||
491 | +static int coroutine_fn GRAPH_RDLOCK | ||
492 | +qed_aio_write_alloc(QEDAIOCB *acb, size_t len) | ||
493 | { | ||
494 | BDRVQEDState *s = acb_to_s(acb); | ||
495 | int ret; | ||
496 | @@ -XXX,XX +XXX,XX @@ out: | ||
497 | * | ||
498 | * Called with table_lock held. | ||
499 | */ | ||
500 | -static int coroutine_fn qed_aio_write_data(void *opaque, int ret, | ||
501 | - uint64_t offset, size_t len) | ||
502 | +static int coroutine_fn GRAPH_RDLOCK | ||
503 | +qed_aio_write_data(void *opaque, int ret, uint64_t offset, size_t len) | ||
504 | { | ||
505 | QEDAIOCB *acb = opaque; | ||
506 | |||
507 | @@ -XXX,XX +XXX,XX @@ static int coroutine_fn qed_aio_read_data(void *opaque, int ret, | ||
508 | /** | ||
509 | * Begin next I/O or complete the request | ||
510 | */ | ||
511 | -static int coroutine_fn qed_aio_next_io(QEDAIOCB *acb) | ||
512 | +static int coroutine_fn GRAPH_RDLOCK qed_aio_next_io(QEDAIOCB *acb) | ||
513 | { | ||
514 | BDRVQEDState *s = acb_to_s(acb); | ||
515 | uint64_t offset; | ||
516 | @@ -XXX,XX +XXX,XX @@ static int coroutine_fn qed_aio_next_io(QEDAIOCB *acb) | ||
517 | return ret; | ||
518 | } | ||
519 | |||
520 | -static int coroutine_fn qed_co_request(BlockDriverState *bs, int64_t sector_num, | ||
521 | - QEMUIOVector *qiov, int nb_sectors, | ||
522 | - int flags) | ||
523 | +static int coroutine_fn GRAPH_RDLOCK | ||
524 | +qed_co_request(BlockDriverState *bs, int64_t sector_num, QEMUIOVector *qiov, | ||
525 | + int nb_sectors, int flags) | ||
526 | { | ||
527 | QEDAIOCB acb = { | ||
528 | .bs = bs, | ||
529 | @@ -XXX,XX +XXX,XX @@ static int coroutine_fn bdrv_qed_co_readv(BlockDriverState *bs, | ||
530 | int64_t sector_num, int nb_sectors, | ||
531 | QEMUIOVector *qiov) | ||
532 | { | ||
533 | + assume_graph_lock(); /* FIXME */ | ||
534 | return qed_co_request(bs, sector_num, qiov, nb_sectors, 0); | ||
535 | } | ||
536 | |||
537 | @@ -XXX,XX +XXX,XX @@ static int coroutine_fn bdrv_qed_co_writev(BlockDriverState *bs, | ||
538 | int64_t sector_num, int nb_sectors, | ||
539 | QEMUIOVector *qiov, int flags) | ||
540 | { | ||
541 | + assume_graph_lock(); /* FIXME */ | ||
542 | return qed_co_request(bs, sector_num, qiov, nb_sectors, QED_AIOCB_WRITE); | ||
543 | } | ||
544 | |||
545 | @@ -XXX,XX +XXX,XX @@ static int coroutine_fn bdrv_qed_co_pwrite_zeroes(BlockDriverState *bs, | ||
546 | { | ||
547 | BDRVQEDState *s = bs->opaque; | ||
548 | |||
549 | + assume_graph_lock(); /* FIXME */ | ||
550 | + | ||
551 | /* | ||
552 | * Zero writes start without an I/O buffer. If a buffer becomes necessary | ||
553 | * then it will be allocated during request processing. | ||
554 | @@ -XXX,XX +XXX,XX @@ static int bdrv_qed_change_backing_file(BlockDriverState *bs, | ||
555 | return ret; | ||
556 | } | ||
557 | |||
558 | -static void coroutine_fn bdrv_qed_co_invalidate_cache(BlockDriverState *bs, | ||
559 | - Error **errp) | ||
560 | +static void coroutine_fn GRAPH_RDLOCK | ||
561 | +bdrv_qed_co_invalidate_cache(BlockDriverState *bs, Error **errp) | ||
562 | { | ||
563 | BDRVQEDState *s = bs->opaque; | ||
564 | int ret; | ||
565 | @@ -XXX,XX +XXX,XX @@ static void coroutine_fn bdrv_qed_co_invalidate_cache(BlockDriverState *bs, | ||
566 | } | ||
567 | } | ||
568 | |||
569 | -static int coroutine_fn bdrv_qed_co_check(BlockDriverState *bs, | ||
570 | - BdrvCheckResult *result, | ||
571 | - BdrvCheckMode fix) | ||
572 | +static int coroutine_fn GRAPH_RDLOCK | ||
573 | +bdrv_qed_co_check(BlockDriverState *bs, BdrvCheckResult *result, | ||
574 | + BdrvCheckMode fix) | ||
575 | { | ||
576 | BDRVQEDState *s = bs->opaque; | ||
577 | int ret; | ||
578 | diff --git a/block/quorum.c b/block/quorum.c | ||
579 | index XXXXXXX..XXXXXXX 100644 | ||
580 | --- a/block/quorum.c | ||
581 | +++ b/block/quorum.c | ||
582 | @@ -XXX,XX +XXX,XX @@ static int64_t coroutine_fn quorum_co_getlength(BlockDriverState *bs) | ||
583 | return result; | ||
584 | } | ||
585 | |||
586 | -static coroutine_fn int quorum_co_flush(BlockDriverState *bs) | ||
587 | +static coroutine_fn GRAPH_RDLOCK int quorum_co_flush(BlockDriverState *bs) | ||
588 | { | ||
589 | BDRVQuorumState *s = bs->opaque; | ||
590 | QuorumVoteVersion *winner = NULL; | ||
591 | diff --git a/block/throttle.c b/block/throttle.c | ||
592 | index XXXXXXX..XXXXXXX 100644 | ||
593 | --- a/block/throttle.c | ||
594 | +++ b/block/throttle.c | ||
595 | @@ -XXX,XX +XXX,XX @@ static int coroutine_fn throttle_co_pwritev_compressed(BlockDriverState *bs, | ||
596 | BDRV_REQ_WRITE_COMPRESSED); | ||
597 | } | ||
598 | |||
599 | -static int coroutine_fn throttle_co_flush(BlockDriverState *bs) | ||
600 | +static int coroutine_fn GRAPH_RDLOCK throttle_co_flush(BlockDriverState *bs) | ||
601 | { | ||
602 | return bdrv_co_flush(bs->file->bs); | ||
603 | } | ||
604 | diff --git a/block/vmdk.c b/block/vmdk.c | ||
605 | index XXXXXXX..XXXXXXX 100644 | ||
606 | --- a/block/vmdk.c | ||
607 | +++ b/block/vmdk.c | ||
608 | @@ -XXX,XX +XXX,XX @@ exit: | ||
609 | return ret; | ||
610 | } | ||
611 | |||
612 | -static int coroutine_fn vmdk_L2update(VmdkExtent *extent, VmdkMetaData *m_data, | ||
613 | - uint32_t offset) | ||
614 | +static int coroutine_fn GRAPH_RDLOCK | ||
615 | +vmdk_L2update(VmdkExtent *extent, VmdkMetaData *m_data, uint32_t offset) | ||
616 | { | ||
617 | offset = cpu_to_le32(offset); | ||
618 | /* update L2 table */ | ||
619 | @@ -XXX,XX +XXX,XX @@ static int coroutine_fn vmdk_pwritev(BlockDriverState *bs, uint64_t offset, | ||
620 | uint64_t bytes_done = 0; | ||
621 | VmdkMetaData m_data; | ||
622 | |||
623 | + assume_graph_lock(); /* FIXME */ | ||
624 | + | ||
625 | if (DIV_ROUND_UP(offset, BDRV_SECTOR_SIZE) > bs->total_sectors) { | ||
626 | error_report("Wrong offset: offset=0x%" PRIx64 | ||
627 | " total_sectors=0x%" PRIx64, | ||
628 | -- | ||
629 | 2.39.2 | diff view generated by jsdifflib |
Deleted patch | |||
---|---|---|---|
1 | From: Emanuele Giuseppe Esposito <eesposit@redhat.com> | ||
2 | 1 | ||
3 | This adds GRAPH_RDLOCK annotations to declare that callers of | ||
4 | bdrv_co_pdiscard() need to hold a reader lock for the graph. | ||
5 | |||
6 | For some places, we know that they will hold the lock, but we don't have | ||
7 | the GRAPH_RDLOCK annotations yet. In this case, add assume_graph_lock() | ||
8 | with a FIXME comment. These places will be removed once everything is | ||
9 | properly annotated. | ||
10 | |||
11 | Signed-off-by: Kevin Wolf <kwolf@redhat.com> | ||
12 | Message-Id: <20230203152202.49054-9-kwolf@redhat.com> | ||
13 | Reviewed-by: Emanuele Giuseppe Esposito <eesposit@redhat.com> | ||
14 | Signed-off-by: Kevin Wolf <kwolf@redhat.com> | ||
15 | --- | ||
16 | include/block/block-io.h | 5 +++-- | ||
17 | include/block/block_int-common.h | 15 +++++++++------ | ||
18 | include/block/block_int-io.h | 2 +- | ||
19 | block/blkdebug.c | 4 ++-- | ||
20 | block/blklogwrites.c | 5 ++--- | ||
21 | block/blkreplay.c | 4 ++-- | ||
22 | block/block-backend.c | 1 + | ||
23 | block/copy-before-write.c | 8 ++++---- | ||
24 | block/copy-on-read.c | 4 ++-- | ||
25 | block/filter-compress.c | 4 ++-- | ||
26 | block/io.c | 2 ++ | ||
27 | block/mirror.c | 14 +++++++++----- | ||
28 | block/preallocate.c | 4 ++-- | ||
29 | block/raw-format.c | 4 ++-- | ||
30 | block/snapshot-access.c | 4 ++-- | ||
31 | block/throttle.c | 4 ++-- | ||
32 | 16 files changed, 47 insertions(+), 37 deletions(-) | ||
33 | |||
34 | diff --git a/include/block/block-io.h b/include/block/block-io.h | ||
35 | index XXXXXXX..XXXXXXX 100644 | ||
36 | --- a/include/block/block-io.h | ||
37 | +++ b/include/block/block-io.h | ||
38 | @@ -XXX,XX +XXX,XX @@ bdrv_co_ioctl(BlockDriverState *bs, int req, void *buf); | ||
39 | /* Ensure contents are flushed to disk. */ | ||
40 | int coroutine_fn GRAPH_RDLOCK bdrv_co_flush(BlockDriverState *bs); | ||
41 | |||
42 | -int coroutine_fn bdrv_co_pdiscard(BdrvChild *child, int64_t offset, | ||
43 | - int64_t bytes); | ||
44 | +int coroutine_fn GRAPH_RDLOCK bdrv_co_pdiscard(BdrvChild *child, int64_t offset, | ||
45 | + int64_t bytes); | ||
46 | + | ||
47 | bool bdrv_can_write_zeroes_with_unmap(BlockDriverState *bs); | ||
48 | int bdrv_block_status(BlockDriverState *bs, int64_t offset, | ||
49 | int64_t bytes, int64_t *pnum, int64_t *map, | ||
50 | diff --git a/include/block/block_int-common.h b/include/block/block_int-common.h | ||
51 | index XXXXXXX..XXXXXXX 100644 | ||
52 | --- a/include/block/block_int-common.h | ||
53 | +++ b/include/block/block_int-common.h | ||
54 | @@ -XXX,XX +XXX,XX @@ struct BlockDriver { | ||
55 | BdrvRequestFlags flags, BlockCompletionFunc *cb, void *opaque); | ||
56 | BlockAIOCB * GRAPH_RDLOCK_PTR (*bdrv_aio_flush)( | ||
57 | BlockDriverState *bs, BlockCompletionFunc *cb, void *opaque); | ||
58 | - BlockAIOCB *(*bdrv_aio_pdiscard)(BlockDriverState *bs, | ||
59 | - int64_t offset, int bytes, | ||
60 | + | ||
61 | + BlockAIOCB * GRAPH_RDLOCK_PTR (*bdrv_aio_pdiscard)( | ||
62 | + BlockDriverState *bs, int64_t offset, int bytes, | ||
63 | BlockCompletionFunc *cb, void *opaque); | ||
64 | |||
65 | int coroutine_fn (*bdrv_co_readv)(BlockDriverState *bs, | ||
66 | @@ -XXX,XX +XXX,XX @@ struct BlockDriver { | ||
67 | */ | ||
68 | int coroutine_fn (*bdrv_co_pwrite_zeroes)(BlockDriverState *bs, | ||
69 | int64_t offset, int64_t bytes, BdrvRequestFlags flags); | ||
70 | - int coroutine_fn (*bdrv_co_pdiscard)(BlockDriverState *bs, | ||
71 | - int64_t offset, int64_t bytes); | ||
72 | + | ||
73 | + int coroutine_fn GRAPH_RDLOCK_PTR (*bdrv_co_pdiscard)( | ||
74 | + BlockDriverState *bs, int64_t offset, int64_t bytes); | ||
75 | |||
76 | /* | ||
77 | * Map [offset, offset + nbytes) range onto a child of @bs to copy from, | ||
78 | @@ -XXX,XX +XXX,XX @@ struct BlockDriver { | ||
79 | int coroutine_fn (*bdrv_co_snapshot_block_status)(BlockDriverState *bs, | ||
80 | bool want_zero, int64_t offset, int64_t bytes, int64_t *pnum, | ||
81 | int64_t *map, BlockDriverState **file); | ||
82 | - int coroutine_fn (*bdrv_co_pdiscard_snapshot)(BlockDriverState *bs, | ||
83 | - int64_t offset, int64_t bytes); | ||
84 | + | ||
85 | + int coroutine_fn GRAPH_RDLOCK_PTR (*bdrv_co_pdiscard_snapshot)( | ||
86 | + BlockDriverState *bs, int64_t offset, int64_t bytes); | ||
87 | |||
88 | /* | ||
89 | * Invalidate any cached meta-data. | ||
90 | diff --git a/include/block/block_int-io.h b/include/block/block_int-io.h | ||
91 | index XXXXXXX..XXXXXXX 100644 | ||
92 | --- a/include/block/block_int-io.h | ||
93 | +++ b/include/block/block_int-io.h | ||
94 | @@ -XXX,XX +XXX,XX @@ int coroutine_fn bdrv_co_preadv_snapshot(BdrvChild *child, | ||
95 | int coroutine_fn bdrv_co_snapshot_block_status(BlockDriverState *bs, | ||
96 | bool want_zero, int64_t offset, int64_t bytes, int64_t *pnum, | ||
97 | int64_t *map, BlockDriverState **file); | ||
98 | -int coroutine_fn bdrv_co_pdiscard_snapshot(BlockDriverState *bs, | ||
99 | +int coroutine_fn GRAPH_RDLOCK bdrv_co_pdiscard_snapshot(BlockDriverState *bs, | ||
100 | int64_t offset, int64_t bytes); | ||
101 | |||
102 | |||
103 | diff --git a/block/blkdebug.c b/block/blkdebug.c | ||
104 | index XXXXXXX..XXXXXXX 100644 | ||
105 | --- a/block/blkdebug.c | ||
106 | +++ b/block/blkdebug.c | ||
107 | @@ -XXX,XX +XXX,XX @@ static int coroutine_fn blkdebug_co_pwrite_zeroes(BlockDriverState *bs, | ||
108 | return bdrv_co_pwrite_zeroes(bs->file, offset, bytes, flags); | ||
109 | } | ||
110 | |||
111 | -static int coroutine_fn blkdebug_co_pdiscard(BlockDriverState *bs, | ||
112 | - int64_t offset, int64_t bytes) | ||
113 | +static int coroutine_fn GRAPH_RDLOCK | ||
114 | +blkdebug_co_pdiscard(BlockDriverState *bs, int64_t offset, int64_t bytes) | ||
115 | { | ||
116 | uint32_t align = bs->bl.pdiscard_alignment; | ||
117 | int err; | ||
118 | diff --git a/block/blklogwrites.c b/block/blklogwrites.c | ||
119 | index XXXXXXX..XXXXXXX 100644 | ||
120 | --- a/block/blklogwrites.c | ||
121 | +++ b/block/blklogwrites.c | ||
122 | @@ -XXX,XX +XXX,XX @@ blk_log_writes_co_do_file_flush(BlkLogWritesFileReq *fr) | ||
123 | return bdrv_co_flush(fr->bs->file->bs); | ||
124 | } | ||
125 | |||
126 | -static int coroutine_fn | ||
127 | +static int coroutine_fn GRAPH_RDLOCK | ||
128 | blk_log_writes_co_do_file_pdiscard(BlkLogWritesFileReq *fr) | ||
129 | { | ||
130 | return bdrv_co_pdiscard(fr->bs->file, fr->offset, fr->bytes); | ||
131 | @@ -XXX,XX +XXX,XX @@ blk_log_writes_co_flush_to_disk(BlockDriverState *bs) | ||
132 | LOG_FLUSH_FLAG, false); | ||
133 | } | ||
134 | |||
135 | -static int coroutine_fn | ||
136 | +static int coroutine_fn GRAPH_RDLOCK | ||
137 | blk_log_writes_co_pdiscard(BlockDriverState *bs, int64_t offset, int64_t bytes) | ||
138 | { | ||
139 | - assume_graph_lock(); /* FIXME */ | ||
140 | return blk_log_writes_co_log(bs, offset, bytes, NULL, 0, | ||
141 | blk_log_writes_co_do_file_pdiscard, | ||
142 | LOG_DISCARD_FLAG, false); | ||
143 | diff --git a/block/blkreplay.c b/block/blkreplay.c | ||
144 | index XXXXXXX..XXXXXXX 100644 | ||
145 | --- a/block/blkreplay.c | ||
146 | +++ b/block/blkreplay.c | ||
147 | @@ -XXX,XX +XXX,XX @@ static int coroutine_fn blkreplay_co_pwrite_zeroes(BlockDriverState *bs, | ||
148 | return ret; | ||
149 | } | ||
150 | |||
151 | -static int coroutine_fn blkreplay_co_pdiscard(BlockDriverState *bs, | ||
152 | - int64_t offset, int64_t bytes) | ||
153 | +static int coroutine_fn GRAPH_RDLOCK | ||
154 | +blkreplay_co_pdiscard(BlockDriverState *bs, int64_t offset, int64_t bytes) | ||
155 | { | ||
156 | uint64_t reqid = blkreplay_next_id(); | ||
157 | int ret = bdrv_co_pdiscard(bs->file, offset, bytes); | ||
158 | diff --git a/block/block-backend.c b/block/block-backend.c | ||
159 | index XXXXXXX..XXXXXXX 100644 | ||
160 | --- a/block/block-backend.c | ||
161 | +++ b/block/block-backend.c | ||
162 | @@ -XXX,XX +XXX,XX @@ blk_co_do_pdiscard(BlockBackend *blk, int64_t offset, int64_t bytes) | ||
163 | IO_CODE(); | ||
164 | |||
165 | blk_wait_while_drained(blk); | ||
166 | + GRAPH_RDLOCK_GUARD(); | ||
167 | |||
168 | ret = blk_check_byte_request(blk, offset, bytes); | ||
169 | if (ret < 0) { | ||
170 | diff --git a/block/copy-before-write.c b/block/copy-before-write.c | ||
171 | index XXXXXXX..XXXXXXX 100644 | ||
172 | --- a/block/copy-before-write.c | ||
173 | +++ b/block/copy-before-write.c | ||
174 | @@ -XXX,XX +XXX,XX @@ static coroutine_fn int cbw_do_copy_before_write(BlockDriverState *bs, | ||
175 | return 0; | ||
176 | } | ||
177 | |||
178 | -static int coroutine_fn cbw_co_pdiscard(BlockDriverState *bs, | ||
179 | - int64_t offset, int64_t bytes) | ||
180 | +static int coroutine_fn GRAPH_RDLOCK | ||
181 | +cbw_co_pdiscard(BlockDriverState *bs, int64_t offset, int64_t bytes) | ||
182 | { | ||
183 | int ret = cbw_do_copy_before_write(bs, offset, bytes, 0); | ||
184 | if (ret < 0) { | ||
185 | @@ -XXX,XX +XXX,XX @@ cbw_co_snapshot_block_status(BlockDriverState *bs, | ||
186 | return ret; | ||
187 | } | ||
188 | |||
189 | -static int coroutine_fn cbw_co_pdiscard_snapshot(BlockDriverState *bs, | ||
190 | - int64_t offset, int64_t bytes) | ||
191 | +static int coroutine_fn GRAPH_RDLOCK | ||
192 | +cbw_co_pdiscard_snapshot(BlockDriverState *bs, int64_t offset, int64_t bytes) | ||
193 | { | ||
194 | BDRVCopyBeforeWriteState *s = bs->opaque; | ||
195 | |||
196 | diff --git a/block/copy-on-read.c b/block/copy-on-read.c | ||
197 | index XXXXXXX..XXXXXXX 100644 | ||
198 | --- a/block/copy-on-read.c | ||
199 | +++ b/block/copy-on-read.c | ||
200 | @@ -XXX,XX +XXX,XX @@ static int coroutine_fn cor_co_pwrite_zeroes(BlockDriverState *bs, | ||
201 | } | ||
202 | |||
203 | |||
204 | -static int coroutine_fn cor_co_pdiscard(BlockDriverState *bs, | ||
205 | - int64_t offset, int64_t bytes) | ||
206 | +static int coroutine_fn GRAPH_RDLOCK | ||
207 | +cor_co_pdiscard(BlockDriverState *bs, int64_t offset, int64_t bytes) | ||
208 | { | ||
209 | return bdrv_co_pdiscard(bs->file, offset, bytes); | ||
210 | } | ||
211 | diff --git a/block/filter-compress.c b/block/filter-compress.c | ||
212 | index XXXXXXX..XXXXXXX 100644 | ||
213 | --- a/block/filter-compress.c | ||
214 | +++ b/block/filter-compress.c | ||
215 | @@ -XXX,XX +XXX,XX @@ static int coroutine_fn compress_co_pwrite_zeroes(BlockDriverState *bs, | ||
216 | } | ||
217 | |||
218 | |||
219 | -static int coroutine_fn compress_co_pdiscard(BlockDriverState *bs, | ||
220 | - int64_t offset, int64_t bytes) | ||
221 | +static int coroutine_fn GRAPH_RDLOCK | ||
222 | +compress_co_pdiscard(BlockDriverState *bs, int64_t offset, int64_t bytes) | ||
223 | { | ||
224 | return bdrv_co_pdiscard(bs->file, offset, bytes); | ||
225 | } | ||
226 | diff --git a/block/io.c b/block/io.c | ||
227 | index XXXXXXX..XXXXXXX 100644 | ||
228 | --- a/block/io.c | ||
229 | +++ b/block/io.c | ||
230 | @@ -XXX,XX +XXX,XX @@ int coroutine_fn bdrv_co_pdiscard(BdrvChild *child, int64_t offset, | ||
231 | int head, tail, align; | ||
232 | BlockDriverState *bs = child->bs; | ||
233 | IO_CODE(); | ||
234 | + assert_bdrv_graph_readable(); | ||
235 | |||
236 | if (!bs || !bs->drv || !bdrv_co_is_inserted(bs)) { | ||
237 | return -ENOMEDIUM; | ||
238 | @@ -XXX,XX +XXX,XX @@ bdrv_co_pdiscard_snapshot(BlockDriverState *bs, int64_t offset, int64_t bytes) | ||
239 | BlockDriver *drv = bs->drv; | ||
240 | int ret; | ||
241 | IO_CODE(); | ||
242 | + assert_bdrv_graph_readable(); | ||
243 | |||
244 | if (!drv) { | ||
245 | return -ENOMEDIUM; | ||
246 | diff --git a/block/mirror.c b/block/mirror.c | ||
247 | index XXXXXXX..XXXXXXX 100644 | ||
248 | --- a/block/mirror.c | ||
249 | +++ b/block/mirror.c | ||
250 | @@ -XXX,XX +XXX,XX @@ static int coroutine_fn bdrv_mirror_top_preadv(BlockDriverState *bs, | ||
251 | return bdrv_co_preadv(bs->backing, offset, bytes, qiov, flags); | ||
252 | } | ||
253 | |||
254 | -static int coroutine_fn bdrv_mirror_top_do_write(BlockDriverState *bs, | ||
255 | - MirrorMethod method, uint64_t offset, uint64_t bytes, QEMUIOVector *qiov, | ||
256 | - int flags) | ||
257 | +static int coroutine_fn GRAPH_RDLOCK | ||
258 | +bdrv_mirror_top_do_write(BlockDriverState *bs, MirrorMethod method, | ||
259 | + uint64_t offset, uint64_t bytes, QEMUIOVector *qiov, | ||
260 | + int flags) | ||
261 | { | ||
262 | MirrorOp *op = NULL; | ||
263 | MirrorBDSOpaque *s = bs->opaque; | ||
264 | @@ -XXX,XX +XXX,XX @@ static int coroutine_fn bdrv_mirror_top_pwritev(BlockDriverState *bs, | ||
265 | int ret = 0; | ||
266 | bool copy_to_target = false; | ||
267 | |||
268 | + assume_graph_lock(); /* FIXME */ | ||
269 | + | ||
270 | if (s->job) { | ||
271 | copy_to_target = s->job->ret >= 0 && | ||
272 | !job_is_cancelled(&s->job->common.job) && | ||
273 | @@ -XXX,XX +XXX,XX @@ static int coroutine_fn GRAPH_RDLOCK bdrv_mirror_top_flush(BlockDriverState *bs) | ||
274 | static int coroutine_fn bdrv_mirror_top_pwrite_zeroes(BlockDriverState *bs, | ||
275 | int64_t offset, int64_t bytes, BdrvRequestFlags flags) | ||
276 | { | ||
277 | + assume_graph_lock(); /* FIXME */ | ||
278 | return bdrv_mirror_top_do_write(bs, MIRROR_METHOD_ZERO, offset, bytes, NULL, | ||
279 | flags); | ||
280 | } | ||
281 | |||
282 | -static int coroutine_fn bdrv_mirror_top_pdiscard(BlockDriverState *bs, | ||
283 | - int64_t offset, int64_t bytes) | ||
284 | +static int coroutine_fn GRAPH_RDLOCK | ||
285 | +bdrv_mirror_top_pdiscard(BlockDriverState *bs, int64_t offset, int64_t bytes) | ||
286 | { | ||
287 | return bdrv_mirror_top_do_write(bs, MIRROR_METHOD_DISCARD, offset, bytes, | ||
288 | NULL, 0); | ||
289 | diff --git a/block/preallocate.c b/block/preallocate.c | ||
290 | index XXXXXXX..XXXXXXX 100644 | ||
291 | --- a/block/preallocate.c | ||
292 | +++ b/block/preallocate.c | ||
293 | @@ -XXX,XX +XXX,XX @@ static coroutine_fn int preallocate_co_preadv_part( | ||
294 | flags); | ||
295 | } | ||
296 | |||
297 | -static int coroutine_fn preallocate_co_pdiscard(BlockDriverState *bs, | ||
298 | - int64_t offset, int64_t bytes) | ||
299 | +static int coroutine_fn GRAPH_RDLOCK | ||
300 | +preallocate_co_pdiscard(BlockDriverState *bs, int64_t offset, int64_t bytes) | ||
301 | { | ||
302 | return bdrv_co_pdiscard(bs->file, offset, bytes); | ||
303 | } | ||
304 | diff --git a/block/raw-format.c b/block/raw-format.c | ||
305 | index XXXXXXX..XXXXXXX 100644 | ||
306 | --- a/block/raw-format.c | ||
307 | +++ b/block/raw-format.c | ||
308 | @@ -XXX,XX +XXX,XX @@ static int coroutine_fn raw_co_pwrite_zeroes(BlockDriverState *bs, | ||
309 | return bdrv_co_pwrite_zeroes(bs->file, offset, bytes, flags); | ||
310 | } | ||
311 | |||
312 | -static int coroutine_fn raw_co_pdiscard(BlockDriverState *bs, | ||
313 | - int64_t offset, int64_t bytes) | ||
314 | +static int coroutine_fn GRAPH_RDLOCK | ||
315 | +raw_co_pdiscard(BlockDriverState *bs, int64_t offset, int64_t bytes) | ||
316 | { | ||
317 | int ret; | ||
318 | |||
319 | diff --git a/block/snapshot-access.c b/block/snapshot-access.c | ||
320 | index XXXXXXX..XXXXXXX 100644 | ||
321 | --- a/block/snapshot-access.c | ||
322 | +++ b/block/snapshot-access.c | ||
323 | @@ -XXX,XX +XXX,XX @@ snapshot_access_co_block_status(BlockDriverState *bs, | ||
324 | bytes, pnum, map, file); | ||
325 | } | ||
326 | |||
327 | -static int coroutine_fn snapshot_access_co_pdiscard(BlockDriverState *bs, | ||
328 | - int64_t offset, int64_t bytes) | ||
329 | +static int coroutine_fn GRAPH_RDLOCK | ||
330 | +snapshot_access_co_pdiscard(BlockDriverState *bs, int64_t offset, int64_t bytes) | ||
331 | { | ||
332 | return bdrv_co_pdiscard_snapshot(bs->file->bs, offset, bytes); | ||
333 | } | ||
334 | diff --git a/block/throttle.c b/block/throttle.c | ||
335 | index XXXXXXX..XXXXXXX 100644 | ||
336 | --- a/block/throttle.c | ||
337 | +++ b/block/throttle.c | ||
338 | @@ -XXX,XX +XXX,XX @@ static int coroutine_fn throttle_co_pwrite_zeroes(BlockDriverState *bs, | ||
339 | return bdrv_co_pwrite_zeroes(bs->file, offset, bytes, flags); | ||
340 | } | ||
341 | |||
342 | -static int coroutine_fn throttle_co_pdiscard(BlockDriverState *bs, | ||
343 | - int64_t offset, int64_t bytes) | ||
344 | +static int coroutine_fn GRAPH_RDLOCK | ||
345 | +throttle_co_pdiscard(BlockDriverState *bs, int64_t offset, int64_t bytes) | ||
346 | { | ||
347 | ThrottleGroupMember *tgm = bs->opaque; | ||
348 | throttle_group_co_io_limits_intercept(tgm, bytes, true); | ||
349 | -- | ||
350 | 2.39.2 | diff view generated by jsdifflib |
Deleted patch | |||
---|---|---|---|
1 | This adds GRAPH_RDLOCK annotations to declare that callers of | ||
2 | bdrv_co_pwrite_zeroes() need to hold a reader lock for the graph. | ||
3 | 1 | ||
4 | For some places, we know that they will hold the lock, but we don't have | ||
5 | the GRAPH_RDLOCK annotations yet. In this case, add assume_graph_lock() | ||
6 | with a FIXME comment. These places will be removed once everything is | ||
7 | properly annotated. | ||
8 | |||
9 | Signed-off-by: Kevin Wolf <kwolf@redhat.com> | ||
10 | Message-Id: <20230203152202.49054-10-kwolf@redhat.com> | ||
11 | Reviewed-by: Emanuele Giuseppe Esposito <eesposit@redhat.com> | ||
12 | Signed-off-by: Kevin Wolf <kwolf@redhat.com> | ||
13 | --- | ||
14 | block/qcow2.h | 6 ++++-- | ||
15 | include/block/block-io.h | 9 +++++---- | ||
16 | include/block/block_int-common.h | 5 +++-- | ||
17 | block/blkdebug.c | 6 +++--- | ||
18 | block/blklogwrites.c | 5 ++--- | ||
19 | block/blkreplay.c | 5 +++-- | ||
20 | block/block-copy.c | 13 +++++++------ | ||
21 | block/copy-before-write.c | 5 +++-- | ||
22 | block/copy-on-read.c | 6 +++--- | ||
23 | block/filter-compress.c | 6 +++--- | ||
24 | block/io.c | 12 +++++++++--- | ||
25 | block/mirror.c | 6 +++--- | ||
26 | block/preallocate.c | 11 +++++++---- | ||
27 | block/qcow2.c | 30 ++++++++++++++++++------------ | ||
28 | block/qed.c | 9 +++------ | ||
29 | block/quorum.c | 15 ++++++++++----- | ||
30 | block/raw-format.c | 6 +++--- | ||
31 | block/throttle.c | 6 +++--- | ||
32 | 18 files changed, 92 insertions(+), 69 deletions(-) | ||
33 | |||
34 | diff --git a/block/qcow2.h b/block/qcow2.h | ||
35 | index XXXXXXX..XXXXXXX 100644 | ||
36 | --- a/block/qcow2.h | ||
37 | +++ b/block/qcow2.h | ||
38 | @@ -XXX,XX +XXX,XX @@ void qcow2_alloc_cluster_abort(BlockDriverState *bs, QCowL2Meta *m); | ||
39 | int qcow2_cluster_discard(BlockDriverState *bs, uint64_t offset, | ||
40 | uint64_t bytes, enum qcow2_discard_type type, | ||
41 | bool full_discard); | ||
42 | -int coroutine_fn qcow2_subcluster_zeroize(BlockDriverState *bs, uint64_t offset, | ||
43 | - uint64_t bytes, int flags); | ||
44 | + | ||
45 | +int coroutine_fn GRAPH_RDLOCK | ||
46 | +qcow2_subcluster_zeroize(BlockDriverState *bs, uint64_t offset, uint64_t bytes, | ||
47 | + int flags); | ||
48 | |||
49 | int qcow2_expand_zero_clusters(BlockDriverState *bs, | ||
50 | BlockDriverAmendStatusCB *status_cb, | ||
51 | diff --git a/include/block/block-io.h b/include/block/block-io.h | ||
52 | index XXXXXXX..XXXXXXX 100644 | ||
53 | --- a/include/block/block-io.h | ||
54 | +++ b/include/block/block-io.h | ||
55 | @@ -XXX,XX +XXX,XX @@ int coroutine_fn bdrv_co_pwrite_sync(BdrvChild *child, int64_t offset, | ||
56 | * function is not suitable for zeroing the entire image in a single request | ||
57 | * because it may allocate memory for the entire region. | ||
58 | */ | ||
59 | -int coroutine_fn bdrv_co_pwrite_zeroes(BdrvChild *child, int64_t offset, | ||
60 | - int64_t bytes, BdrvRequestFlags flags); | ||
61 | +int coroutine_fn GRAPH_RDLOCK | ||
62 | +bdrv_co_pwrite_zeroes(BdrvChild *child, int64_t offset, int64_t bytes, | ||
63 | + BdrvRequestFlags flags); | ||
64 | |||
65 | int coroutine_fn GRAPH_RDLOCK | ||
66 | bdrv_co_truncate(BdrvChild *child, int64_t offset, bool exact, | ||
67 | @@ -XXX,XX +XXX,XX @@ int bdrv_is_allocated_above(BlockDriverState *top, BlockDriverState *base, | ||
68 | bool include_base, int64_t offset, int64_t bytes, | ||
69 | int64_t *pnum); | ||
70 | |||
71 | -int coroutine_fn bdrv_co_is_zero_fast(BlockDriverState *bs, int64_t offset, | ||
72 | - int64_t bytes); | ||
73 | +int coroutine_fn GRAPH_RDLOCK | ||
74 | +bdrv_co_is_zero_fast(BlockDriverState *bs, int64_t offset, int64_t bytes); | ||
75 | |||
76 | int bdrv_apply_auto_read_only(BlockDriverState *bs, const char *errmsg, | ||
77 | Error **errp); | ||
78 | diff --git a/include/block/block_int-common.h b/include/block/block_int-common.h | ||
79 | index XXXXXXX..XXXXXXX 100644 | ||
80 | --- a/include/block/block_int-common.h | ||
81 | +++ b/include/block/block_int-common.h | ||
82 | @@ -XXX,XX +XXX,XX @@ struct BlockDriver { | ||
83 | * function pointer may be NULL or return -ENOSUP and .bdrv_co_writev() | ||
84 | * will be called instead. | ||
85 | */ | ||
86 | - int coroutine_fn (*bdrv_co_pwrite_zeroes)(BlockDriverState *bs, | ||
87 | - int64_t offset, int64_t bytes, BdrvRequestFlags flags); | ||
88 | + int coroutine_fn GRAPH_RDLOCK_PTR (*bdrv_co_pwrite_zeroes)( | ||
89 | + BlockDriverState *bs, int64_t offset, int64_t bytes, | ||
90 | + BdrvRequestFlags flags); | ||
91 | |||
92 | int coroutine_fn GRAPH_RDLOCK_PTR (*bdrv_co_pdiscard)( | ||
93 | BlockDriverState *bs, int64_t offset, int64_t bytes); | ||
94 | diff --git a/block/blkdebug.c b/block/blkdebug.c | ||
95 | index XXXXXXX..XXXXXXX 100644 | ||
96 | --- a/block/blkdebug.c | ||
97 | +++ b/block/blkdebug.c | ||
98 | @@ -XXX,XX +XXX,XX @@ static int GRAPH_RDLOCK coroutine_fn blkdebug_co_flush(BlockDriverState *bs) | ||
99 | return bdrv_co_flush(bs->file->bs); | ||
100 | } | ||
101 | |||
102 | -static int coroutine_fn blkdebug_co_pwrite_zeroes(BlockDriverState *bs, | ||
103 | - int64_t offset, int64_t bytes, | ||
104 | - BdrvRequestFlags flags) | ||
105 | +static int coroutine_fn GRAPH_RDLOCK | ||
106 | +blkdebug_co_pwrite_zeroes(BlockDriverState *bs, int64_t offset, int64_t bytes, | ||
107 | + BdrvRequestFlags flags) | ||
108 | { | ||
109 | uint32_t align = MAX(bs->bl.request_alignment, | ||
110 | bs->bl.pwrite_zeroes_alignment); | ||
111 | diff --git a/block/blklogwrites.c b/block/blklogwrites.c | ||
112 | index XXXXXXX..XXXXXXX 100644 | ||
113 | --- a/block/blklogwrites.c | ||
114 | +++ b/block/blklogwrites.c | ||
115 | @@ -XXX,XX +XXX,XX @@ blk_log_writes_co_do_file_pwritev(BlkLogWritesFileReq *fr) | ||
116 | fr->qiov, fr->file_flags); | ||
117 | } | ||
118 | |||
119 | -static int coroutine_fn | ||
120 | +static int coroutine_fn GRAPH_RDLOCK | ||
121 | blk_log_writes_co_do_file_pwrite_zeroes(BlkLogWritesFileReq *fr) | ||
122 | { | ||
123 | return bdrv_co_pwrite_zeroes(fr->bs->file, fr->offset, fr->bytes, | ||
124 | @@ -XXX,XX +XXX,XX @@ blk_log_writes_co_pwritev(BlockDriverState *bs, int64_t offset, int64_t bytes, | ||
125 | blk_log_writes_co_do_file_pwritev, 0, false); | ||
126 | } | ||
127 | |||
128 | -static int coroutine_fn | ||
129 | +static int coroutine_fn GRAPH_RDLOCK | ||
130 | blk_log_writes_co_pwrite_zeroes(BlockDriverState *bs, int64_t offset, | ||
131 | int64_t bytes, BdrvRequestFlags flags) | ||
132 | { | ||
133 | - assume_graph_lock(); /* FIXME */ | ||
134 | return blk_log_writes_co_log(bs, offset, bytes, NULL, flags, | ||
135 | blk_log_writes_co_do_file_pwrite_zeroes, 0, | ||
136 | true); | ||
137 | diff --git a/block/blkreplay.c b/block/blkreplay.c | ||
138 | index XXXXXXX..XXXXXXX 100644 | ||
139 | --- a/block/blkreplay.c | ||
140 | +++ b/block/blkreplay.c | ||
141 | @@ -XXX,XX +XXX,XX @@ static int coroutine_fn blkreplay_co_pwritev(BlockDriverState *bs, | ||
142 | return ret; | ||
143 | } | ||
144 | |||
145 | -static int coroutine_fn blkreplay_co_pwrite_zeroes(BlockDriverState *bs, | ||
146 | - int64_t offset, int64_t bytes, BdrvRequestFlags flags) | ||
147 | +static int coroutine_fn GRAPH_RDLOCK | ||
148 | +blkreplay_co_pwrite_zeroes(BlockDriverState *bs, int64_t offset, int64_t bytes, | ||
149 | + BdrvRequestFlags flags) | ||
150 | { | ||
151 | uint64_t reqid = blkreplay_next_id(); | ||
152 | int ret = bdrv_co_pwrite_zeroes(bs->file, offset, bytes, flags); | ||
153 | diff --git a/block/block-copy.c b/block/block-copy.c | ||
154 | index XXXXXXX..XXXXXXX 100644 | ||
155 | --- a/block/block-copy.c | ||
156 | +++ b/block/block-copy.c | ||
157 | @@ -XXX,XX +XXX,XX @@ static coroutine_fn int block_copy_task_run(AioTaskPool *pool, | ||
158 | * value of @method should be used for subsequent tasks. | ||
159 | * Returns 0 on success. | ||
160 | */ | ||
161 | -static int coroutine_fn block_copy_do_copy(BlockCopyState *s, | ||
162 | - int64_t offset, int64_t bytes, | ||
163 | - BlockCopyMethod *method, | ||
164 | - bool *error_is_read) | ||
165 | +static int coroutine_fn GRAPH_RDLOCK | ||
166 | +block_copy_do_copy(BlockCopyState *s, int64_t offset, int64_t bytes, | ||
167 | + BlockCopyMethod *method, bool *error_is_read) | ||
168 | { | ||
169 | int ret; | ||
170 | int64_t nbytes = MIN(offset + bytes, s->len) - offset; | ||
171 | @@ -XXX,XX +XXX,XX @@ static coroutine_fn int block_copy_task_entry(AioTask *task) | ||
172 | BlockCopyMethod method = t->method; | ||
173 | int ret; | ||
174 | |||
175 | - ret = block_copy_do_copy(s, t->req.offset, t->req.bytes, &method, | ||
176 | - &error_is_read); | ||
177 | + WITH_GRAPH_RDLOCK_GUARD() { | ||
178 | + ret = block_copy_do_copy(s, t->req.offset, t->req.bytes, &method, | ||
179 | + &error_is_read); | ||
180 | + } | ||
181 | |||
182 | WITH_QEMU_LOCK_GUARD(&s->lock) { | ||
183 | if (s->method == t->method) { | ||
184 | diff --git a/block/copy-before-write.c b/block/copy-before-write.c | ||
185 | index XXXXXXX..XXXXXXX 100644 | ||
186 | --- a/block/copy-before-write.c | ||
187 | +++ b/block/copy-before-write.c | ||
188 | @@ -XXX,XX +XXX,XX @@ cbw_co_pdiscard(BlockDriverState *bs, int64_t offset, int64_t bytes) | ||
189 | return bdrv_co_pdiscard(bs->file, offset, bytes); | ||
190 | } | ||
191 | |||
192 | -static int coroutine_fn cbw_co_pwrite_zeroes(BlockDriverState *bs, | ||
193 | - int64_t offset, int64_t bytes, BdrvRequestFlags flags) | ||
194 | +static int coroutine_fn GRAPH_RDLOCK | ||
195 | +cbw_co_pwrite_zeroes(BlockDriverState *bs, int64_t offset, int64_t bytes, | ||
196 | + BdrvRequestFlags flags) | ||
197 | { | ||
198 | int ret = cbw_do_copy_before_write(bs, offset, bytes, flags); | ||
199 | if (ret < 0) { | ||
200 | diff --git a/block/copy-on-read.c b/block/copy-on-read.c | ||
201 | index XXXXXXX..XXXXXXX 100644 | ||
202 | --- a/block/copy-on-read.c | ||
203 | +++ b/block/copy-on-read.c | ||
204 | @@ -XXX,XX +XXX,XX @@ static int coroutine_fn cor_co_pwritev_part(BlockDriverState *bs, | ||
205 | } | ||
206 | |||
207 | |||
208 | -static int coroutine_fn cor_co_pwrite_zeroes(BlockDriverState *bs, | ||
209 | - int64_t offset, int64_t bytes, | ||
210 | - BdrvRequestFlags flags) | ||
211 | +static int coroutine_fn GRAPH_RDLOCK | ||
212 | +cor_co_pwrite_zeroes(BlockDriverState *bs, int64_t offset, int64_t bytes, | ||
213 | + BdrvRequestFlags flags) | ||
214 | { | ||
215 | return bdrv_co_pwrite_zeroes(bs->file, offset, bytes, flags); | ||
216 | } | ||
217 | diff --git a/block/filter-compress.c b/block/filter-compress.c | ||
218 | index XXXXXXX..XXXXXXX 100644 | ||
219 | --- a/block/filter-compress.c | ||
220 | +++ b/block/filter-compress.c | ||
221 | @@ -XXX,XX +XXX,XX @@ static int coroutine_fn compress_co_pwritev_part(BlockDriverState *bs, | ||
222 | } | ||
223 | |||
224 | |||
225 | -static int coroutine_fn compress_co_pwrite_zeroes(BlockDriverState *bs, | ||
226 | - int64_t offset, int64_t bytes, | ||
227 | - BdrvRequestFlags flags) | ||
228 | +static int coroutine_fn GRAPH_RDLOCK | ||
229 | +compress_co_pwrite_zeroes(BlockDriverState *bs, int64_t offset, int64_t bytes, | ||
230 | + BdrvRequestFlags flags) | ||
231 | { | ||
232 | return bdrv_co_pwrite_zeroes(bs->file, offset, bytes, flags); | ||
233 | } | ||
234 | diff --git a/block/io.c b/block/io.c | ||
235 | index XXXXXXX..XXXXXXX 100644 | ||
236 | --- a/block/io.c | ||
237 | +++ b/block/io.c | ||
238 | @@ -XXX,XX +XXX,XX @@ static int coroutine_fn bdrv_co_do_copy_on_readv(BdrvChild *child, | ||
239 | int64_t progress = 0; | ||
240 | bool skip_write; | ||
241 | |||
242 | + assume_graph_lock(); /* FIXME */ | ||
243 | + | ||
244 | bdrv_check_qiov_request(offset, bytes, qiov, qiov_offset, &error_abort); | ||
245 | |||
246 | if (!drv) { | ||
247 | @@ -XXX,XX +XXX,XX @@ static int coroutine_fn bdrv_co_do_pwrite_zeroes(BlockDriverState *bs, | ||
248 | bs->bl.request_alignment); | ||
249 | int max_transfer = MIN_NON_ZERO(bs->bl.max_transfer, MAX_BOUNCE_BUFFER); | ||
250 | |||
251 | + assert_bdrv_graph_readable(); | ||
252 | bdrv_check_request(offset, bytes, &error_abort); | ||
253 | |||
254 | if (!drv) { | ||
255 | @@ -XXX,XX +XXX,XX @@ static int coroutine_fn bdrv_aligned_pwritev(BdrvChild *child, | ||
256 | int64_t bytes_remaining = bytes; | ||
257 | int max_transfer; | ||
258 | |||
259 | + assume_graph_lock(); /* FIXME */ | ||
260 | + | ||
261 | bdrv_check_qiov_request(offset, bytes, qiov, qiov_offset, &error_abort); | ||
262 | |||
263 | if (!drv) { | ||
264 | @@ -XXX,XX +XXX,XX @@ int coroutine_fn bdrv_co_pwrite_zeroes(BdrvChild *child, int64_t offset, | ||
265 | { | ||
266 | IO_CODE(); | ||
267 | trace_bdrv_co_pwrite_zeroes(child->bs, offset, bytes, flags); | ||
268 | + assert_bdrv_graph_readable(); | ||
269 | |||
270 | if (!(child->bs->open_flags & BDRV_O_UNMAP)) { | ||
271 | flags &= ~BDRV_REQ_MAY_UNMAP; | ||
272 | @@ -XXX,XX +XXX,XX @@ int coroutine_fn bdrv_co_is_zero_fast(BlockDriverState *bs, int64_t offset, | ||
273 | int64_t pnum = bytes; | ||
274 | IO_CODE(); | ||
275 | |||
276 | - assume_graph_lock(); /* FIXME */ | ||
277 | - | ||
278 | if (!bytes) { | ||
279 | return 1; | ||
280 | } | ||
281 | @@ -XXX,XX +XXX,XX @@ void bdrv_unregister_buf(BlockDriverState *bs, void *host, size_t size) | ||
282 | } | ||
283 | } | ||
284 | |||
285 | -static int coroutine_fn bdrv_co_copy_range_internal( | ||
286 | +static int coroutine_fn GRAPH_RDLOCK bdrv_co_copy_range_internal( | ||
287 | BdrvChild *src, int64_t src_offset, BdrvChild *dst, | ||
288 | int64_t dst_offset, int64_t bytes, | ||
289 | BdrvRequestFlags read_flags, BdrvRequestFlags write_flags, | ||
290 | @@ -XXX,XX +XXX,XX @@ int coroutine_fn bdrv_co_copy_range_from(BdrvChild *src, int64_t src_offset, | ||
291 | BdrvRequestFlags write_flags) | ||
292 | { | ||
293 | IO_CODE(); | ||
294 | + assume_graph_lock(); /* FIXME */ | ||
295 | trace_bdrv_co_copy_range_from(src, src_offset, dst, dst_offset, bytes, | ||
296 | read_flags, write_flags); | ||
297 | return bdrv_co_copy_range_internal(src, src_offset, dst, dst_offset, | ||
298 | @@ -XXX,XX +XXX,XX @@ int coroutine_fn bdrv_co_copy_range_to(BdrvChild *src, int64_t src_offset, | ||
299 | BdrvRequestFlags write_flags) | ||
300 | { | ||
301 | IO_CODE(); | ||
302 | + assume_graph_lock(); /* FIXME */ | ||
303 | trace_bdrv_co_copy_range_to(src, src_offset, dst, dst_offset, bytes, | ||
304 | read_flags, write_flags); | ||
305 | return bdrv_co_copy_range_internal(src, src_offset, dst, dst_offset, | ||
306 | diff --git a/block/mirror.c b/block/mirror.c | ||
307 | index XXXXXXX..XXXXXXX 100644 | ||
308 | --- a/block/mirror.c | ||
309 | +++ b/block/mirror.c | ||
310 | @@ -XXX,XX +XXX,XX @@ static int coroutine_fn GRAPH_RDLOCK bdrv_mirror_top_flush(BlockDriverState *bs) | ||
311 | return bdrv_co_flush(bs->backing->bs); | ||
312 | } | ||
313 | |||
314 | -static int coroutine_fn bdrv_mirror_top_pwrite_zeroes(BlockDriverState *bs, | ||
315 | - int64_t offset, int64_t bytes, BdrvRequestFlags flags) | ||
316 | +static int coroutine_fn GRAPH_RDLOCK | ||
317 | +bdrv_mirror_top_pwrite_zeroes(BlockDriverState *bs, int64_t offset, | ||
318 | + int64_t bytes, BdrvRequestFlags flags) | ||
319 | { | ||
320 | - assume_graph_lock(); /* FIXME */ | ||
321 | return bdrv_mirror_top_do_write(bs, MIRROR_METHOD_ZERO, offset, bytes, NULL, | ||
322 | flags); | ||
323 | } | ||
324 | diff --git a/block/preallocate.c b/block/preallocate.c | ||
325 | index XXXXXXX..XXXXXXX 100644 | ||
326 | --- a/block/preallocate.c | ||
327 | +++ b/block/preallocate.c | ||
328 | @@ -XXX,XX +XXX,XX @@ static bool has_prealloc_perms(BlockDriverState *bs) | ||
329 | * want_merge_zero is used to merge write-zero request with preallocation in | ||
330 | * one bdrv_co_pwrite_zeroes() call. | ||
331 | */ | ||
332 | -static bool coroutine_fn handle_write(BlockDriverState *bs, int64_t offset, | ||
333 | - int64_t bytes, bool want_merge_zero) | ||
334 | +static bool coroutine_fn GRAPH_RDLOCK | ||
335 | +handle_write(BlockDriverState *bs, int64_t offset, int64_t bytes, | ||
336 | + bool want_merge_zero) | ||
337 | { | ||
338 | BDRVPreallocateState *s = bs->opaque; | ||
339 | int64_t end = offset + bytes; | ||
340 | @@ -XXX,XX +XXX,XX @@ static bool coroutine_fn handle_write(BlockDriverState *bs, int64_t offset, | ||
341 | return want_merge_zero; | ||
342 | } | ||
343 | |||
344 | -static int coroutine_fn preallocate_co_pwrite_zeroes(BlockDriverState *bs, | ||
345 | - int64_t offset, int64_t bytes, BdrvRequestFlags flags) | ||
346 | +static int coroutine_fn GRAPH_RDLOCK | ||
347 | +preallocate_co_pwrite_zeroes(BlockDriverState *bs, int64_t offset, | ||
348 | + int64_t bytes, BdrvRequestFlags flags) | ||
349 | { | ||
350 | bool want_merge_zero = | ||
351 | !(flags & ~(BDRV_REQ_ZERO_WRITE | BDRV_REQ_NO_FALLBACK)); | ||
352 | @@ -XXX,XX +XXX,XX @@ static coroutine_fn int preallocate_co_pwritev_part(BlockDriverState *bs, | ||
353 | size_t qiov_offset, | ||
354 | BdrvRequestFlags flags) | ||
355 | { | ||
356 | + assume_graph_lock(); /* FIXME */ | ||
357 | handle_write(bs, offset, bytes, false); | ||
358 | |||
359 | return bdrv_co_pwritev_part(bs->file, offset, bytes, qiov, qiov_offset, | ||
360 | diff --git a/block/qcow2.c b/block/qcow2.c | ||
361 | index XXXXXXX..XXXXXXX 100644 | ||
362 | --- a/block/qcow2.c | ||
363 | +++ b/block/qcow2.c | ||
364 | @@ -XXX,XX +XXX,XX @@ static bool merge_cow(uint64_t offset, unsigned bytes, | ||
365 | * Return 1 if the COW regions read as zeroes, 0 if not, < 0 on error. | ||
366 | * Note that returning 0 does not guarantee non-zero data. | ||
367 | */ | ||
368 | -static int coroutine_fn is_zero_cow(BlockDriverState *bs, QCowL2Meta *m) | ||
369 | +static int coroutine_fn GRAPH_RDLOCK | ||
370 | +is_zero_cow(BlockDriverState *bs, QCowL2Meta *m) | ||
371 | { | ||
372 | /* | ||
373 | * This check is designed for optimization shortcut so it must be | ||
374 | @@ -XXX,XX +XXX,XX @@ static int coroutine_fn is_zero_cow(BlockDriverState *bs, QCowL2Meta *m) | ||
375 | m->cow_end.nb_bytes); | ||
376 | } | ||
377 | |||
378 | -static int coroutine_fn handle_alloc_space(BlockDriverState *bs, | ||
379 | - QCowL2Meta *l2meta) | ||
380 | +static int coroutine_fn GRAPH_RDLOCK | ||
381 | +handle_alloc_space(BlockDriverState *bs, QCowL2Meta *l2meta) | ||
382 | { | ||
383 | BDRVQcow2State *s = bs->opaque; | ||
384 | QCowL2Meta *m; | ||
385 | @@ -XXX,XX +XXX,XX @@ static int coroutine_fn handle_alloc_space(BlockDriverState *bs, | ||
386 | * l2meta - if not NULL, qcow2_co_pwritev_task() will consume it. Caller must | ||
387 | * not use it somehow after qcow2_co_pwritev_task() call | ||
388 | */ | ||
389 | -static coroutine_fn int qcow2_co_pwritev_task(BlockDriverState *bs, | ||
390 | - uint64_t host_offset, | ||
391 | - uint64_t offset, uint64_t bytes, | ||
392 | - QEMUIOVector *qiov, | ||
393 | - uint64_t qiov_offset, | ||
394 | - QCowL2Meta *l2meta) | ||
395 | +static coroutine_fn GRAPH_RDLOCK | ||
396 | +int qcow2_co_pwritev_task(BlockDriverState *bs, uint64_t host_offset, | ||
397 | + uint64_t offset, uint64_t bytes, QEMUIOVector *qiov, | ||
398 | + uint64_t qiov_offset, QCowL2Meta *l2meta) | ||
399 | { | ||
400 | int ret; | ||
401 | BDRVQcow2State *s = bs->opaque; | ||
402 | @@ -XXX,XX +XXX,XX @@ out_locked: | ||
403 | return ret; | ||
404 | } | ||
405 | |||
406 | -static coroutine_fn int qcow2_co_pwritev_task_entry(AioTask *task) | ||
407 | +/* | ||
408 | + * This function can count as GRAPH_RDLOCK because qcow2_co_pwritev_part() holds | ||
409 | + * the graph lock and keeps it until this coroutine has terminated. | ||
410 | + */ | ||
411 | +static coroutine_fn GRAPH_RDLOCK int qcow2_co_pwritev_task_entry(AioTask *task) | ||
412 | { | ||
413 | Qcow2AioTask *t = container_of(task, Qcow2AioTask, task); | ||
414 | |||
415 | @@ -XXX,XX +XXX,XX @@ static coroutine_fn int qcow2_co_pwritev_part( | ||
416 | QCowL2Meta *l2meta = NULL; | ||
417 | AioTaskPool *aio = NULL; | ||
418 | |||
419 | + assume_graph_lock(); /* FIXME */ | ||
420 | + | ||
421 | trace_qcow2_writev_start_req(qemu_coroutine_self(), offset, bytes); | ||
422 | |||
423 | while (bytes != 0 && aio_task_pool_status(aio) == 0) { | ||
424 | @@ -XXX,XX +XXX,XX @@ static bool is_zero(BlockDriverState *bs, int64_t offset, int64_t bytes) | ||
425 | return res >= 0 && (res & BDRV_BLOCK_ZERO) && bytes == 0; | ||
426 | } | ||
427 | |||
428 | -static coroutine_fn int qcow2_co_pwrite_zeroes(BlockDriverState *bs, | ||
429 | - int64_t offset, int64_t bytes, BdrvRequestFlags flags) | ||
430 | +static int coroutine_fn GRAPH_RDLOCK | ||
431 | +qcow2_co_pwrite_zeroes(BlockDriverState *bs, int64_t offset, int64_t bytes, | ||
432 | + BdrvRequestFlags flags) | ||
433 | { | ||
434 | int ret; | ||
435 | BDRVQcow2State *s = bs->opaque; | ||
436 | diff --git a/block/qed.c b/block/qed.c | ||
437 | index XXXXXXX..XXXXXXX 100644 | ||
438 | --- a/block/qed.c | ||
439 | +++ b/block/qed.c | ||
440 | @@ -XXX,XX +XXX,XX @@ static int coroutine_fn bdrv_qed_co_writev(BlockDriverState *bs, | ||
441 | return qed_co_request(bs, sector_num, qiov, nb_sectors, QED_AIOCB_WRITE); | ||
442 | } | ||
443 | |||
444 | -static int coroutine_fn bdrv_qed_co_pwrite_zeroes(BlockDriverState *bs, | ||
445 | - int64_t offset, | ||
446 | - int64_t bytes, | ||
447 | - BdrvRequestFlags flags) | ||
448 | +static int coroutine_fn GRAPH_RDLOCK | ||
449 | +bdrv_qed_co_pwrite_zeroes(BlockDriverState *bs, int64_t offset, int64_t bytes, | ||
450 | + BdrvRequestFlags flags) | ||
451 | { | ||
452 | BDRVQEDState *s = bs->opaque; | ||
453 | |||
454 | - assume_graph_lock(); /* FIXME */ | ||
455 | - | ||
456 | /* | ||
457 | * Zero writes start without an I/O buffer. If a buffer becomes necessary | ||
458 | * then it will be allocated during request processing. | ||
459 | diff --git a/block/quorum.c b/block/quorum.c | ||
460 | index XXXXXXX..XXXXXXX 100644 | ||
461 | --- a/block/quorum.c | ||
462 | +++ b/block/quorum.c | ||
463 | @@ -XXX,XX +XXX,XX @@ static int coroutine_fn quorum_co_preadv(BlockDriverState *bs, | ||
464 | return ret; | ||
465 | } | ||
466 | |||
467 | -static void coroutine_fn write_quorum_entry(void *opaque) | ||
468 | +/* | ||
469 | + * This function can count as GRAPH_RDLOCK because quorum_co_pwritev() holds the | ||
470 | + * graph lock and keeps it until this coroutine has terminated. | ||
471 | + */ | ||
472 | +static void coroutine_fn GRAPH_RDLOCK write_quorum_entry(void *opaque) | ||
473 | { | ||
474 | QuorumCo *co = opaque; | ||
475 | QuorumAIOCB *acb = co->acb; | ||
476 | @@ -XXX,XX +XXX,XX @@ static int coroutine_fn quorum_co_pwritev(BlockDriverState *bs, int64_t offset, | ||
477 | QuorumAIOCB *acb = quorum_aio_get(bs, qiov, offset, bytes, flags); | ||
478 | int i, ret; | ||
479 | |||
480 | + assume_graph_lock(); /* FIXME */ | ||
481 | + | ||
482 | for (i = 0; i < s->num_children; i++) { | ||
483 | Coroutine *co; | ||
484 | QuorumCo data = { | ||
485 | @@ -XXX,XX +XXX,XX @@ static int coroutine_fn quorum_co_pwritev(BlockDriverState *bs, int64_t offset, | ||
486 | return ret; | ||
487 | } | ||
488 | |||
489 | -static int coroutine_fn quorum_co_pwrite_zeroes(BlockDriverState *bs, | ||
490 | - int64_t offset, int64_t bytes, | ||
491 | - BdrvRequestFlags flags) | ||
492 | - | ||
493 | +static int coroutine_fn GRAPH_RDLOCK | ||
494 | +quorum_co_pwrite_zeroes(BlockDriverState *bs, int64_t offset, int64_t bytes, | ||
495 | + BdrvRequestFlags flags) | ||
496 | { | ||
497 | return quorum_co_pwritev(bs, offset, bytes, NULL, | ||
498 | flags | BDRV_REQ_ZERO_WRITE); | ||
499 | diff --git a/block/raw-format.c b/block/raw-format.c | ||
500 | index XXXXXXX..XXXXXXX 100644 | ||
501 | --- a/block/raw-format.c | ||
502 | +++ b/block/raw-format.c | ||
503 | @@ -XXX,XX +XXX,XX @@ static int coroutine_fn raw_co_block_status(BlockDriverState *bs, | ||
504 | return BDRV_BLOCK_RAW | BDRV_BLOCK_OFFSET_VALID; | ||
505 | } | ||
506 | |||
507 | -static int coroutine_fn raw_co_pwrite_zeroes(BlockDriverState *bs, | ||
508 | - int64_t offset, int64_t bytes, | ||
509 | - BdrvRequestFlags flags) | ||
510 | +static int coroutine_fn GRAPH_RDLOCK | ||
511 | +raw_co_pwrite_zeroes(BlockDriverState *bs, int64_t offset, int64_t bytes, | ||
512 | + BdrvRequestFlags flags) | ||
513 | { | ||
514 | int ret; | ||
515 | |||
516 | diff --git a/block/throttle.c b/block/throttle.c | ||
517 | index XXXXXXX..XXXXXXX 100644 | ||
518 | --- a/block/throttle.c | ||
519 | +++ b/block/throttle.c | ||
520 | @@ -XXX,XX +XXX,XX @@ static int coroutine_fn throttle_co_pwritev(BlockDriverState *bs, | ||
521 | return bdrv_co_pwritev(bs->file, offset, bytes, qiov, flags); | ||
522 | } | ||
523 | |||
524 | -static int coroutine_fn throttle_co_pwrite_zeroes(BlockDriverState *bs, | ||
525 | - int64_t offset, int64_t bytes, | ||
526 | - BdrvRequestFlags flags) | ||
527 | +static int coroutine_fn GRAPH_RDLOCK | ||
528 | +throttle_co_pwrite_zeroes(BlockDriverState *bs, int64_t offset, int64_t bytes, | ||
529 | + BdrvRequestFlags flags) | ||
530 | { | ||
531 | ThrottleGroupMember *tgm = bs->opaque; | ||
532 | throttle_group_co_io_limits_intercept(tgm, bytes, true); | ||
533 | -- | ||
534 | 2.39.2 | diff view generated by jsdifflib |
Deleted patch | |||
---|---|---|---|
1 | This adds GRAPH_RDLOCK annotations to declare that callers of | ||
2 | bdrv_driver_*() need to hold a reader lock for the graph. It doesn't add | ||
3 | the annotation to public functions yet. | ||
4 | 1 | ||
5 | For some places, we know that they will hold the lock, but we don't have | ||
6 | the GRAPH_RDLOCK annotations yet. In this case, add assume_graph_lock() | ||
7 | with a FIXME comment. These places will be removed once everything is | ||
8 | properly annotated. | ||
9 | |||
10 | Signed-off-by: Kevin Wolf <kwolf@redhat.com> | ||
11 | Message-Id: <20230203152202.49054-11-kwolf@redhat.com> | ||
12 | Reviewed-by: Emanuele Giuseppe Esposito <eesposit@redhat.com> | ||
13 | Signed-off-by: Kevin Wolf <kwolf@redhat.com> | ||
14 | --- | ||
15 | block/qcow2.h | 5 ++- | ||
16 | include/block/block_int-common.h | 40 ++++++++++--------- | ||
17 | block/io.c | 66 +++++++++++++++----------------- | ||
18 | block/parallels.c | 8 ++-- | ||
19 | block/qcow.c | 20 ++++------ | ||
20 | block/qcow2-cluster.c | 10 ++--- | ||
21 | block/qcow2.c | 37 ++++++++++-------- | ||
22 | block/qed.c | 14 +++---- | ||
23 | block/quorum.c | 8 ++-- | ||
24 | block/vmdk.c | 4 +- | ||
25 | 10 files changed, 101 insertions(+), 111 deletions(-) | ||
26 | |||
27 | diff --git a/block/qcow2.h b/block/qcow2.h | ||
28 | index XXXXXXX..XXXXXXX 100644 | ||
29 | --- a/block/qcow2.h | ||
30 | +++ b/block/qcow2.h | ||
31 | @@ -XXX,XX +XXX,XX @@ int coroutine_fn qcow2_alloc_compressed_cluster_offset(BlockDriverState *bs, | ||
32 | void qcow2_parse_compressed_l2_entry(BlockDriverState *bs, uint64_t l2_entry, | ||
33 | uint64_t *coffset, int *csize); | ||
34 | |||
35 | -int coroutine_fn qcow2_alloc_cluster_link_l2(BlockDriverState *bs, | ||
36 | - QCowL2Meta *m); | ||
37 | +int coroutine_fn GRAPH_RDLOCK | ||
38 | +qcow2_alloc_cluster_link_l2(BlockDriverState *bs, QCowL2Meta *m); | ||
39 | + | ||
40 | void qcow2_alloc_cluster_abort(BlockDriverState *bs, QCowL2Meta *m); | ||
41 | int qcow2_cluster_discard(BlockDriverState *bs, uint64_t offset, | ||
42 | uint64_t bytes, enum qcow2_discard_type type, | ||
43 | diff --git a/include/block/block_int-common.h b/include/block/block_int-common.h | ||
44 | index XXXXXXX..XXXXXXX 100644 | ||
45 | --- a/include/block/block_int-common.h | ||
46 | +++ b/include/block/block_int-common.h | ||
47 | @@ -XXX,XX +XXX,XX @@ struct BlockDriver { | ||
48 | Error **errp); | ||
49 | |||
50 | /* aio */ | ||
51 | - BlockAIOCB *(*bdrv_aio_preadv)(BlockDriverState *bs, | ||
52 | + BlockAIOCB * GRAPH_RDLOCK_PTR (*bdrv_aio_preadv)(BlockDriverState *bs, | ||
53 | int64_t offset, int64_t bytes, QEMUIOVector *qiov, | ||
54 | BdrvRequestFlags flags, BlockCompletionFunc *cb, void *opaque); | ||
55 | - BlockAIOCB *(*bdrv_aio_pwritev)(BlockDriverState *bs, | ||
56 | + | ||
57 | + BlockAIOCB * GRAPH_RDLOCK_PTR (*bdrv_aio_pwritev)(BlockDriverState *bs, | ||
58 | int64_t offset, int64_t bytes, QEMUIOVector *qiov, | ||
59 | BdrvRequestFlags flags, BlockCompletionFunc *cb, void *opaque); | ||
60 | + | ||
61 | BlockAIOCB * GRAPH_RDLOCK_PTR (*bdrv_aio_flush)( | ||
62 | BlockDriverState *bs, BlockCompletionFunc *cb, void *opaque); | ||
63 | |||
64 | @@ -XXX,XX +XXX,XX @@ struct BlockDriver { | ||
65 | BlockDriverState *bs, int64_t offset, int bytes, | ||
66 | BlockCompletionFunc *cb, void *opaque); | ||
67 | |||
68 | - int coroutine_fn (*bdrv_co_readv)(BlockDriverState *bs, | ||
69 | + int coroutine_fn GRAPH_RDLOCK_PTR (*bdrv_co_readv)(BlockDriverState *bs, | ||
70 | int64_t sector_num, int nb_sectors, QEMUIOVector *qiov); | ||
71 | |||
72 | /** | ||
73 | @@ -XXX,XX +XXX,XX @@ struct BlockDriver { | ||
74 | * | ||
75 | * The buffer in @qiov may point directly to guest memory. | ||
76 | */ | ||
77 | - int coroutine_fn (*bdrv_co_preadv)(BlockDriverState *bs, | ||
78 | + int coroutine_fn GRAPH_RDLOCK_PTR (*bdrv_co_preadv)(BlockDriverState *bs, | ||
79 | int64_t offset, int64_t bytes, QEMUIOVector *qiov, | ||
80 | BdrvRequestFlags flags); | ||
81 | |||
82 | - int coroutine_fn (*bdrv_co_preadv_part)(BlockDriverState *bs, | ||
83 | - int64_t offset, int64_t bytes, | ||
84 | + int coroutine_fn GRAPH_RDLOCK_PTR (*bdrv_co_preadv_part)( | ||
85 | + BlockDriverState *bs, int64_t offset, int64_t bytes, | ||
86 | QEMUIOVector *qiov, size_t qiov_offset, | ||
87 | BdrvRequestFlags flags); | ||
88 | |||
89 | - int coroutine_fn (*bdrv_co_writev)(BlockDriverState *bs, | ||
90 | + int coroutine_fn GRAPH_RDLOCK_PTR (*bdrv_co_writev)(BlockDriverState *bs, | ||
91 | int64_t sector_num, int nb_sectors, QEMUIOVector *qiov, | ||
92 | int flags); | ||
93 | /** | ||
94 | @@ -XXX,XX +XXX,XX @@ struct BlockDriver { | ||
95 | * | ||
96 | * The buffer in @qiov may point directly to guest memory. | ||
97 | */ | ||
98 | - int coroutine_fn (*bdrv_co_pwritev)(BlockDriverState *bs, | ||
99 | - int64_t offset, int64_t bytes, QEMUIOVector *qiov, | ||
100 | - BdrvRequestFlags flags); | ||
101 | - int coroutine_fn (*bdrv_co_pwritev_part)(BlockDriverState *bs, | ||
102 | - int64_t offset, int64_t bytes, QEMUIOVector *qiov, size_t qiov_offset, | ||
103 | + int coroutine_fn GRAPH_RDLOCK_PTR (*bdrv_co_pwritev)( | ||
104 | + BlockDriverState *bs, int64_t offset, int64_t bytes, QEMUIOVector *qiov, | ||
105 | BdrvRequestFlags flags); | ||
106 | + int coroutine_fn GRAPH_RDLOCK_PTR (*bdrv_co_pwritev_part)( | ||
107 | + BlockDriverState *bs, int64_t offset, int64_t bytes, QEMUIOVector *qiov, | ||
108 | + size_t qiov_offset, BdrvRequestFlags flags); | ||
109 | |||
110 | /* | ||
111 | * Efficiently zero a region of the disk image. Typically an image format | ||
112 | @@ -XXX,XX +XXX,XX @@ struct BlockDriver { | ||
113 | BlockMeasureInfo *(*bdrv_measure)(QemuOpts *opts, BlockDriverState *in_bs, | ||
114 | Error **errp); | ||
115 | |||
116 | - int coroutine_fn (*bdrv_co_pwritev_compressed)(BlockDriverState *bs, | ||
117 | - int64_t offset, int64_t bytes, QEMUIOVector *qiov); | ||
118 | - int coroutine_fn (*bdrv_co_pwritev_compressed_part)(BlockDriverState *bs, | ||
119 | - int64_t offset, int64_t bytes, QEMUIOVector *qiov, | ||
120 | - size_t qiov_offset); | ||
121 | + int coroutine_fn GRAPH_RDLOCK_PTR (*bdrv_co_pwritev_compressed)( | ||
122 | + BlockDriverState *bs, int64_t offset, int64_t bytes, | ||
123 | + QEMUIOVector *qiov); | ||
124 | + | ||
125 | + int coroutine_fn GRAPH_RDLOCK_PTR (*bdrv_co_pwritev_compressed_part)( | ||
126 | + BlockDriverState *bs, int64_t offset, int64_t bytes, | ||
127 | + QEMUIOVector *qiov, size_t qiov_offset); | ||
128 | |||
129 | int coroutine_fn (*bdrv_co_get_info)(BlockDriverState *bs, | ||
130 | BlockDriverInfo *bdi); | ||
131 | @@ -XXX,XX +XXX,XX @@ struct BlockDriver { | ||
132 | BlockDriverState *bs, const char *name, Error **errp); | ||
133 | }; | ||
134 | |||
135 | -static inline bool block_driver_can_compress(BlockDriver *drv) | ||
136 | +static inline bool TSA_NO_TSA block_driver_can_compress(BlockDriver *drv) | ||
137 | { | ||
138 | return drv->bdrv_co_pwritev_compressed || | ||
139 | drv->bdrv_co_pwritev_compressed_part; | ||
140 | diff --git a/block/io.c b/block/io.c | ||
141 | index XXXXXXX..XXXXXXX 100644 | ||
142 | --- a/block/io.c | ||
143 | +++ b/block/io.c | ||
144 | @@ -XXX,XX +XXX,XX @@ void bdrv_refresh_limits(BlockDriverState *bs, Transaction *tran, Error **errp) | ||
145 | bool have_limits; | ||
146 | |||
147 | GLOBAL_STATE_CODE(); | ||
148 | + assume_graph_lock(); /* FIXME */ | ||
149 | |||
150 | if (tran) { | ||
151 | BdrvRefreshLimitsState *s = g_new(BdrvRefreshLimitsState, 1); | ||
152 | @@ -XXX,XX +XXX,XX @@ static void bdrv_co_io_em_complete(void *opaque, int ret) | ||
153 | aio_co_wake(co->coroutine); | ||
154 | } | ||
155 | |||
156 | -static int coroutine_fn bdrv_driver_preadv(BlockDriverState *bs, | ||
157 | - int64_t offset, int64_t bytes, | ||
158 | - QEMUIOVector *qiov, | ||
159 | - size_t qiov_offset, int flags) | ||
160 | +static int coroutine_fn GRAPH_RDLOCK | ||
161 | +bdrv_driver_preadv(BlockDriverState *bs, int64_t offset, int64_t bytes, | ||
162 | + QEMUIOVector *qiov, size_t qiov_offset, int flags) | ||
163 | { | ||
164 | BlockDriver *drv = bs->drv; | ||
165 | int64_t sector_num; | ||
166 | @@ -XXX,XX +XXX,XX @@ out: | ||
167 | return ret; | ||
168 | } | ||
169 | |||
170 | -static int coroutine_fn bdrv_driver_pwritev(BlockDriverState *bs, | ||
171 | - int64_t offset, int64_t bytes, | ||
172 | - QEMUIOVector *qiov, | ||
173 | - size_t qiov_offset, | ||
174 | - BdrvRequestFlags flags) | ||
175 | +static int coroutine_fn GRAPH_RDLOCK | ||
176 | +bdrv_driver_pwritev(BlockDriverState *bs, int64_t offset, int64_t bytes, | ||
177 | + QEMUIOVector *qiov, size_t qiov_offset, | ||
178 | + BdrvRequestFlags flags) | ||
179 | { | ||
180 | BlockDriver *drv = bs->drv; | ||
181 | bool emulate_fua = false; | ||
182 | @@ -XXX,XX +XXX,XX @@ static int coroutine_fn bdrv_driver_pwritev(BlockDriverState *bs, | ||
183 | QEMUIOVector local_qiov; | ||
184 | int ret; | ||
185 | |||
186 | - assume_graph_lock(); /* FIXME */ | ||
187 | - | ||
188 | bdrv_check_qiov_request(offset, bytes, qiov, qiov_offset, &error_abort); | ||
189 | |||
190 | if (!drv) { | ||
191 | @@ -XXX,XX +XXX,XX @@ emulate_flags: | ||
192 | return ret; | ||
193 | } | ||
194 | |||
195 | -static int coroutine_fn | ||
196 | +static int coroutine_fn GRAPH_RDLOCK | ||
197 | bdrv_driver_pwritev_compressed(BlockDriverState *bs, int64_t offset, | ||
198 | int64_t bytes, QEMUIOVector *qiov, | ||
199 | size_t qiov_offset) | ||
200 | @@ -XXX,XX +XXX,XX @@ bdrv_driver_pwritev_compressed(BlockDriverState *bs, int64_t offset, | ||
201 | return ret; | ||
202 | } | ||
203 | |||
204 | -static int coroutine_fn bdrv_co_do_copy_on_readv(BdrvChild *child, | ||
205 | - int64_t offset, int64_t bytes, QEMUIOVector *qiov, | ||
206 | - size_t qiov_offset, int flags) | ||
207 | +static int coroutine_fn GRAPH_RDLOCK | ||
208 | +bdrv_co_do_copy_on_readv(BdrvChild *child, int64_t offset, int64_t bytes, | ||
209 | + QEMUIOVector *qiov, size_t qiov_offset, int flags) | ||
210 | { | ||
211 | BlockDriverState *bs = child->bs; | ||
212 | |||
213 | @@ -XXX,XX +XXX,XX @@ static int coroutine_fn bdrv_co_do_copy_on_readv(BdrvChild *child, | ||
214 | int64_t progress = 0; | ||
215 | bool skip_write; | ||
216 | |||
217 | - assume_graph_lock(); /* FIXME */ | ||
218 | - | ||
219 | bdrv_check_qiov_request(offset, bytes, qiov, qiov_offset, &error_abort); | ||
220 | |||
221 | if (!drv) { | ||
222 | @@ -XXX,XX +XXX,XX @@ err: | ||
223 | * handles copy on read, zeroing after EOF, and fragmentation of large | ||
224 | * reads; any other features must be implemented by the caller. | ||
225 | */ | ||
226 | -static int coroutine_fn bdrv_aligned_preadv(BdrvChild *child, | ||
227 | - BdrvTrackedRequest *req, int64_t offset, int64_t bytes, | ||
228 | - int64_t align, QEMUIOVector *qiov, size_t qiov_offset, int flags) | ||
229 | +static int coroutine_fn GRAPH_RDLOCK | ||
230 | +bdrv_aligned_preadv(BdrvChild *child, BdrvTrackedRequest *req, | ||
231 | + int64_t offset, int64_t bytes, int64_t align, | ||
232 | + QEMUIOVector *qiov, size_t qiov_offset, int flags) | ||
233 | { | ||
234 | BlockDriverState *bs = child->bs; | ||
235 | int64_t total_bytes, max_bytes; | ||
236 | @@ -XXX,XX +XXX,XX @@ static bool bdrv_init_padding(BlockDriverState *bs, | ||
237 | return true; | ||
238 | } | ||
239 | |||
240 | -static coroutine_fn int bdrv_padding_rmw_read(BdrvChild *child, | ||
241 | - BdrvTrackedRequest *req, | ||
242 | - BdrvRequestPadding *pad, | ||
243 | - bool zero_middle) | ||
244 | +static int coroutine_fn GRAPH_RDLOCK | ||
245 | +bdrv_padding_rmw_read(BdrvChild *child, BdrvTrackedRequest *req, | ||
246 | + BdrvRequestPadding *pad, bool zero_middle) | ||
247 | { | ||
248 | QEMUIOVector local_qiov; | ||
249 | BlockDriverState *bs = child->bs; | ||
250 | @@ -XXX,XX +XXX,XX @@ int coroutine_fn bdrv_co_preadv_part(BdrvChild *child, | ||
251 | int ret; | ||
252 | IO_CODE(); | ||
253 | |||
254 | + assume_graph_lock(); /* FIXME */ | ||
255 | + | ||
256 | trace_bdrv_co_preadv_part(bs, offset, bytes, flags); | ||
257 | |||
258 | if (!bdrv_co_is_inserted(bs)) { | ||
259 | @@ -XXX,XX +XXX,XX @@ bdrv_co_write_req_finish(BdrvChild *child, int64_t offset, int64_t bytes, | ||
260 | * Forwards an already correctly aligned write request to the BlockDriver, | ||
261 | * after possibly fragmenting it. | ||
262 | */ | ||
263 | -static int coroutine_fn bdrv_aligned_pwritev(BdrvChild *child, | ||
264 | - BdrvTrackedRequest *req, int64_t offset, int64_t bytes, | ||
265 | - int64_t align, QEMUIOVector *qiov, size_t qiov_offset, | ||
266 | - BdrvRequestFlags flags) | ||
267 | +static int coroutine_fn GRAPH_RDLOCK | ||
268 | +bdrv_aligned_pwritev(BdrvChild *child, BdrvTrackedRequest *req, | ||
269 | + int64_t offset, int64_t bytes, int64_t align, | ||
270 | + QEMUIOVector *qiov, size_t qiov_offset, | ||
271 | + BdrvRequestFlags flags) | ||
272 | { | ||
273 | BlockDriverState *bs = child->bs; | ||
274 | BlockDriver *drv = bs->drv; | ||
275 | @@ -XXX,XX +XXX,XX @@ static int coroutine_fn bdrv_aligned_pwritev(BdrvChild *child, | ||
276 | int64_t bytes_remaining = bytes; | ||
277 | int max_transfer; | ||
278 | |||
279 | - assume_graph_lock(); /* FIXME */ | ||
280 | - | ||
281 | bdrv_check_qiov_request(offset, bytes, qiov, qiov_offset, &error_abort); | ||
282 | |||
283 | if (!drv) { | ||
284 | @@ -XXX,XX +XXX,XX @@ static int coroutine_fn bdrv_aligned_pwritev(BdrvChild *child, | ||
285 | return ret; | ||
286 | } | ||
287 | |||
288 | -static int coroutine_fn bdrv_co_do_zero_pwritev(BdrvChild *child, | ||
289 | - int64_t offset, | ||
290 | - int64_t bytes, | ||
291 | - BdrvRequestFlags flags, | ||
292 | - BdrvTrackedRequest *req) | ||
293 | +static int coroutine_fn GRAPH_RDLOCK | ||
294 | +bdrv_co_do_zero_pwritev(BdrvChild *child, int64_t offset, int64_t bytes, | ||
295 | + BdrvRequestFlags flags, BdrvTrackedRequest *req) | ||
296 | { | ||
297 | BlockDriverState *bs = child->bs; | ||
298 | QEMUIOVector local_qiov; | ||
299 | @@ -XXX,XX +XXX,XX @@ int coroutine_fn bdrv_co_pwritev_part(BdrvChild *child, | ||
300 | bool padded = false; | ||
301 | IO_CODE(); | ||
302 | |||
303 | + assume_graph_lock(); /* FIXME */ | ||
304 | + | ||
305 | trace_bdrv_co_pwritev_part(child->bs, offset, bytes, flags); | ||
306 | |||
307 | if (!bdrv_co_is_inserted(bs)) { | ||
308 | diff --git a/block/parallels.c b/block/parallels.c | ||
309 | index XXXXXXX..XXXXXXX 100644 | ||
310 | --- a/block/parallels.c | ||
311 | +++ b/block/parallels.c | ||
312 | @@ -XXX,XX +XXX,XX @@ static int coroutine_fn parallels_co_block_status(BlockDriverState *bs, | ||
313 | return BDRV_BLOCK_DATA | BDRV_BLOCK_OFFSET_VALID; | ||
314 | } | ||
315 | |||
316 | -static coroutine_fn int parallels_co_writev(BlockDriverState *bs, | ||
317 | - int64_t sector_num, int nb_sectors, | ||
318 | - QEMUIOVector *qiov, int flags) | ||
319 | +static int coroutine_fn GRAPH_RDLOCK | ||
320 | +parallels_co_writev(BlockDriverState *bs, int64_t sector_num, int nb_sectors, | ||
321 | + QEMUIOVector *qiov, int flags) | ||
322 | { | ||
323 | BDRVParallelsState *s = bs->opaque; | ||
324 | uint64_t bytes_done = 0; | ||
325 | QEMUIOVector hd_qiov; | ||
326 | int ret = 0; | ||
327 | |||
328 | - assume_graph_lock(); /* FIXME */ | ||
329 | - | ||
330 | qemu_iovec_init(&hd_qiov, qiov->niov); | ||
331 | |||
332 | while (nb_sectors > 0) { | ||
333 | diff --git a/block/qcow.c b/block/qcow.c | ||
334 | index XXXXXXX..XXXXXXX 100644 | ||
335 | --- a/block/qcow.c | ||
336 | +++ b/block/qcow.c | ||
337 | @@ -XXX,XX +XXX,XX @@ static void qcow_refresh_limits(BlockDriverState *bs, Error **errp) | ||
338 | bs->bl.request_alignment = BDRV_SECTOR_SIZE; | ||
339 | } | ||
340 | |||
341 | -static coroutine_fn int qcow_co_preadv(BlockDriverState *bs, int64_t offset, | ||
342 | - int64_t bytes, QEMUIOVector *qiov, | ||
343 | - BdrvRequestFlags flags) | ||
344 | +static int coroutine_fn GRAPH_RDLOCK | ||
345 | +qcow_co_preadv(BlockDriverState *bs, int64_t offset, int64_t bytes, | ||
346 | + QEMUIOVector *qiov, BdrvRequestFlags flags) | ||
347 | { | ||
348 | BDRVQcowState *s = bs->opaque; | ||
349 | int offset_in_cluster; | ||
350 | @@ -XXX,XX +XXX,XX @@ static coroutine_fn int qcow_co_preadv(BlockDriverState *bs, int64_t offset, | ||
351 | uint8_t *buf; | ||
352 | void *orig_buf; | ||
353 | |||
354 | - assume_graph_lock(); /* FIXME */ | ||
355 | - | ||
356 | if (qiov->niov > 1) { | ||
357 | buf = orig_buf = qemu_try_blockalign(bs, qiov->size); | ||
358 | if (buf == NULL) { | ||
359 | @@ -XXX,XX +XXX,XX @@ static coroutine_fn int qcow_co_preadv(BlockDriverState *bs, int64_t offset, | ||
360 | return ret; | ||
361 | } | ||
362 | |||
363 | -static coroutine_fn int qcow_co_pwritev(BlockDriverState *bs, int64_t offset, | ||
364 | - int64_t bytes, QEMUIOVector *qiov, | ||
365 | - BdrvRequestFlags flags) | ||
366 | +static int coroutine_fn GRAPH_RDLOCK | ||
367 | +qcow_co_pwritev(BlockDriverState *bs, int64_t offset, int64_t bytes, | ||
368 | + QEMUIOVector *qiov, BdrvRequestFlags flags) | ||
369 | { | ||
370 | BDRVQcowState *s = bs->opaque; | ||
371 | int offset_in_cluster; | ||
372 | @@ -XXX,XX +XXX,XX @@ static coroutine_fn int qcow_co_pwritev(BlockDriverState *bs, int64_t offset, | ||
373 | uint8_t *buf; | ||
374 | void *orig_buf; | ||
375 | |||
376 | - assume_graph_lock(); /* FIXME */ | ||
377 | - | ||
378 | s->cluster_cache_offset = -1; /* disable compressed cache */ | ||
379 | |||
380 | /* We must always copy the iov when encrypting, so we | ||
381 | @@ -XXX,XX +XXX,XX @@ static int qcow_make_empty(BlockDriverState *bs) | ||
382 | |||
383 | /* XXX: put compressed sectors first, then all the cluster aligned | ||
384 | tables to avoid losing bytes in alignment */ | ||
385 | -static coroutine_fn int | ||
386 | +static int coroutine_fn GRAPH_RDLOCK | ||
387 | qcow_co_pwritev_compressed(BlockDriverState *bs, int64_t offset, int64_t bytes, | ||
388 | QEMUIOVector *qiov) | ||
389 | { | ||
390 | @@ -XXX,XX +XXX,XX @@ qcow_co_pwritev_compressed(BlockDriverState *bs, int64_t offset, int64_t bytes, | ||
391 | uint8_t *buf, *out_buf; | ||
392 | uint64_t cluster_offset; | ||
393 | |||
394 | - assume_graph_lock(); /* FIXME */ | ||
395 | - | ||
396 | buf = qemu_blockalign(bs, s->cluster_size); | ||
397 | if (bytes != s->cluster_size) { | ||
398 | if (bytes > s->cluster_size || | ||
399 | diff --git a/block/qcow2-cluster.c b/block/qcow2-cluster.c | ||
400 | index XXXXXXX..XXXXXXX 100644 | ||
401 | --- a/block/qcow2-cluster.c | ||
402 | +++ b/block/qcow2-cluster.c | ||
403 | @@ -XXX,XX +XXX,XX @@ static int count_contiguous_subclusters(BlockDriverState *bs, int nb_clusters, | ||
404 | return count; | ||
405 | } | ||
406 | |||
407 | -static int coroutine_fn do_perform_cow_read(BlockDriverState *bs, | ||
408 | - uint64_t src_cluster_offset, | ||
409 | - unsigned offset_in_cluster, | ||
410 | - QEMUIOVector *qiov) | ||
411 | +static int coroutine_fn GRAPH_RDLOCK | ||
412 | +do_perform_cow_read(BlockDriverState *bs, uint64_t src_cluster_offset, | ||
413 | + unsigned offset_in_cluster, QEMUIOVector *qiov) | ||
414 | { | ||
415 | int ret; | ||
416 | |||
417 | @@ -XXX,XX +XXX,XX @@ int coroutine_fn qcow2_alloc_compressed_cluster_offset(BlockDriverState *bs, | ||
418 | return 0; | ||
419 | } | ||
420 | |||
421 | -static int coroutine_fn perform_cow(BlockDriverState *bs, QCowL2Meta *m) | ||
422 | +static int coroutine_fn GRAPH_RDLOCK | ||
423 | +perform_cow(BlockDriverState *bs, QCowL2Meta *m) | ||
424 | { | ||
425 | BDRVQcow2State *s = bs->opaque; | ||
426 | Qcow2COWRegion *start = &m->cow_start; | ||
427 | diff --git a/block/qcow2.c b/block/qcow2.c | ||
428 | index XXXXXXX..XXXXXXX 100644 | ||
429 | --- a/block/qcow2.c | ||
430 | +++ b/block/qcow2.c | ||
431 | @@ -XXX,XX +XXX,XX @@ static int coroutine_fn qcow2_co_block_status(BlockDriverState *bs, | ||
432 | return status; | ||
433 | } | ||
434 | |||
435 | -static coroutine_fn int qcow2_handle_l2meta(BlockDriverState *bs, | ||
436 | - QCowL2Meta **pl2meta, | ||
437 | - bool link_l2) | ||
438 | +static int coroutine_fn GRAPH_RDLOCK | ||
439 | +qcow2_handle_l2meta(BlockDriverState *bs, QCowL2Meta **pl2meta, bool link_l2) | ||
440 | { | ||
441 | int ret = 0; | ||
442 | QCowL2Meta *l2meta = *pl2meta; | ||
443 | @@ -XXX,XX +XXX,XX @@ static coroutine_fn GRAPH_RDLOCK int qcow2_co_pwritev_task_entry(AioTask *task) | ||
444 | t->l2meta); | ||
445 | } | ||
446 | |||
447 | -static coroutine_fn int qcow2_co_pwritev_part( | ||
448 | - BlockDriverState *bs, int64_t offset, int64_t bytes, | ||
449 | - QEMUIOVector *qiov, size_t qiov_offset, BdrvRequestFlags flags) | ||
450 | +static int coroutine_fn GRAPH_RDLOCK | ||
451 | +qcow2_co_pwritev_part(BlockDriverState *bs, int64_t offset, int64_t bytes, | ||
452 | + QEMUIOVector *qiov, size_t qiov_offset, | ||
453 | + BdrvRequestFlags flags) | ||
454 | { | ||
455 | BDRVQcow2State *s = bs->opaque; | ||
456 | int offset_in_cluster; | ||
457 | @@ -XXX,XX +XXX,XX @@ static coroutine_fn int qcow2_co_pwritev_part( | ||
458 | QCowL2Meta *l2meta = NULL; | ||
459 | AioTaskPool *aio = NULL; | ||
460 | |||
461 | - assume_graph_lock(); /* FIXME */ | ||
462 | - | ||
463 | trace_qcow2_writev_start_req(qemu_coroutine_self(), offset, bytes); | ||
464 | |||
465 | while (bytes != 0 && aio_task_pool_status(aio) == 0) { | ||
466 | @@ -XXX,XX +XXX,XX @@ qcow2_co_copy_range_to(BlockDriverState *bs, | ||
467 | uint64_t host_offset; | ||
468 | QCowL2Meta *l2meta = NULL; | ||
469 | |||
470 | + assume_graph_lock(); /* FIXME */ | ||
471 | assert(!bs->encrypted); | ||
472 | |||
473 | qemu_co_mutex_lock(&s->lock); | ||
474 | @@ -XXX,XX +XXX,XX @@ fail: | ||
475 | return ret; | ||
476 | } | ||
477 | |||
478 | -static coroutine_fn int | ||
479 | +static int coroutine_fn GRAPH_RDLOCK | ||
480 | qcow2_co_pwritev_compressed_task(BlockDriverState *bs, | ||
481 | uint64_t offset, uint64_t bytes, | ||
482 | QEMUIOVector *qiov, size_t qiov_offset) | ||
483 | @@ -XXX,XX +XXX,XX @@ fail: | ||
484 | return ret; | ||
485 | } | ||
486 | |||
487 | -static coroutine_fn int qcow2_co_pwritev_compressed_task_entry(AioTask *task) | ||
488 | +/* | ||
489 | + * This function can count as GRAPH_RDLOCK because | ||
490 | + * qcow2_co_pwritev_compressed_part() holds the graph lock and keeps it until | ||
491 | + * this coroutine has terminated. | ||
492 | + */ | ||
493 | +static int coroutine_fn GRAPH_RDLOCK | ||
494 | +qcow2_co_pwritev_compressed_task_entry(AioTask *task) | ||
495 | { | ||
496 | Qcow2AioTask *t = container_of(task, Qcow2AioTask, task); | ||
497 | |||
498 | @@ -XXX,XX +XXX,XX @@ static coroutine_fn int qcow2_co_pwritev_compressed_task_entry(AioTask *task) | ||
499 | * XXX: put compressed sectors first, then all the cluster aligned | ||
500 | * tables to avoid losing bytes in alignment | ||
501 | */ | ||
502 | -static coroutine_fn int | ||
503 | +static int coroutine_fn GRAPH_RDLOCK | ||
504 | qcow2_co_pwritev_compressed_part(BlockDriverState *bs, | ||
505 | int64_t offset, int64_t bytes, | ||
506 | QEMUIOVector *qiov, size_t qiov_offset) | ||
507 | @@ -XXX,XX +XXX,XX @@ qcow2_co_pwritev_compressed_part(BlockDriverState *bs, | ||
508 | AioTaskPool *aio = NULL; | ||
509 | int ret = 0; | ||
510 | |||
511 | - assume_graph_lock(); /* FIXME */ | ||
512 | - | ||
513 | if (has_data_file(bs)) { | ||
514 | return -ENOTSUP; | ||
515 | } | ||
516 | @@ -XXX,XX +XXX,XX @@ static int64_t qcow2_check_vmstate_request(BlockDriverState *bs, | ||
517 | return pos; | ||
518 | } | ||
519 | |||
520 | -static coroutine_fn int qcow2_co_save_vmstate(BlockDriverState *bs, | ||
521 | - QEMUIOVector *qiov, int64_t pos) | ||
522 | +static int coroutine_fn GRAPH_RDLOCK | ||
523 | +qcow2_co_save_vmstate(BlockDriverState *bs, QEMUIOVector *qiov, int64_t pos) | ||
524 | { | ||
525 | int64_t offset = qcow2_check_vmstate_request(bs, qiov, pos); | ||
526 | if (offset < 0) { | ||
527 | @@ -XXX,XX +XXX,XX @@ static coroutine_fn int qcow2_co_save_vmstate(BlockDriverState *bs, | ||
528 | return bs->drv->bdrv_co_pwritev_part(bs, offset, qiov->size, qiov, 0, 0); | ||
529 | } | ||
530 | |||
531 | -static coroutine_fn int qcow2_co_load_vmstate(BlockDriverState *bs, | ||
532 | - QEMUIOVector *qiov, int64_t pos) | ||
533 | +static int coroutine_fn GRAPH_RDLOCK | ||
534 | +qcow2_co_load_vmstate(BlockDriverState *bs, QEMUIOVector *qiov, int64_t pos) | ||
535 | { | ||
536 | int64_t offset = qcow2_check_vmstate_request(bs, qiov, pos); | ||
537 | if (offset < 0) { | ||
538 | diff --git a/block/qed.c b/block/qed.c | ||
539 | index XXXXXXX..XXXXXXX 100644 | ||
540 | --- a/block/qed.c | ||
541 | +++ b/block/qed.c | ||
542 | @@ -XXX,XX +XXX,XX @@ qed_co_request(BlockDriverState *bs, int64_t sector_num, QEMUIOVector *qiov, | ||
543 | return qed_aio_next_io(&acb); | ||
544 | } | ||
545 | |||
546 | -static int coroutine_fn bdrv_qed_co_readv(BlockDriverState *bs, | ||
547 | - int64_t sector_num, int nb_sectors, | ||
548 | - QEMUIOVector *qiov) | ||
549 | +static int coroutine_fn GRAPH_RDLOCK | ||
550 | +bdrv_qed_co_readv(BlockDriverState *bs, int64_t sector_num, int nb_sectors, | ||
551 | + QEMUIOVector *qiov) | ||
552 | { | ||
553 | - assume_graph_lock(); /* FIXME */ | ||
554 | return qed_co_request(bs, sector_num, qiov, nb_sectors, 0); | ||
555 | } | ||
556 | |||
557 | -static int coroutine_fn bdrv_qed_co_writev(BlockDriverState *bs, | ||
558 | - int64_t sector_num, int nb_sectors, | ||
559 | - QEMUIOVector *qiov, int flags) | ||
560 | +static int coroutine_fn GRAPH_RDLOCK | ||
561 | +bdrv_qed_co_writev(BlockDriverState *bs, int64_t sector_num, int nb_sectors, | ||
562 | + QEMUIOVector *qiov, int flags) | ||
563 | { | ||
564 | - assume_graph_lock(); /* FIXME */ | ||
565 | return qed_co_request(bs, sector_num, qiov, nb_sectors, QED_AIOCB_WRITE); | ||
566 | } | ||
567 | |||
568 | diff --git a/block/quorum.c b/block/quorum.c | ||
569 | index XXXXXXX..XXXXXXX 100644 | ||
570 | --- a/block/quorum.c | ||
571 | +++ b/block/quorum.c | ||
572 | @@ -XXX,XX +XXX,XX @@ static void coroutine_fn GRAPH_RDLOCK write_quorum_entry(void *opaque) | ||
573 | } | ||
574 | } | ||
575 | |||
576 | -static int coroutine_fn quorum_co_pwritev(BlockDriverState *bs, int64_t offset, | ||
577 | - int64_t bytes, QEMUIOVector *qiov, | ||
578 | - BdrvRequestFlags flags) | ||
579 | +static int coroutine_fn GRAPH_RDLOCK | ||
580 | +quorum_co_pwritev(BlockDriverState *bs, int64_t offset, int64_t bytes, | ||
581 | + QEMUIOVector *qiov, BdrvRequestFlags flags) | ||
582 | { | ||
583 | BDRVQuorumState *s = bs->opaque; | ||
584 | QuorumAIOCB *acb = quorum_aio_get(bs, qiov, offset, bytes, flags); | ||
585 | int i, ret; | ||
586 | |||
587 | - assume_graph_lock(); /* FIXME */ | ||
588 | - | ||
589 | for (i = 0; i < s->num_children; i++) { | ||
590 | Coroutine *co; | ||
591 | QuorumCo data = { | ||
592 | diff --git a/block/vmdk.c b/block/vmdk.c | ||
593 | index XXXXXXX..XXXXXXX 100644 | ||
594 | --- a/block/vmdk.c | ||
595 | +++ b/block/vmdk.c | ||
596 | @@ -XXX,XX +XXX,XX @@ vmdk_co_pwritev(BlockDriverState *bs, int64_t offset, int64_t bytes, | ||
597 | return ret; | ||
598 | } | ||
599 | |||
600 | -static int coroutine_fn | ||
601 | +static int coroutine_fn GRAPH_RDLOCK | ||
602 | vmdk_co_pwritev_compressed(BlockDriverState *bs, int64_t offset, int64_t bytes, | ||
603 | QEMUIOVector *qiov) | ||
604 | { | ||
605 | - assume_graph_lock(); /* FIXME */ | ||
606 | - | ||
607 | if (bytes == 0) { | ||
608 | /* The caller will write bytes 0 to signal EOF. | ||
609 | * When receive it, we align EOF to a sector boundary. */ | ||
610 | -- | ||
611 | 2.39.2 | diff view generated by jsdifflib |
Deleted patch | |||
---|---|---|---|
1 | This adds GRAPH_RDLOCK annotations to declare that callers of | ||
2 | bdrv_co_pread*/pwrite*() need to hold a reader lock for the graph. | ||
3 | 1 | ||
4 | For some places, we know that they will hold the lock, but we don't have | ||
5 | the GRAPH_RDLOCK annotations yet. In this case, add assume_graph_lock() | ||
6 | with a FIXME comment. These places will be removed once everything is | ||
7 | properly annotated. | ||
8 | |||
9 | Signed-off-by: Kevin Wolf <kwolf@redhat.com> | ||
10 | Message-Id: <20230203152202.49054-12-kwolf@redhat.com> | ||
11 | Reviewed-by: Emanuele Giuseppe Esposito <eesposit@redhat.com> | ||
12 | Signed-off-by: Kevin Wolf <kwolf@redhat.com> | ||
13 | --- | ||
14 | block/qcow2.h | 9 ++--- | ||
15 | block/qed.h | 18 +++++----- | ||
16 | include/block/block_int-io.h | 14 ++++---- | ||
17 | block/blkdebug.c | 4 +-- | ||
18 | block/blklogwrites.c | 7 ++-- | ||
19 | block/blkreplay.c | 10 +++--- | ||
20 | block/block-backend.c | 2 ++ | ||
21 | block/bochs.c | 2 +- | ||
22 | block/commit.c | 5 +-- | ||
23 | block/copy-before-write.c | 16 ++++----- | ||
24 | block/copy-on-read.c | 26 ++++++--------- | ||
25 | block/crypto.c | 4 +-- | ||
26 | block/filter-compress.c | 19 +++++------ | ||
27 | block/io.c | 7 ++-- | ||
28 | block/mirror.c | 18 +++++----- | ||
29 | block/parallels.c | 8 +++-- | ||
30 | block/preallocate.c | 18 +++++----- | ||
31 | block/qcow.c | 8 ++--- | ||
32 | block/qcow2-cluster.c | 7 ++-- | ||
33 | block/qcow2.c | 53 +++++++++++++++-------------- | ||
34 | block/qed-table.c | 4 +-- | ||
35 | block/qed.c | 31 +++++++++-------- | ||
36 | block/quorum.c | 29 ++++++++++------ | ||
37 | block/raw-format.c | 12 +++---- | ||
38 | block/replication.c | 15 ++++----- | ||
39 | block/throttle.c | 21 +++++------- | ||
40 | block/vdi.c | 4 +-- | ||
41 | block/vhdx.c | 11 +++--- | ||
42 | block/vmdk.c | 65 +++++++++++++++--------------------- | ||
43 | block/vpc.c | 4 +-- | ||
44 | tests/unit/test-bdrv-drain.c | 20 ++++++----- | ||
45 | 31 files changed, 233 insertions(+), 238 deletions(-) | ||
46 | |||
47 | diff --git a/block/qcow2.h b/block/qcow2.h | ||
48 | index XXXXXXX..XXXXXXX 100644 | ||
49 | --- a/block/qcow2.h | ||
50 | +++ b/block/qcow2.h | ||
51 | @@ -XXX,XX +XXX,XX @@ int qcow2_validate_table(BlockDriverState *bs, uint64_t offset, | ||
52 | Error **errp); | ||
53 | |||
54 | /* qcow2-refcount.c functions */ | ||
55 | -int coroutine_fn qcow2_refcount_init(BlockDriverState *bs); | ||
56 | +int coroutine_fn GRAPH_RDLOCK qcow2_refcount_init(BlockDriverState *bs); | ||
57 | void qcow2_refcount_close(BlockDriverState *bs); | ||
58 | |||
59 | int qcow2_get_refcount(BlockDriverState *bs, int64_t cluster_index, | ||
60 | @@ -XXX,XX +XXX,XX @@ void qcow2_free_snapshots(BlockDriverState *bs); | ||
61 | int qcow2_read_snapshots(BlockDriverState *bs, Error **errp); | ||
62 | int qcow2_write_snapshots(BlockDriverState *bs); | ||
63 | |||
64 | -int coroutine_fn qcow2_check_read_snapshot_table(BlockDriverState *bs, | ||
65 | - BdrvCheckResult *result, | ||
66 | - BdrvCheckMode fix); | ||
67 | +int coroutine_fn GRAPH_RDLOCK | ||
68 | +qcow2_check_read_snapshot_table(BlockDriverState *bs, BdrvCheckResult *result, | ||
69 | + BdrvCheckMode fix); | ||
70 | + | ||
71 | int coroutine_fn qcow2_check_fix_snapshot_table(BlockDriverState *bs, | ||
72 | BdrvCheckResult *result, | ||
73 | BdrvCheckMode fix); | ||
74 | diff --git a/block/qed.h b/block/qed.h | ||
75 | index XXXXXXX..XXXXXXX 100644 | ||
76 | --- a/block/qed.h | ||
77 | +++ b/block/qed.h | ||
78 | @@ -XXX,XX +XXX,XX @@ void qed_commit_l2_cache_entry(L2TableCache *l2_cache, CachedL2Table *l2_table); | ||
79 | /** | ||
80 | * Table I/O functions | ||
81 | */ | ||
82 | -int coroutine_fn qed_read_l1_table_sync(BDRVQEDState *s); | ||
83 | +int coroutine_fn GRAPH_RDLOCK qed_read_l1_table_sync(BDRVQEDState *s); | ||
84 | |||
85 | int coroutine_fn GRAPH_RDLOCK | ||
86 | qed_write_l1_table(BDRVQEDState *s, unsigned int index, unsigned int n); | ||
87 | @@ -XXX,XX +XXX,XX @@ qed_write_l1_table(BDRVQEDState *s, unsigned int index, unsigned int n); | ||
88 | int coroutine_fn GRAPH_RDLOCK | ||
89 | qed_write_l1_table_sync(BDRVQEDState *s, unsigned int index, unsigned int n); | ||
90 | |||
91 | -int coroutine_fn qed_read_l2_table_sync(BDRVQEDState *s, QEDRequest *request, | ||
92 | - uint64_t offset); | ||
93 | -int coroutine_fn qed_read_l2_table(BDRVQEDState *s, QEDRequest *request, | ||
94 | - uint64_t offset); | ||
95 | +int coroutine_fn GRAPH_RDLOCK | ||
96 | +qed_read_l2_table_sync(BDRVQEDState *s, QEDRequest *request, uint64_t offset); | ||
97 | + | ||
98 | +int coroutine_fn GRAPH_RDLOCK | ||
99 | +qed_read_l2_table(BDRVQEDState *s, QEDRequest *request, uint64_t offset); | ||
100 | |||
101 | int coroutine_fn GRAPH_RDLOCK | ||
102 | qed_write_l2_table(BDRVQEDState *s, QEDRequest *request, unsigned int index, | ||
103 | @@ -XXX,XX +XXX,XX @@ qed_write_l2_table_sync(BDRVQEDState *s, QEDRequest *request, | ||
104 | /** | ||
105 | * Cluster functions | ||
106 | */ | ||
107 | -int coroutine_fn qed_find_cluster(BDRVQEDState *s, QEDRequest *request, | ||
108 | - uint64_t pos, size_t *len, | ||
109 | - uint64_t *img_offset); | ||
110 | +int coroutine_fn GRAPH_RDLOCK | ||
111 | +qed_find_cluster(BDRVQEDState *s, QEDRequest *request, uint64_t pos, | ||
112 | + size_t *len, uint64_t *img_offset); | ||
113 | |||
114 | /** | ||
115 | * Consistency check | ||
116 | @@ -XXX,XX +XXX,XX @@ int coroutine_fn qed_find_cluster(BDRVQEDState *s, QEDRequest *request, | ||
117 | int coroutine_fn GRAPH_RDLOCK | ||
118 | qed_check(BDRVQEDState *s, BdrvCheckResult *result, bool fix); | ||
119 | |||
120 | - | ||
121 | QEDTable *qed_alloc_table(BDRVQEDState *s); | ||
122 | |||
123 | /** | ||
124 | diff --git a/include/block/block_int-io.h b/include/block/block_int-io.h | ||
125 | index XXXXXXX..XXXXXXX 100644 | ||
126 | --- a/include/block/block_int-io.h | ||
127 | +++ b/include/block/block_int-io.h | ||
128 | @@ -XXX,XX +XXX,XX @@ int coroutine_fn GRAPH_RDLOCK bdrv_co_pdiscard_snapshot(BlockDriverState *bs, | ||
129 | int64_t offset, int64_t bytes); | ||
130 | |||
131 | |||
132 | -int coroutine_fn bdrv_co_preadv(BdrvChild *child, | ||
133 | +int coroutine_fn GRAPH_RDLOCK bdrv_co_preadv(BdrvChild *child, | ||
134 | int64_t offset, int64_t bytes, QEMUIOVector *qiov, | ||
135 | BdrvRequestFlags flags); | ||
136 | -int coroutine_fn bdrv_co_preadv_part(BdrvChild *child, | ||
137 | +int coroutine_fn GRAPH_RDLOCK bdrv_co_preadv_part(BdrvChild *child, | ||
138 | int64_t offset, int64_t bytes, | ||
139 | QEMUIOVector *qiov, size_t qiov_offset, BdrvRequestFlags flags); | ||
140 | -int coroutine_fn bdrv_co_pwritev(BdrvChild *child, | ||
141 | +int coroutine_fn GRAPH_RDLOCK bdrv_co_pwritev(BdrvChild *child, | ||
142 | int64_t offset, int64_t bytes, QEMUIOVector *qiov, | ||
143 | BdrvRequestFlags flags); | ||
144 | -int coroutine_fn bdrv_co_pwritev_part(BdrvChild *child, | ||
145 | +int coroutine_fn GRAPH_RDLOCK bdrv_co_pwritev_part(BdrvChild *child, | ||
146 | int64_t offset, int64_t bytes, | ||
147 | QEMUIOVector *qiov, size_t qiov_offset, BdrvRequestFlags flags); | ||
148 | |||
149 | -static inline int coroutine_fn bdrv_co_pread(BdrvChild *child, | ||
150 | +static inline int coroutine_fn GRAPH_RDLOCK bdrv_co_pread(BdrvChild *child, | ||
151 | int64_t offset, int64_t bytes, void *buf, BdrvRequestFlags flags) | ||
152 | { | ||
153 | QEMUIOVector qiov = QEMU_IOVEC_INIT_BUF(qiov, buf, bytes); | ||
154 | IO_CODE(); | ||
155 | + assert_bdrv_graph_readable(); | ||
156 | |||
157 | return bdrv_co_preadv(child, offset, bytes, &qiov, flags); | ||
158 | } | ||
159 | |||
160 | -static inline int coroutine_fn bdrv_co_pwrite(BdrvChild *child, | ||
161 | +static inline int coroutine_fn GRAPH_RDLOCK bdrv_co_pwrite(BdrvChild *child, | ||
162 | int64_t offset, int64_t bytes, const void *buf, BdrvRequestFlags flags) | ||
163 | { | ||
164 | QEMUIOVector qiov = QEMU_IOVEC_INIT_BUF(qiov, buf, bytes); | ||
165 | IO_CODE(); | ||
166 | + assert_bdrv_graph_readable(); | ||
167 | |||
168 | return bdrv_co_pwritev(child, offset, bytes, &qiov, flags); | ||
169 | } | ||
170 | diff --git a/block/blkdebug.c b/block/blkdebug.c | ||
171 | index XXXXXXX..XXXXXXX 100644 | ||
172 | --- a/block/blkdebug.c | ||
173 | +++ b/block/blkdebug.c | ||
174 | @@ -XXX,XX +XXX,XX @@ static int rule_check(BlockDriverState *bs, uint64_t offset, uint64_t bytes, | ||
175 | return -error; | ||
176 | } | ||
177 | |||
178 | -static int coroutine_fn | ||
179 | +static int coroutine_fn GRAPH_RDLOCK | ||
180 | blkdebug_co_preadv(BlockDriverState *bs, int64_t offset, int64_t bytes, | ||
181 | QEMUIOVector *qiov, BdrvRequestFlags flags) | ||
182 | { | ||
183 | @@ -XXX,XX +XXX,XX @@ blkdebug_co_preadv(BlockDriverState *bs, int64_t offset, int64_t bytes, | ||
184 | return bdrv_co_preadv(bs->file, offset, bytes, qiov, flags); | ||
185 | } | ||
186 | |||
187 | -static int coroutine_fn | ||
188 | +static int coroutine_fn GRAPH_RDLOCK | ||
189 | blkdebug_co_pwritev(BlockDriverState *bs, int64_t offset, int64_t bytes, | ||
190 | QEMUIOVector *qiov, BdrvRequestFlags flags) | ||
191 | { | ||
192 | diff --git a/block/blklogwrites.c b/block/blklogwrites.c | ||
193 | index XXXXXXX..XXXXXXX 100644 | ||
194 | --- a/block/blklogwrites.c | ||
195 | +++ b/block/blklogwrites.c | ||
196 | @@ -XXX,XX +XXX,XX @@ static void blk_log_writes_refresh_limits(BlockDriverState *bs, Error **errp) | ||
197 | bs->bl.request_alignment = s->sectorsize; | ||
198 | } | ||
199 | |||
200 | -static int coroutine_fn | ||
201 | +static int coroutine_fn GRAPH_RDLOCK | ||
202 | blk_log_writes_co_preadv(BlockDriverState *bs, int64_t offset, int64_t bytes, | ||
203 | QEMUIOVector *qiov, BdrvRequestFlags flags) | ||
204 | { | ||
205 | @@ -XXX,XX +XXX,XX @@ blk_log_writes_co_log(BlockDriverState *bs, uint64_t offset, uint64_t bytes, | ||
206 | return fr.file_ret; | ||
207 | } | ||
208 | |||
209 | -static int coroutine_fn | ||
210 | +static int coroutine_fn GRAPH_RDLOCK | ||
211 | blk_log_writes_co_do_file_pwritev(BlkLogWritesFileReq *fr) | ||
212 | { | ||
213 | return bdrv_co_pwritev(fr->bs->file, fr->offset, fr->bytes, | ||
214 | @@ -XXX,XX +XXX,XX @@ blk_log_writes_co_do_file_pdiscard(BlkLogWritesFileReq *fr) | ||
215 | return bdrv_co_pdiscard(fr->bs->file, fr->offset, fr->bytes); | ||
216 | } | ||
217 | |||
218 | -static int coroutine_fn | ||
219 | +static int coroutine_fn GRAPH_RDLOCK | ||
220 | blk_log_writes_co_pwritev(BlockDriverState *bs, int64_t offset, int64_t bytes, | ||
221 | QEMUIOVector *qiov, BdrvRequestFlags flags) | ||
222 | { | ||
223 | - assume_graph_lock(); /* FIXME */ | ||
224 | return blk_log_writes_co_log(bs, offset, bytes, qiov, flags, | ||
225 | blk_log_writes_co_do_file_pwritev, 0, false); | ||
226 | } | ||
227 | diff --git a/block/blkreplay.c b/block/blkreplay.c | ||
228 | index XXXXXXX..XXXXXXX 100644 | ||
229 | --- a/block/blkreplay.c | ||
230 | +++ b/block/blkreplay.c | ||
231 | @@ -XXX,XX +XXX,XX @@ static void block_request_create(uint64_t reqid, BlockDriverState *bs, | ||
232 | replay_block_event(req->bh, reqid); | ||
233 | } | ||
234 | |||
235 | -static int coroutine_fn blkreplay_co_preadv(BlockDriverState *bs, | ||
236 | - int64_t offset, int64_t bytes, QEMUIOVector *qiov, BdrvRequestFlags flags) | ||
237 | +static int coroutine_fn GRAPH_RDLOCK | ||
238 | +blkreplay_co_preadv(BlockDriverState *bs, int64_t offset, int64_t bytes, | ||
239 | + QEMUIOVector *qiov, BdrvRequestFlags flags) | ||
240 | { | ||
241 | uint64_t reqid = blkreplay_next_id(); | ||
242 | int ret = bdrv_co_preadv(bs->file, offset, bytes, qiov, flags); | ||
243 | @@ -XXX,XX +XXX,XX @@ static int coroutine_fn blkreplay_co_preadv(BlockDriverState *bs, | ||
244 | return ret; | ||
245 | } | ||
246 | |||
247 | -static int coroutine_fn blkreplay_co_pwritev(BlockDriverState *bs, | ||
248 | - int64_t offset, int64_t bytes, QEMUIOVector *qiov, BdrvRequestFlags flags) | ||
249 | +static int coroutine_fn GRAPH_RDLOCK | ||
250 | +blkreplay_co_pwritev(BlockDriverState *bs, int64_t offset, int64_t bytes, | ||
251 | + QEMUIOVector *qiov, BdrvRequestFlags flags) | ||
252 | { | ||
253 | uint64_t reqid = blkreplay_next_id(); | ||
254 | int ret = bdrv_co_pwritev(bs->file, offset, bytes, qiov, flags); | ||
255 | diff --git a/block/block-backend.c b/block/block-backend.c | ||
256 | index XXXXXXX..XXXXXXX 100644 | ||
257 | --- a/block/block-backend.c | ||
258 | +++ b/block/block-backend.c | ||
259 | @@ -XXX,XX +XXX,XX @@ blk_co_do_preadv_part(BlockBackend *blk, int64_t offset, int64_t bytes, | ||
260 | IO_CODE(); | ||
261 | |||
262 | blk_wait_while_drained(blk); | ||
263 | + GRAPH_RDLOCK_GUARD(); | ||
264 | |||
265 | /* Call blk_bs() only after waiting, the graph may have changed */ | ||
266 | bs = blk_bs(blk); | ||
267 | @@ -XXX,XX +XXX,XX @@ blk_co_do_pwritev_part(BlockBackend *blk, int64_t offset, int64_t bytes, | ||
268 | IO_CODE(); | ||
269 | |||
270 | blk_wait_while_drained(blk); | ||
271 | + GRAPH_RDLOCK_GUARD(); | ||
272 | |||
273 | /* Call blk_bs() only after waiting, the graph may have changed */ | ||
274 | bs = blk_bs(blk); | ||
275 | diff --git a/block/bochs.c b/block/bochs.c | ||
276 | index XXXXXXX..XXXXXXX 100644 | ||
277 | --- a/block/bochs.c | ||
278 | +++ b/block/bochs.c | ||
279 | @@ -XXX,XX +XXX,XX @@ static int64_t seek_to_sector(BlockDriverState *bs, int64_t sector_num) | ||
280 | return bitmap_offset + (512 * (s->bitmap_blocks + extent_offset)); | ||
281 | } | ||
282 | |||
283 | -static int coroutine_fn | ||
284 | +static int coroutine_fn GRAPH_RDLOCK | ||
285 | bochs_co_preadv(BlockDriverState *bs, int64_t offset, int64_t bytes, | ||
286 | QEMUIOVector *qiov, BdrvRequestFlags flags) | ||
287 | { | ||
288 | diff --git a/block/commit.c b/block/commit.c | ||
289 | index XXXXXXX..XXXXXXX 100644 | ||
290 | --- a/block/commit.c | ||
291 | +++ b/block/commit.c | ||
292 | @@ -XXX,XX +XXX,XX @@ static const BlockJobDriver commit_job_driver = { | ||
293 | }, | ||
294 | }; | ||
295 | |||
296 | -static int coroutine_fn bdrv_commit_top_preadv(BlockDriverState *bs, | ||
297 | - int64_t offset, int64_t bytes, QEMUIOVector *qiov, BdrvRequestFlags flags) | ||
298 | +static int coroutine_fn GRAPH_RDLOCK | ||
299 | +bdrv_commit_top_preadv(BlockDriverState *bs, int64_t offset, int64_t bytes, | ||
300 | + QEMUIOVector *qiov, BdrvRequestFlags flags) | ||
301 | { | ||
302 | return bdrv_co_preadv(bs->backing, offset, bytes, qiov, flags); | ||
303 | } | ||
304 | diff --git a/block/copy-before-write.c b/block/copy-before-write.c | ||
305 | index XXXXXXX..XXXXXXX 100644 | ||
306 | --- a/block/copy-before-write.c | ||
307 | +++ b/block/copy-before-write.c | ||
308 | @@ -XXX,XX +XXX,XX @@ typedef struct BDRVCopyBeforeWriteState { | ||
309 | int snapshot_error; | ||
310 | } BDRVCopyBeforeWriteState; | ||
311 | |||
312 | -static coroutine_fn int cbw_co_preadv( | ||
313 | - BlockDriverState *bs, int64_t offset, int64_t bytes, | ||
314 | - QEMUIOVector *qiov, BdrvRequestFlags flags) | ||
315 | +static int coroutine_fn GRAPH_RDLOCK | ||
316 | +cbw_co_preadv(BlockDriverState *bs, int64_t offset, int64_t bytes, | ||
317 | + QEMUIOVector *qiov, BdrvRequestFlags flags) | ||
318 | { | ||
319 | return bdrv_co_preadv(bs->file, offset, bytes, qiov, flags); | ||
320 | } | ||
321 | @@ -XXX,XX +XXX,XX @@ cbw_co_pwrite_zeroes(BlockDriverState *bs, int64_t offset, int64_t bytes, | ||
322 | return bdrv_co_pwrite_zeroes(bs->file, offset, bytes, flags); | ||
323 | } | ||
324 | |||
325 | -static coroutine_fn int cbw_co_pwritev(BlockDriverState *bs, | ||
326 | - int64_t offset, | ||
327 | - int64_t bytes, | ||
328 | - QEMUIOVector *qiov, | ||
329 | - BdrvRequestFlags flags) | ||
330 | +static coroutine_fn GRAPH_RDLOCK | ||
331 | +int cbw_co_pwritev(BlockDriverState *bs, int64_t offset, int64_t bytes, | ||
332 | + QEMUIOVector *qiov, BdrvRequestFlags flags) | ||
333 | { | ||
334 | int ret = cbw_do_copy_before_write(bs, offset, bytes, flags); | ||
335 | if (ret < 0) { | ||
336 | @@ -XXX,XX +XXX,XX @@ cbw_co_preadv_snapshot(BlockDriverState *bs, int64_t offset, int64_t bytes, | ||
337 | BdrvChild *file; | ||
338 | int ret; | ||
339 | |||
340 | + assume_graph_lock(); /* FIXME */ | ||
341 | + | ||
342 | /* TODO: upgrade to async loop using AioTask */ | ||
343 | while (bytes) { | ||
344 | int64_t cur_bytes; | ||
345 | diff --git a/block/copy-on-read.c b/block/copy-on-read.c | ||
346 | index XXXXXXX..XXXXXXX 100644 | ||
347 | --- a/block/copy-on-read.c | ||
348 | +++ b/block/copy-on-read.c | ||
349 | @@ -XXX,XX +XXX,XX @@ static int64_t coroutine_fn cor_co_getlength(BlockDriverState *bs) | ||
350 | } | ||
351 | |||
352 | |||
353 | -static int coroutine_fn cor_co_preadv_part(BlockDriverState *bs, | ||
354 | - int64_t offset, int64_t bytes, | ||
355 | - QEMUIOVector *qiov, | ||
356 | - size_t qiov_offset, | ||
357 | - BdrvRequestFlags flags) | ||
358 | +static int coroutine_fn GRAPH_RDLOCK | ||
359 | +cor_co_preadv_part(BlockDriverState *bs, int64_t offset, int64_t bytes, | ||
360 | + QEMUIOVector *qiov, size_t qiov_offset, | ||
361 | + BdrvRequestFlags flags) | ||
362 | { | ||
363 | int64_t n; | ||
364 | int local_flags; | ||
365 | @@ -XXX,XX +XXX,XX @@ static int coroutine_fn cor_co_preadv_part(BlockDriverState *bs, | ||
366 | } | ||
367 | |||
368 | |||
369 | -static int coroutine_fn cor_co_pwritev_part(BlockDriverState *bs, | ||
370 | - int64_t offset, | ||
371 | - int64_t bytes, | ||
372 | - QEMUIOVector *qiov, | ||
373 | - size_t qiov_offset, | ||
374 | - BdrvRequestFlags flags) | ||
375 | +static int coroutine_fn GRAPH_RDLOCK | ||
376 | +cor_co_pwritev_part(BlockDriverState *bs, int64_t offset, int64_t bytes, | ||
377 | + QEMUIOVector *qiov, size_t qiov_offset, | ||
378 | + BdrvRequestFlags flags) | ||
379 | { | ||
380 | return bdrv_co_pwritev_part(bs->file, offset, bytes, qiov, qiov_offset, | ||
381 | flags); | ||
382 | @@ -XXX,XX +XXX,XX @@ cor_co_pdiscard(BlockDriverState *bs, int64_t offset, int64_t bytes) | ||
383 | } | ||
384 | |||
385 | |||
386 | -static int coroutine_fn cor_co_pwritev_compressed(BlockDriverState *bs, | ||
387 | - int64_t offset, | ||
388 | - int64_t bytes, | ||
389 | - QEMUIOVector *qiov) | ||
390 | +static int coroutine_fn GRAPH_RDLOCK | ||
391 | +cor_co_pwritev_compressed(BlockDriverState *bs, int64_t offset, int64_t bytes, | ||
392 | + QEMUIOVector *qiov) | ||
393 | { | ||
394 | return bdrv_co_pwritev(bs->file, offset, bytes, qiov, | ||
395 | BDRV_REQ_WRITE_COMPRESSED); | ||
396 | diff --git a/block/crypto.c b/block/crypto.c | ||
397 | index XXXXXXX..XXXXXXX 100644 | ||
398 | --- a/block/crypto.c | ||
399 | +++ b/block/crypto.c | ||
400 | @@ -XXX,XX +XXX,XX @@ static int block_crypto_reopen_prepare(BDRVReopenState *state, | ||
401 | */ | ||
402 | #define BLOCK_CRYPTO_MAX_IO_SIZE (1024 * 1024) | ||
403 | |||
404 | -static coroutine_fn int | ||
405 | +static int coroutine_fn GRAPH_RDLOCK | ||
406 | block_crypto_co_preadv(BlockDriverState *bs, int64_t offset, int64_t bytes, | ||
407 | QEMUIOVector *qiov, BdrvRequestFlags flags) | ||
408 | { | ||
409 | @@ -XXX,XX +XXX,XX @@ block_crypto_co_preadv(BlockDriverState *bs, int64_t offset, int64_t bytes, | ||
410 | } | ||
411 | |||
412 | |||
413 | -static coroutine_fn int | ||
414 | +static int coroutine_fn GRAPH_RDLOCK | ||
415 | block_crypto_co_pwritev(BlockDriverState *bs, int64_t offset, int64_t bytes, | ||
416 | QEMUIOVector *qiov, BdrvRequestFlags flags) | ||
417 | { | ||
418 | diff --git a/block/filter-compress.c b/block/filter-compress.c | ||
419 | index XXXXXXX..XXXXXXX 100644 | ||
420 | --- a/block/filter-compress.c | ||
421 | +++ b/block/filter-compress.c | ||
422 | @@ -XXX,XX +XXX,XX @@ static int64_t coroutine_fn compress_co_getlength(BlockDriverState *bs) | ||
423 | } | ||
424 | |||
425 | |||
426 | -static int coroutine_fn compress_co_preadv_part(BlockDriverState *bs, | ||
427 | - int64_t offset, int64_t bytes, | ||
428 | - QEMUIOVector *qiov, | ||
429 | - size_t qiov_offset, | ||
430 | - BdrvRequestFlags flags) | ||
431 | +static int coroutine_fn GRAPH_RDLOCK | ||
432 | +compress_co_preadv_part(BlockDriverState *bs, int64_t offset, int64_t bytes, | ||
433 | + QEMUIOVector *qiov, size_t qiov_offset, | ||
434 | + BdrvRequestFlags flags) | ||
435 | { | ||
436 | return bdrv_co_preadv_part(bs->file, offset, bytes, qiov, qiov_offset, | ||
437 | flags); | ||
438 | } | ||
439 | |||
440 | |||
441 | -static int coroutine_fn compress_co_pwritev_part(BlockDriverState *bs, | ||
442 | - int64_t offset, | ||
443 | - int64_t bytes, | ||
444 | - QEMUIOVector *qiov, | ||
445 | - size_t qiov_offset, | ||
446 | - BdrvRequestFlags flags) | ||
447 | +static int coroutine_fn GRAPH_RDLOCK | ||
448 | +compress_co_pwritev_part(BlockDriverState *bs, int64_t offset, int64_t bytes, | ||
449 | + QEMUIOVector *qiov, size_t qiov_offset, | ||
450 | + BdrvRequestFlags flags) | ||
451 | { | ||
452 | return bdrv_co_pwritev_part(bs->file, offset, bytes, qiov, qiov_offset, | ||
453 | flags | BDRV_REQ_WRITE_COMPRESSED); | ||
454 | diff --git a/block/io.c b/block/io.c | ||
455 | index XXXXXXX..XXXXXXX 100644 | ||
456 | --- a/block/io.c | ||
457 | +++ b/block/io.c | ||
458 | @@ -XXX,XX +XXX,XX @@ bdrv_driver_preadv(BlockDriverState *bs, int64_t offset, int64_t bytes, | ||
459 | unsigned int nb_sectors; | ||
460 | QEMUIOVector local_qiov; | ||
461 | int ret; | ||
462 | + assert_bdrv_graph_readable(); | ||
463 | |||
464 | bdrv_check_qiov_request(offset, bytes, qiov, qiov_offset, &error_abort); | ||
465 | assert(!(flags & ~bs->supported_read_flags)); | ||
466 | @@ -XXX,XX +XXX,XX @@ bdrv_driver_pwritev(BlockDriverState *bs, int64_t offset, int64_t bytes, | ||
467 | unsigned int nb_sectors; | ||
468 | QEMUIOVector local_qiov; | ||
469 | int ret; | ||
470 | + assert_bdrv_graph_readable(); | ||
471 | |||
472 | bdrv_check_qiov_request(offset, bytes, qiov, qiov_offset, &error_abort); | ||
473 | |||
474 | @@ -XXX,XX +XXX,XX @@ bdrv_driver_pwritev_compressed(BlockDriverState *bs, int64_t offset, | ||
475 | BlockDriver *drv = bs->drv; | ||
476 | QEMUIOVector local_qiov; | ||
477 | int ret; | ||
478 | + assert_bdrv_graph_readable(); | ||
479 | |||
480 | bdrv_check_qiov_request(offset, bytes, qiov, qiov_offset, &error_abort); | ||
481 | |||
482 | @@ -XXX,XX +XXX,XX @@ int coroutine_fn bdrv_co_preadv_part(BdrvChild *child, | ||
483 | int ret; | ||
484 | IO_CODE(); | ||
485 | |||
486 | - assume_graph_lock(); /* FIXME */ | ||
487 | - | ||
488 | trace_bdrv_co_preadv_part(bs, offset, bytes, flags); | ||
489 | |||
490 | if (!bdrv_co_is_inserted(bs)) { | ||
491 | @@ -XXX,XX +XXX,XX @@ int coroutine_fn bdrv_co_pwritev_part(BdrvChild *child, | ||
492 | bool padded = false; | ||
493 | IO_CODE(); | ||
494 | |||
495 | - assume_graph_lock(); /* FIXME */ | ||
496 | - | ||
497 | trace_bdrv_co_pwritev_part(child->bs, offset, bytes, flags); | ||
498 | |||
499 | if (!bdrv_co_is_inserted(bs)) { | ||
500 | diff --git a/block/mirror.c b/block/mirror.c | ||
501 | index XXXXXXX..XXXXXXX 100644 | ||
502 | --- a/block/mirror.c | ||
503 | +++ b/block/mirror.c | ||
504 | @@ -XXX,XX +XXX,XX @@ static void coroutine_fn mirror_co_read(void *opaque) | ||
505 | op->is_in_flight = true; | ||
506 | trace_mirror_one_iteration(s, op->offset, op->bytes); | ||
507 | |||
508 | - ret = bdrv_co_preadv(s->mirror_top_bs->backing, op->offset, op->bytes, | ||
509 | - &op->qiov, 0); | ||
510 | + WITH_GRAPH_RDLOCK_GUARD() { | ||
511 | + ret = bdrv_co_preadv(s->mirror_top_bs->backing, op->offset, op->bytes, | ||
512 | + &op->qiov, 0); | ||
513 | + } | ||
514 | mirror_read_complete(op, ret); | ||
515 | } | ||
516 | |||
517 | @@ -XXX,XX +XXX,XX @@ static void coroutine_fn active_write_settle(MirrorOp *op) | ||
518 | g_free(op); | ||
519 | } | ||
520 | |||
521 | -static int coroutine_fn bdrv_mirror_top_preadv(BlockDriverState *bs, | ||
522 | - int64_t offset, int64_t bytes, QEMUIOVector *qiov, BdrvRequestFlags flags) | ||
523 | +static int coroutine_fn GRAPH_RDLOCK | ||
524 | +bdrv_mirror_top_preadv(BlockDriverState *bs, int64_t offset, int64_t bytes, | ||
525 | + QEMUIOVector *qiov, BdrvRequestFlags flags) | ||
526 | { | ||
527 | return bdrv_co_preadv(bs->backing, offset, bytes, qiov, flags); | ||
528 | } | ||
529 | @@ -XXX,XX +XXX,XX @@ out: | ||
530 | return ret; | ||
531 | } | ||
532 | |||
533 | -static int coroutine_fn bdrv_mirror_top_pwritev(BlockDriverState *bs, | ||
534 | - int64_t offset, int64_t bytes, QEMUIOVector *qiov, BdrvRequestFlags flags) | ||
535 | +static int coroutine_fn GRAPH_RDLOCK | ||
536 | +bdrv_mirror_top_pwritev(BlockDriverState *bs, int64_t offset, int64_t bytes, | ||
537 | + QEMUIOVector *qiov, BdrvRequestFlags flags) | ||
538 | { | ||
539 | MirrorBDSOpaque *s = bs->opaque; | ||
540 | QEMUIOVector bounce_qiov; | ||
541 | @@ -XXX,XX +XXX,XX @@ static int coroutine_fn bdrv_mirror_top_pwritev(BlockDriverState *bs, | ||
542 | int ret = 0; | ||
543 | bool copy_to_target = false; | ||
544 | |||
545 | - assume_graph_lock(); /* FIXME */ | ||
546 | - | ||
547 | if (s->job) { | ||
548 | copy_to_target = s->job->ret >= 0 && | ||
549 | !job_is_cancelled(&s->job->common.job) && | ||
550 | diff --git a/block/parallels.c b/block/parallels.c | ||
551 | index XXXXXXX..XXXXXXX 100644 | ||
552 | --- a/block/parallels.c | ||
553 | +++ b/block/parallels.c | ||
554 | @@ -XXX,XX +XXX,XX @@ allocate_clusters(BlockDriverState *bs, int64_t sector_num, | ||
555 | } | ||
556 | |||
557 | |||
558 | -static coroutine_fn int parallels_co_flush_to_os(BlockDriverState *bs) | ||
559 | +static int coroutine_fn GRAPH_RDLOCK | ||
560 | +parallels_co_flush_to_os(BlockDriverState *bs) | ||
561 | { | ||
562 | BDRVParallelsState *s = bs->opaque; | ||
563 | unsigned long size = DIV_ROUND_UP(s->header_size, s->bat_dirty_block); | ||
564 | @@ -XXX,XX +XXX,XX @@ parallels_co_writev(BlockDriverState *bs, int64_t sector_num, int nb_sectors, | ||
565 | return ret; | ||
566 | } | ||
567 | |||
568 | -static coroutine_fn int parallels_co_readv(BlockDriverState *bs, | ||
569 | - int64_t sector_num, int nb_sectors, QEMUIOVector *qiov) | ||
570 | +static int coroutine_fn GRAPH_RDLOCK | ||
571 | +parallels_co_readv(BlockDriverState *bs, int64_t sector_num, int nb_sectors, | ||
572 | + QEMUIOVector *qiov) | ||
573 | { | ||
574 | BDRVParallelsState *s = bs->opaque; | ||
575 | uint64_t bytes_done = 0; | ||
576 | diff --git a/block/preallocate.c b/block/preallocate.c | ||
577 | index XXXXXXX..XXXXXXX 100644 | ||
578 | --- a/block/preallocate.c | ||
579 | +++ b/block/preallocate.c | ||
580 | @@ -XXX,XX +XXX,XX @@ static void preallocate_reopen_abort(BDRVReopenState *state) | ||
581 | state->opaque = NULL; | ||
582 | } | ||
583 | |||
584 | -static coroutine_fn int preallocate_co_preadv_part( | ||
585 | - BlockDriverState *bs, int64_t offset, int64_t bytes, | ||
586 | - QEMUIOVector *qiov, size_t qiov_offset, BdrvRequestFlags flags) | ||
587 | +static int coroutine_fn GRAPH_RDLOCK | ||
588 | +preallocate_co_preadv_part(BlockDriverState *bs, int64_t offset, int64_t bytes, | ||
589 | + QEMUIOVector *qiov, size_t qiov_offset, | ||
590 | + BdrvRequestFlags flags) | ||
591 | { | ||
592 | return bdrv_co_preadv_part(bs->file, offset, bytes, qiov, qiov_offset, | ||
593 | flags); | ||
594 | @@ -XXX,XX +XXX,XX @@ preallocate_co_pwrite_zeroes(BlockDriverState *bs, int64_t offset, | ||
595 | return bdrv_co_pwrite_zeroes(bs->file, offset, bytes, flags); | ||
596 | } | ||
597 | |||
598 | -static coroutine_fn int preallocate_co_pwritev_part(BlockDriverState *bs, | ||
599 | - int64_t offset, | ||
600 | - int64_t bytes, | ||
601 | - QEMUIOVector *qiov, | ||
602 | - size_t qiov_offset, | ||
603 | - BdrvRequestFlags flags) | ||
604 | +static int coroutine_fn GRAPH_RDLOCK | ||
605 | +preallocate_co_pwritev_part(BlockDriverState *bs, int64_t offset, int64_t bytes, | ||
606 | + QEMUIOVector *qiov, size_t qiov_offset, | ||
607 | + BdrvRequestFlags flags) | ||
608 | { | ||
609 | - assume_graph_lock(); /* FIXME */ | ||
610 | handle_write(bs, offset, bytes, false); | ||
611 | |||
612 | return bdrv_co_pwritev_part(bs->file, offset, bytes, qiov, qiov_offset, | ||
613 | diff --git a/block/qcow.c b/block/qcow.c | ||
614 | index XXXXXXX..XXXXXXX 100644 | ||
615 | --- a/block/qcow.c | ||
616 | +++ b/block/qcow.c | ||
617 | @@ -XXX,XX +XXX,XX @@ typedef struct BDRVQcowState { | ||
618 | |||
619 | static QemuOptsList qcow_create_opts; | ||
620 | |||
621 | -static int coroutine_fn decompress_cluster(BlockDriverState *bs, | ||
622 | - uint64_t cluster_offset); | ||
623 | +static int coroutine_fn GRAPH_RDLOCK | ||
624 | +decompress_cluster(BlockDriverState *bs, uint64_t cluster_offset); | ||
625 | |||
626 | static int qcow_probe(const uint8_t *buf, int buf_size, const char *filename) | ||
627 | { | ||
628 | @@ -XXX,XX +XXX,XX @@ static int decompress_buffer(uint8_t *out_buf, int out_buf_size, | ||
629 | return 0; | ||
630 | } | ||
631 | |||
632 | -static int coroutine_fn decompress_cluster(BlockDriverState *bs, | ||
633 | - uint64_t cluster_offset) | ||
634 | +static int coroutine_fn GRAPH_RDLOCK | ||
635 | +decompress_cluster(BlockDriverState *bs, uint64_t cluster_offset) | ||
636 | { | ||
637 | BDRVQcowState *s = bs->opaque; | ||
638 | int ret, csize; | ||
639 | diff --git a/block/qcow2-cluster.c b/block/qcow2-cluster.c | ||
640 | index XXXXXXX..XXXXXXX 100644 | ||
641 | --- a/block/qcow2-cluster.c | ||
642 | +++ b/block/qcow2-cluster.c | ||
643 | @@ -XXX,XX +XXX,XX @@ do_perform_cow_read(BlockDriverState *bs, uint64_t src_cluster_offset, | ||
644 | return 0; | ||
645 | } | ||
646 | |||
647 | -static int coroutine_fn do_perform_cow_write(BlockDriverState *bs, | ||
648 | - uint64_t cluster_offset, | ||
649 | - unsigned offset_in_cluster, | ||
650 | - QEMUIOVector *qiov) | ||
651 | +static int coroutine_fn GRAPH_RDLOCK | ||
652 | +do_perform_cow_write(BlockDriverState *bs, uint64_t cluster_offset, | ||
653 | + unsigned offset_in_cluster, QEMUIOVector *qiov) | ||
654 | { | ||
655 | BDRVQcow2State *s = bs->opaque; | ||
656 | int ret; | ||
657 | diff --git a/block/qcow2.c b/block/qcow2.c | ||
658 | index XXXXXXX..XXXXXXX 100644 | ||
659 | --- a/block/qcow2.c | ||
660 | +++ b/block/qcow2.c | ||
661 | @@ -XXX,XX +XXX,XX @@ static void qcow2_add_check_result(BdrvCheckResult *out, | ||
662 | } | ||
663 | } | ||
664 | |||
665 | -static int coroutine_fn qcow2_co_check_locked(BlockDriverState *bs, | ||
666 | - BdrvCheckResult *result, | ||
667 | - BdrvCheckMode fix) | ||
668 | +static int coroutine_fn GRAPH_RDLOCK | ||
669 | +qcow2_co_check_locked(BlockDriverState *bs, BdrvCheckResult *result, | ||
670 | + BdrvCheckMode fix) | ||
671 | { | ||
672 | BdrvCheckResult snapshot_res = {}; | ||
673 | BdrvCheckResult refcount_res = {}; | ||
674 | @@ -XXX,XX +XXX,XX @@ static int coroutine_fn qcow2_co_check_locked(BlockDriverState *bs, | ||
675 | return ret; | ||
676 | } | ||
677 | |||
678 | -static int coroutine_fn qcow2_co_check(BlockDriverState *bs, | ||
679 | - BdrvCheckResult *result, | ||
680 | - BdrvCheckMode fix) | ||
681 | +static int coroutine_fn GRAPH_RDLOCK | ||
682 | +qcow2_co_check(BlockDriverState *bs, BdrvCheckResult *result, | ||
683 | + BdrvCheckMode fix) | ||
684 | { | ||
685 | BDRVQcow2State *s = bs->opaque; | ||
686 | int ret; | ||
687 | @@ -XXX,XX +XXX,XX @@ static int validate_compression_type(BDRVQcow2State *s, Error **errp) | ||
688 | } | ||
689 | |||
690 | /* Called with s->lock held. */ | ||
691 | -static int coroutine_fn qcow2_do_open(BlockDriverState *bs, QDict *options, | ||
692 | - int flags, bool open_data_file, | ||
693 | - Error **errp) | ||
694 | +static int coroutine_fn GRAPH_RDLOCK | ||
695 | +qcow2_do_open(BlockDriverState *bs, QDict *options, int flags, | ||
696 | + bool open_data_file, Error **errp) | ||
697 | { | ||
698 | ERRP_GUARD(); | ||
699 | BDRVQcow2State *s = bs->opaque; | ||
700 | @@ -XXX,XX +XXX,XX @@ static void coroutine_fn qcow2_open_entry(void *opaque) | ||
701 | QCow2OpenCo *qoc = opaque; | ||
702 | BDRVQcow2State *s = qoc->bs->opaque; | ||
703 | |||
704 | + assume_graph_lock(); /* FIXME */ | ||
705 | + | ||
706 | qemu_co_mutex_lock(&s->lock); | ||
707 | qoc->ret = qcow2_do_open(qoc->bs, qoc->options, qoc->flags, true, | ||
708 | qoc->errp); | ||
709 | @@ -XXX,XX +XXX,XX @@ out: | ||
710 | return ret; | ||
711 | } | ||
712 | |||
713 | -static coroutine_fn int | ||
714 | +static int coroutine_fn GRAPH_RDLOCK | ||
715 | qcow2_co_preadv_encrypted(BlockDriverState *bs, | ||
716 | uint64_t host_offset, | ||
717 | uint64_t offset, | ||
718 | @@ -XXX,XX +XXX,XX @@ static coroutine_fn int qcow2_add_task(BlockDriverState *bs, | ||
719 | return 0; | ||
720 | } | ||
721 | |||
722 | -static coroutine_fn int qcow2_co_preadv_task(BlockDriverState *bs, | ||
723 | - QCow2SubclusterType subc_type, | ||
724 | - uint64_t host_offset, | ||
725 | - uint64_t offset, uint64_t bytes, | ||
726 | - QEMUIOVector *qiov, | ||
727 | - size_t qiov_offset) | ||
728 | +static int coroutine_fn GRAPH_RDLOCK | ||
729 | +qcow2_co_preadv_task(BlockDriverState *bs, QCow2SubclusterType subc_type, | ||
730 | + uint64_t host_offset, uint64_t offset, uint64_t bytes, | ||
731 | + QEMUIOVector *qiov, size_t qiov_offset) | ||
732 | { | ||
733 | BDRVQcow2State *s = bs->opaque; | ||
734 | |||
735 | @@ -XXX,XX +XXX,XX @@ static coroutine_fn int qcow2_co_preadv_task(BlockDriverState *bs, | ||
736 | g_assert_not_reached(); | ||
737 | } | ||
738 | |||
739 | -static coroutine_fn int qcow2_co_preadv_task_entry(AioTask *task) | ||
740 | +/* | ||
741 | + * This function can count as GRAPH_RDLOCK because qcow2_co_preadv_part() holds | ||
742 | + * the graph lock and keeps it until this coroutine has terminated. | ||
743 | + */ | ||
744 | +static int coroutine_fn GRAPH_RDLOCK qcow2_co_preadv_task_entry(AioTask *task) | ||
745 | { | ||
746 | Qcow2AioTask *t = container_of(task, Qcow2AioTask, task); | ||
747 | |||
748 | @@ -XXX,XX +XXX,XX @@ static coroutine_fn int qcow2_co_preadv_task_entry(AioTask *task) | ||
749 | t->qiov, t->qiov_offset); | ||
750 | } | ||
751 | |||
752 | -static coroutine_fn int qcow2_co_preadv_part(BlockDriverState *bs, | ||
753 | - int64_t offset, int64_t bytes, | ||
754 | - QEMUIOVector *qiov, | ||
755 | - size_t qiov_offset, | ||
756 | - BdrvRequestFlags flags) | ||
757 | +static int coroutine_fn GRAPH_RDLOCK | ||
758 | +qcow2_co_preadv_part(BlockDriverState *bs, int64_t offset, int64_t bytes, | ||
759 | + QEMUIOVector *qiov, size_t qiov_offset, | ||
760 | + BdrvRequestFlags flags) | ||
761 | { | ||
762 | BDRVQcow2State *s = bs->opaque; | ||
763 | int ret = 0; | ||
764 | @@ -XXX,XX +XXX,XX @@ static void qcow2_close(BlockDriverState *bs) | ||
765 | qcow2_do_close(bs, true); | ||
766 | } | ||
767 | |||
768 | -static void coroutine_fn qcow2_co_invalidate_cache(BlockDriverState *bs, | ||
769 | - Error **errp) | ||
770 | +static void coroutine_fn GRAPH_RDLOCK | ||
771 | +qcow2_co_invalidate_cache(BlockDriverState *bs, Error **errp) | ||
772 | { | ||
773 | ERRP_GUARD(); | ||
774 | BDRVQcow2State *s = bs->opaque; | ||
775 | @@ -XXX,XX +XXX,XX @@ qcow2_co_pwritev_compressed_part(BlockDriverState *bs, | ||
776 | return ret; | ||
777 | } | ||
778 | |||
779 | -static int coroutine_fn | ||
780 | +static int coroutine_fn GRAPH_RDLOCK | ||
781 | qcow2_co_preadv_compressed(BlockDriverState *bs, | ||
782 | uint64_t l2_entry, | ||
783 | uint64_t offset, | ||
784 | diff --git a/block/qed-table.c b/block/qed-table.c | ||
785 | index XXXXXXX..XXXXXXX 100644 | ||
786 | --- a/block/qed-table.c | ||
787 | +++ b/block/qed-table.c | ||
788 | @@ -XXX,XX +XXX,XX @@ | ||
789 | #include "qemu/memalign.h" | ||
790 | |||
791 | /* Called with table_lock held. */ | ||
792 | -static int coroutine_fn qed_read_table(BDRVQEDState *s, uint64_t offset, | ||
793 | - QEDTable *table) | ||
794 | +static int coroutine_fn GRAPH_RDLOCK | ||
795 | +qed_read_table(BDRVQEDState *s, uint64_t offset, QEDTable *table) | ||
796 | { | ||
797 | unsigned int bytes = s->header.cluster_size * s->header.table_size; | ||
798 | |||
799 | diff --git a/block/qed.c b/block/qed.c | ||
800 | index XXXXXXX..XXXXXXX 100644 | ||
801 | --- a/block/qed.c | ||
802 | +++ b/block/qed.c | ||
803 | @@ -XXX,XX +XXX,XX @@ int qed_write_header_sync(BDRVQEDState *s) | ||
804 | * | ||
805 | * No new allocating reqs can start while this function runs. | ||
806 | */ | ||
807 | -static int coroutine_fn qed_write_header(BDRVQEDState *s) | ||
808 | +static int coroutine_fn GRAPH_RDLOCK qed_write_header(BDRVQEDState *s) | ||
809 | { | ||
810 | /* We must write full sectors for O_DIRECT but cannot necessarily generate | ||
811 | * the data following the header if an unrecognized compat feature is | ||
812 | @@ -XXX,XX +XXX,XX @@ fail: | ||
813 | return ret; | ||
814 | } | ||
815 | |||
816 | -static int coroutine_fn bdrv_qed_co_block_status(BlockDriverState *bs, | ||
817 | - bool want_zero, | ||
818 | - int64_t pos, int64_t bytes, | ||
819 | - int64_t *pnum, int64_t *map, | ||
820 | - BlockDriverState **file) | ||
821 | +static int coroutine_fn GRAPH_RDLOCK | ||
822 | +bdrv_qed_co_block_status(BlockDriverState *bs, bool want_zero, int64_t pos, | ||
823 | + int64_t bytes, int64_t *pnum, int64_t *map, | ||
824 | + BlockDriverState **file) | ||
825 | { | ||
826 | BDRVQEDState *s = bs->opaque; | ||
827 | size_t len = MIN(bytes, SIZE_MAX); | ||
828 | @@ -XXX,XX +XXX,XX @@ static BDRVQEDState *acb_to_s(QEDAIOCB *acb) | ||
829 | * This function reads qiov->size bytes starting at pos from the backing file. | ||
830 | * If there is no backing file then zeroes are read. | ||
831 | */ | ||
832 | -static int coroutine_fn qed_read_backing_file(BDRVQEDState *s, uint64_t pos, | ||
833 | - QEMUIOVector *qiov) | ||
834 | +static int coroutine_fn GRAPH_RDLOCK | ||
835 | +qed_read_backing_file(BDRVQEDState *s, uint64_t pos, QEMUIOVector *qiov) | ||
836 | { | ||
837 | if (s->bs->backing) { | ||
838 | BLKDBG_EVENT(s->bs->file, BLKDBG_READ_BACKING_AIO); | ||
839 | @@ -XXX,XX +XXX,XX @@ static int coroutine_fn qed_read_backing_file(BDRVQEDState *s, uint64_t pos, | ||
840 | * @len: Number of bytes | ||
841 | * @offset: Byte offset in image file | ||
842 | */ | ||
843 | -static int coroutine_fn qed_copy_from_backing_file(BDRVQEDState *s, | ||
844 | - uint64_t pos, uint64_t len, | ||
845 | - uint64_t offset) | ||
846 | +static int coroutine_fn GRAPH_RDLOCK | ||
847 | +qed_copy_from_backing_file(BDRVQEDState *s, uint64_t pos, uint64_t len, | ||
848 | + uint64_t offset) | ||
849 | { | ||
850 | QEMUIOVector qiov; | ||
851 | int ret; | ||
852 | @@ -XXX,XX +XXX,XX @@ qed_aio_write_l2_update(QEDAIOCB *acb, uint64_t offset) | ||
853 | * | ||
854 | * Called with table_lock *not* held. | ||
855 | */ | ||
856 | -static int coroutine_fn qed_aio_write_main(QEDAIOCB *acb) | ||
857 | +static int coroutine_fn GRAPH_RDLOCK qed_aio_write_main(QEDAIOCB *acb) | ||
858 | { | ||
859 | BDRVQEDState *s = acb_to_s(acb); | ||
860 | uint64_t offset = acb->cur_cluster + | ||
861 | @@ -XXX,XX +XXX,XX @@ qed_aio_write_alloc(QEDAIOCB *acb, size_t len) | ||
862 | * | ||
863 | * Called with table_lock held. | ||
864 | */ | ||
865 | -static int coroutine_fn qed_aio_write_inplace(QEDAIOCB *acb, uint64_t offset, | ||
866 | - size_t len) | ||
867 | +static int coroutine_fn GRAPH_RDLOCK | ||
868 | +qed_aio_write_inplace(QEDAIOCB *acb, uint64_t offset, size_t len) | ||
869 | { | ||
870 | BDRVQEDState *s = acb_to_s(acb); | ||
871 | int r; | ||
872 | @@ -XXX,XX +XXX,XX @@ qed_aio_write_data(void *opaque, int ret, uint64_t offset, size_t len) | ||
873 | * | ||
874 | * Called with table_lock held. | ||
875 | */ | ||
876 | -static int coroutine_fn qed_aio_read_data(void *opaque, int ret, | ||
877 | - uint64_t offset, size_t len) | ||
878 | +static int coroutine_fn GRAPH_RDLOCK | ||
879 | +qed_aio_read_data(void *opaque, int ret, uint64_t offset, size_t len) | ||
880 | { | ||
881 | QEDAIOCB *acb = opaque; | ||
882 | BDRVQEDState *s = acb_to_s(acb); | ||
883 | diff --git a/block/quorum.c b/block/quorum.c | ||
884 | index XXXXXXX..XXXXXXX 100644 | ||
885 | --- a/block/quorum.c | ||
886 | +++ b/block/quorum.c | ||
887 | @@ -XXX,XX +XXX,XX @@ static void quorum_report_bad_versions(BDRVQuorumState *s, | ||
888 | } | ||
889 | } | ||
890 | |||
891 | -static void coroutine_fn quorum_rewrite_entry(void *opaque) | ||
892 | +/* | ||
893 | + * This function can count as GRAPH_RDLOCK because read_quorum_children() holds | ||
894 | + * the graph lock and keeps it until this coroutine has terminated. | ||
895 | + */ | ||
896 | +static void coroutine_fn GRAPH_RDLOCK quorum_rewrite_entry(void *opaque) | ||
897 | { | ||
898 | QuorumCo *co = opaque; | ||
899 | QuorumAIOCB *acb = co->acb; | ||
900 | @@ -XXX,XX +XXX,XX @@ static void coroutine_fn quorum_rewrite_entry(void *opaque) | ||
901 | } | ||
902 | } | ||
903 | |||
904 | -static bool quorum_rewrite_bad_versions(QuorumAIOCB *acb, | ||
905 | - QuorumVoteValue *value) | ||
906 | +static bool coroutine_fn GRAPH_RDLOCK | ||
907 | +quorum_rewrite_bad_versions(QuorumAIOCB *acb, QuorumVoteValue *value) | ||
908 | { | ||
909 | QuorumVoteVersion *version; | ||
910 | QuorumVoteItem *item; | ||
911 | @@ -XXX,XX +XXX,XX @@ static int quorum_vote_error(QuorumAIOCB *acb) | ||
912 | return ret; | ||
913 | } | ||
914 | |||
915 | -static void quorum_vote(QuorumAIOCB *acb) | ||
916 | +static void coroutine_fn GRAPH_RDLOCK quorum_vote(QuorumAIOCB *acb) | ||
917 | { | ||
918 | bool quorum = true; | ||
919 | int i, j, ret; | ||
920 | @@ -XXX,XX +XXX,XX @@ free_exit: | ||
921 | quorum_free_vote_list(&acb->votes); | ||
922 | } | ||
923 | |||
924 | -static void coroutine_fn read_quorum_children_entry(void *opaque) | ||
925 | +/* | ||
926 | + * This function can count as GRAPH_RDLOCK because read_quorum_children() holds | ||
927 | + * the graph lock and keeps it until this coroutine has terminated. | ||
928 | + */ | ||
929 | +static void coroutine_fn GRAPH_RDLOCK read_quorum_children_entry(void *opaque) | ||
930 | { | ||
931 | QuorumCo *co = opaque; | ||
932 | QuorumAIOCB *acb = co->acb; | ||
933 | @@ -XXX,XX +XXX,XX @@ static void coroutine_fn read_quorum_children_entry(void *opaque) | ||
934 | } | ||
935 | } | ||
936 | |||
937 | -static int coroutine_fn read_quorum_children(QuorumAIOCB *acb) | ||
938 | +static int coroutine_fn GRAPH_RDLOCK read_quorum_children(QuorumAIOCB *acb) | ||
939 | { | ||
940 | BDRVQuorumState *s = acb->bs->opaque; | ||
941 | int i; | ||
942 | @@ -XXX,XX +XXX,XX @@ static int coroutine_fn read_quorum_children(QuorumAIOCB *acb) | ||
943 | return acb->vote_ret; | ||
944 | } | ||
945 | |||
946 | -static int coroutine_fn read_fifo_child(QuorumAIOCB *acb) | ||
947 | +static int coroutine_fn GRAPH_RDLOCK read_fifo_child(QuorumAIOCB *acb) | ||
948 | { | ||
949 | BDRVQuorumState *s = acb->bs->opaque; | ||
950 | int n, ret; | ||
951 | @@ -XXX,XX +XXX,XX @@ static int coroutine_fn read_fifo_child(QuorumAIOCB *acb) | ||
952 | return ret; | ||
953 | } | ||
954 | |||
955 | -static int coroutine_fn quorum_co_preadv(BlockDriverState *bs, | ||
956 | - int64_t offset, int64_t bytes, | ||
957 | - QEMUIOVector *qiov, | ||
958 | - BdrvRequestFlags flags) | ||
959 | +static int coroutine_fn GRAPH_RDLOCK | ||
960 | +quorum_co_preadv(BlockDriverState *bs, int64_t offset, int64_t bytes, | ||
961 | + QEMUIOVector *qiov, BdrvRequestFlags flags) | ||
962 | { | ||
963 | BDRVQuorumState *s = bs->opaque; | ||
964 | QuorumAIOCB *acb = quorum_aio_get(bs, qiov, offset, bytes, flags); | ||
965 | diff --git a/block/raw-format.c b/block/raw-format.c | ||
966 | index XXXXXXX..XXXXXXX 100644 | ||
967 | --- a/block/raw-format.c | ||
968 | +++ b/block/raw-format.c | ||
969 | @@ -XXX,XX +XXX,XX @@ static inline int raw_adjust_offset(BlockDriverState *bs, int64_t *offset, | ||
970 | return 0; | ||
971 | } | ||
972 | |||
973 | -static int coroutine_fn raw_co_preadv(BlockDriverState *bs, int64_t offset, | ||
974 | - int64_t bytes, QEMUIOVector *qiov, | ||
975 | - BdrvRequestFlags flags) | ||
976 | +static int coroutine_fn GRAPH_RDLOCK | ||
977 | +raw_co_preadv(BlockDriverState *bs, int64_t offset, int64_t bytes, | ||
978 | + QEMUIOVector *qiov, BdrvRequestFlags flags) | ||
979 | { | ||
980 | int ret; | ||
981 | |||
982 | @@ -XXX,XX +XXX,XX @@ static int coroutine_fn raw_co_preadv(BlockDriverState *bs, int64_t offset, | ||
983 | return bdrv_co_preadv(bs->file, offset, bytes, qiov, flags); | ||
984 | } | ||
985 | |||
986 | -static int coroutine_fn raw_co_pwritev(BlockDriverState *bs, int64_t offset, | ||
987 | - int64_t bytes, QEMUIOVector *qiov, | ||
988 | - BdrvRequestFlags flags) | ||
989 | +static int coroutine_fn GRAPH_RDLOCK | ||
990 | +raw_co_pwritev(BlockDriverState *bs, int64_t offset, int64_t bytes, | ||
991 | + QEMUIOVector *qiov, BdrvRequestFlags flags) | ||
992 | { | ||
993 | void *buf = NULL; | ||
994 | BlockDriver *drv; | ||
995 | diff --git a/block/replication.c b/block/replication.c | ||
996 | index XXXXXXX..XXXXXXX 100644 | ||
997 | --- a/block/replication.c | ||
998 | +++ b/block/replication.c | ||
999 | @@ -XXX,XX +XXX,XX @@ static int replication_return_value(BDRVReplicationState *s, int ret) | ||
1000 | return ret; | ||
1001 | } | ||
1002 | |||
1003 | -static coroutine_fn int replication_co_readv(BlockDriverState *bs, | ||
1004 | - int64_t sector_num, | ||
1005 | - int remaining_sectors, | ||
1006 | - QEMUIOVector *qiov) | ||
1007 | +static int coroutine_fn GRAPH_RDLOCK | ||
1008 | +replication_co_readv(BlockDriverState *bs, int64_t sector_num, | ||
1009 | + int remaining_sectors, QEMUIOVector *qiov) | ||
1010 | { | ||
1011 | BDRVReplicationState *s = bs->opaque; | ||
1012 | int ret; | ||
1013 | @@ -XXX,XX +XXX,XX @@ static coroutine_fn int replication_co_readv(BlockDriverState *bs, | ||
1014 | return replication_return_value(s, ret); | ||
1015 | } | ||
1016 | |||
1017 | -static coroutine_fn int replication_co_writev(BlockDriverState *bs, | ||
1018 | - int64_t sector_num, | ||
1019 | - int remaining_sectors, | ||
1020 | - QEMUIOVector *qiov, | ||
1021 | - int flags) | ||
1022 | +static int coroutine_fn GRAPH_RDLOCK | ||
1023 | +replication_co_writev(BlockDriverState *bs, int64_t sector_num, | ||
1024 | + int remaining_sectors, QEMUIOVector *qiov, int flags) | ||
1025 | { | ||
1026 | BDRVReplicationState *s = bs->opaque; | ||
1027 | QEMUIOVector hd_qiov; | ||
1028 | diff --git a/block/throttle.c b/block/throttle.c | ||
1029 | index XXXXXXX..XXXXXXX 100644 | ||
1030 | --- a/block/throttle.c | ||
1031 | +++ b/block/throttle.c | ||
1032 | @@ -XXX,XX +XXX,XX @@ static int64_t coroutine_fn throttle_co_getlength(BlockDriverState *bs) | ||
1033 | return bdrv_co_getlength(bs->file->bs); | ||
1034 | } | ||
1035 | |||
1036 | -static int coroutine_fn throttle_co_preadv(BlockDriverState *bs, | ||
1037 | - int64_t offset, int64_t bytes, | ||
1038 | - QEMUIOVector *qiov, | ||
1039 | - BdrvRequestFlags flags) | ||
1040 | +static int coroutine_fn GRAPH_RDLOCK | ||
1041 | +throttle_co_preadv(BlockDriverState *bs, int64_t offset, int64_t bytes, | ||
1042 | + QEMUIOVector *qiov, BdrvRequestFlags flags) | ||
1043 | { | ||
1044 | |||
1045 | ThrottleGroupMember *tgm = bs->opaque; | ||
1046 | @@ -XXX,XX +XXX,XX @@ static int coroutine_fn throttle_co_preadv(BlockDriverState *bs, | ||
1047 | return bdrv_co_preadv(bs->file, offset, bytes, qiov, flags); | ||
1048 | } | ||
1049 | |||
1050 | -static int coroutine_fn throttle_co_pwritev(BlockDriverState *bs, | ||
1051 | - int64_t offset, int64_t bytes, | ||
1052 | - QEMUIOVector *qiov, | ||
1053 | - BdrvRequestFlags flags) | ||
1054 | +static int coroutine_fn GRAPH_RDLOCK | ||
1055 | +throttle_co_pwritev(BlockDriverState *bs, int64_t offset, int64_t bytes, | ||
1056 | + QEMUIOVector *qiov, BdrvRequestFlags flags) | ||
1057 | { | ||
1058 | ThrottleGroupMember *tgm = bs->opaque; | ||
1059 | throttle_group_co_io_limits_intercept(tgm, bytes, true); | ||
1060 | @@ -XXX,XX +XXX,XX @@ throttle_co_pdiscard(BlockDriverState *bs, int64_t offset, int64_t bytes) | ||
1061 | return bdrv_co_pdiscard(bs->file, offset, bytes); | ||
1062 | } | ||
1063 | |||
1064 | -static int coroutine_fn throttle_co_pwritev_compressed(BlockDriverState *bs, | ||
1065 | - int64_t offset, | ||
1066 | - int64_t bytes, | ||
1067 | - QEMUIOVector *qiov) | ||
1068 | +static int coroutine_fn GRAPH_RDLOCK | ||
1069 | +throttle_co_pwritev_compressed(BlockDriverState *bs, int64_t offset, | ||
1070 | + int64_t bytes, QEMUIOVector *qiov) | ||
1071 | { | ||
1072 | return throttle_co_pwritev(bs, offset, bytes, qiov, | ||
1073 | BDRV_REQ_WRITE_COMPRESSED); | ||
1074 | diff --git a/block/vdi.c b/block/vdi.c | ||
1075 | index XXXXXXX..XXXXXXX 100644 | ||
1076 | --- a/block/vdi.c | ||
1077 | +++ b/block/vdi.c | ||
1078 | @@ -XXX,XX +XXX,XX @@ static int coroutine_fn vdi_co_block_status(BlockDriverState *bs, | ||
1079 | (s->header.image_type == VDI_TYPE_STATIC ? BDRV_BLOCK_RECURSE : 0); | ||
1080 | } | ||
1081 | |||
1082 | -static int coroutine_fn | ||
1083 | +static int coroutine_fn GRAPH_RDLOCK | ||
1084 | vdi_co_preadv(BlockDriverState *bs, int64_t offset, int64_t bytes, | ||
1085 | QEMUIOVector *qiov, BdrvRequestFlags flags) | ||
1086 | { | ||
1087 | @@ -XXX,XX +XXX,XX @@ vdi_co_preadv(BlockDriverState *bs, int64_t offset, int64_t bytes, | ||
1088 | return ret; | ||
1089 | } | ||
1090 | |||
1091 | -static int coroutine_fn | ||
1092 | +static int coroutine_fn GRAPH_RDLOCK | ||
1093 | vdi_co_pwritev(BlockDriverState *bs, int64_t offset, int64_t bytes, | ||
1094 | QEMUIOVector *qiov, BdrvRequestFlags flags) | ||
1095 | { | ||
1096 | diff --git a/block/vhdx.c b/block/vhdx.c | ||
1097 | index XXXXXXX..XXXXXXX 100644 | ||
1098 | --- a/block/vhdx.c | ||
1099 | +++ b/block/vhdx.c | ||
1100 | @@ -XXX,XX +XXX,XX @@ vhdx_co_get_info(BlockDriverState *bs, BlockDriverInfo *bdi) | ||
1101 | } | ||
1102 | |||
1103 | |||
1104 | -static coroutine_fn int vhdx_co_readv(BlockDriverState *bs, int64_t sector_num, | ||
1105 | - int nb_sectors, QEMUIOVector *qiov) | ||
1106 | +static int coroutine_fn GRAPH_RDLOCK | ||
1107 | +vhdx_co_readv(BlockDriverState *bs, int64_t sector_num, int nb_sectors, | ||
1108 | + QEMUIOVector *qiov) | ||
1109 | { | ||
1110 | BDRVVHDXState *s = bs->opaque; | ||
1111 | int ret = 0; | ||
1112 | @@ -XXX,XX +XXX,XX @@ int vhdx_user_visible_write(BlockDriverState *bs, BDRVVHDXState *s) | ||
1113 | return ret; | ||
1114 | } | ||
1115 | |||
1116 | -static coroutine_fn int vhdx_co_writev(BlockDriverState *bs, int64_t sector_num, | ||
1117 | - int nb_sectors, QEMUIOVector *qiov, | ||
1118 | - int flags) | ||
1119 | +static int coroutine_fn GRAPH_RDLOCK | ||
1120 | +vhdx_co_writev(BlockDriverState *bs, int64_t sector_num, int nb_sectors, | ||
1121 | + QEMUIOVector *qiov, int flags) | ||
1122 | { | ||
1123 | int ret = -ENOTSUP; | ||
1124 | BDRVVHDXState *s = bs->opaque; | ||
1125 | diff --git a/block/vmdk.c b/block/vmdk.c | ||
1126 | index XXXXXXX..XXXXXXX 100644 | ||
1127 | --- a/block/vmdk.c | ||
1128 | +++ b/block/vmdk.c | ||
1129 | @@ -XXX,XX +XXX,XX @@ static void vmdk_refresh_limits(BlockDriverState *bs, Error **errp) | ||
1130 | * [@skip_start_sector, @skip_end_sector) is not copied or written, and leave | ||
1131 | * it for call to write user data in the request. | ||
1132 | */ | ||
1133 | -static int coroutine_fn get_whole_cluster(BlockDriverState *bs, | ||
1134 | - VmdkExtent *extent, | ||
1135 | - uint64_t cluster_offset, | ||
1136 | - uint64_t offset, | ||
1137 | - uint64_t skip_start_bytes, | ||
1138 | - uint64_t skip_end_bytes, | ||
1139 | - bool zeroed) | ||
1140 | +static int coroutine_fn GRAPH_RDLOCK | ||
1141 | +get_whole_cluster(BlockDriverState *bs, VmdkExtent *extent, | ||
1142 | + uint64_t cluster_offset, uint64_t offset, | ||
1143 | + uint64_t skip_start_bytes, uint64_t skip_end_bytes, | ||
1144 | + bool zeroed) | ||
1145 | { | ||
1146 | int ret = VMDK_OK; | ||
1147 | int64_t cluster_bytes; | ||
1148 | @@ -XXX,XX +XXX,XX @@ vmdk_L2update(VmdkExtent *extent, VmdkMetaData *m_data, uint32_t offset) | ||
1149 | * VMDK_UNALLOC if cluster is not mapped and @allocate is false. | ||
1150 | * VMDK_ERROR if failed. | ||
1151 | */ | ||
1152 | -static int coroutine_fn get_cluster_offset(BlockDriverState *bs, | ||
1153 | - VmdkExtent *extent, | ||
1154 | - VmdkMetaData *m_data, | ||
1155 | - uint64_t offset, | ||
1156 | - bool allocate, | ||
1157 | - uint64_t *cluster_offset, | ||
1158 | - uint64_t skip_start_bytes, | ||
1159 | - uint64_t skip_end_bytes) | ||
1160 | +static int coroutine_fn GRAPH_RDLOCK | ||
1161 | +get_cluster_offset(BlockDriverState *bs, VmdkExtent *extent, | ||
1162 | + VmdkMetaData *m_data, uint64_t offset, bool allocate, | ||
1163 | + uint64_t *cluster_offset, uint64_t skip_start_bytes, | ||
1164 | + uint64_t skip_end_bytes) | ||
1165 | { | ||
1166 | unsigned int l1_index, l2_offset, l2_index; | ||
1167 | int min_index, i, j; | ||
1168 | @@ -XXX,XX +XXX,XX @@ static inline uint64_t vmdk_find_offset_in_cluster(VmdkExtent *extent, | ||
1169 | return extent_relative_offset % cluster_size; | ||
1170 | } | ||
1171 | |||
1172 | -static int coroutine_fn vmdk_co_block_status(BlockDriverState *bs, | ||
1173 | - bool want_zero, | ||
1174 | - int64_t offset, int64_t bytes, | ||
1175 | - int64_t *pnum, int64_t *map, | ||
1176 | - BlockDriverState **file) | ||
1177 | +static int coroutine_fn GRAPH_RDLOCK | ||
1178 | +vmdk_co_block_status(BlockDriverState *bs, bool want_zero, | ||
1179 | + int64_t offset, int64_t bytes, int64_t *pnum, | ||
1180 | + int64_t *map, BlockDriverState **file) | ||
1181 | { | ||
1182 | BDRVVmdkState *s = bs->opaque; | ||
1183 | int64_t index_in_cluster, n, ret; | ||
1184 | @@ -XXX,XX +XXX,XX @@ static int coroutine_fn vmdk_co_block_status(BlockDriverState *bs, | ||
1185 | return ret; | ||
1186 | } | ||
1187 | |||
1188 | -static int coroutine_fn | ||
1189 | +static int coroutine_fn GRAPH_RDLOCK | ||
1190 | vmdk_write_extent(VmdkExtent *extent, int64_t cluster_offset, | ||
1191 | int64_t offset_in_cluster, QEMUIOVector *qiov, | ||
1192 | uint64_t qiov_offset, uint64_t n_bytes, | ||
1193 | @@ -XXX,XX +XXX,XX @@ vmdk_write_extent(VmdkExtent *extent, int64_t cluster_offset, | ||
1194 | return ret; | ||
1195 | } | ||
1196 | |||
1197 | -static int coroutine_fn | ||
1198 | +static int coroutine_fn GRAPH_RDLOCK | ||
1199 | vmdk_read_extent(VmdkExtent *extent, int64_t cluster_offset, | ||
1200 | - int64_t offset_in_cluster, QEMUIOVector *qiov, | ||
1201 | - int bytes) | ||
1202 | + int64_t offset_in_cluster, QEMUIOVector *qiov, int bytes) | ||
1203 | { | ||
1204 | int ret; | ||
1205 | int cluster_bytes, buf_bytes; | ||
1206 | @@ -XXX,XX +XXX,XX @@ vmdk_read_extent(VmdkExtent *extent, int64_t cluster_offset, | ||
1207 | return ret; | ||
1208 | } | ||
1209 | |||
1210 | -static int coroutine_fn | ||
1211 | +static int coroutine_fn GRAPH_RDLOCK | ||
1212 | vmdk_co_preadv(BlockDriverState *bs, int64_t offset, int64_t bytes, | ||
1213 | QEMUIOVector *qiov, BdrvRequestFlags flags) | ||
1214 | { | ||
1215 | @@ -XXX,XX +XXX,XX @@ fail: | ||
1216 | * | ||
1217 | * Returns: error code with 0 for success. | ||
1218 | */ | ||
1219 | -static int coroutine_fn vmdk_pwritev(BlockDriverState *bs, uint64_t offset, | ||
1220 | - uint64_t bytes, QEMUIOVector *qiov, | ||
1221 | - bool zeroed, bool zero_dry_run) | ||
1222 | +static int coroutine_fn GRAPH_RDLOCK | ||
1223 | +vmdk_pwritev(BlockDriverState *bs, uint64_t offset, uint64_t bytes, | ||
1224 | + QEMUIOVector *qiov, bool zeroed, bool zero_dry_run) | ||
1225 | { | ||
1226 | BDRVVmdkState *s = bs->opaque; | ||
1227 | VmdkExtent *extent = NULL; | ||
1228 | @@ -XXX,XX +XXX,XX @@ static int coroutine_fn vmdk_pwritev(BlockDriverState *bs, uint64_t offset, | ||
1229 | uint64_t bytes_done = 0; | ||
1230 | VmdkMetaData m_data; | ||
1231 | |||
1232 | - assume_graph_lock(); /* FIXME */ | ||
1233 | - | ||
1234 | if (DIV_ROUND_UP(offset, BDRV_SECTOR_SIZE) > bs->total_sectors) { | ||
1235 | error_report("Wrong offset: offset=0x%" PRIx64 | ||
1236 | " total_sectors=0x%" PRIx64, | ||
1237 | @@ -XXX,XX +XXX,XX @@ static int coroutine_fn vmdk_pwritev(BlockDriverState *bs, uint64_t offset, | ||
1238 | return 0; | ||
1239 | } | ||
1240 | |||
1241 | -static int coroutine_fn | ||
1242 | +static int coroutine_fn GRAPH_RDLOCK | ||
1243 | vmdk_co_pwritev(BlockDriverState *bs, int64_t offset, int64_t bytes, | ||
1244 | QEMUIOVector *qiov, BdrvRequestFlags flags) | ||
1245 | { | ||
1246 | @@ -XXX,XX +XXX,XX @@ vmdk_co_pwritev_compressed(BlockDriverState *bs, int64_t offset, int64_t bytes, | ||
1247 | return vmdk_co_pwritev(bs, offset, bytes, qiov, 0); | ||
1248 | } | ||
1249 | |||
1250 | -static int coroutine_fn vmdk_co_pwrite_zeroes(BlockDriverState *bs, | ||
1251 | - int64_t offset, | ||
1252 | - int64_t bytes, | ||
1253 | - BdrvRequestFlags flags) | ||
1254 | +static int coroutine_fn GRAPH_RDLOCK | ||
1255 | +vmdk_co_pwrite_zeroes(BlockDriverState *bs, int64_t offset, int64_t bytes, | ||
1256 | + BdrvRequestFlags flags) | ||
1257 | { | ||
1258 | int ret; | ||
1259 | BDRVVmdkState *s = bs->opaque; | ||
1260 | @@ -XXX,XX +XXX,XX @@ static VmdkExtentInfo *vmdk_get_extent_info(VmdkExtent *extent) | ||
1261 | return info; | ||
1262 | } | ||
1263 | |||
1264 | -static int coroutine_fn vmdk_co_check(BlockDriverState *bs, | ||
1265 | - BdrvCheckResult *result, | ||
1266 | - BdrvCheckMode fix) | ||
1267 | +static int coroutine_fn GRAPH_RDLOCK | ||
1268 | +vmdk_co_check(BlockDriverState *bs, BdrvCheckResult *result, BdrvCheckMode fix) | ||
1269 | { | ||
1270 | BDRVVmdkState *s = bs->opaque; | ||
1271 | VmdkExtent *extent = NULL; | ||
1272 | diff --git a/block/vpc.c b/block/vpc.c | ||
1273 | index XXXXXXX..XXXXXXX 100644 | ||
1274 | --- a/block/vpc.c | ||
1275 | +++ b/block/vpc.c | ||
1276 | @@ -XXX,XX +XXX,XX @@ vpc_co_get_info(BlockDriverState *bs, BlockDriverInfo *bdi) | ||
1277 | return 0; | ||
1278 | } | ||
1279 | |||
1280 | -static int coroutine_fn | ||
1281 | +static int coroutine_fn GRAPH_RDLOCK | ||
1282 | vpc_co_preadv(BlockDriverState *bs, int64_t offset, int64_t bytes, | ||
1283 | QEMUIOVector *qiov, BdrvRequestFlags flags) | ||
1284 | { | ||
1285 | @@ -XXX,XX +XXX,XX @@ fail: | ||
1286 | return ret; | ||
1287 | } | ||
1288 | |||
1289 | -static int coroutine_fn | ||
1290 | +static int coroutine_fn GRAPH_RDLOCK | ||
1291 | vpc_co_pwritev(BlockDriverState *bs, int64_t offset, int64_t bytes, | ||
1292 | QEMUIOVector *qiov, BdrvRequestFlags flags) | ||
1293 | { | ||
1294 | diff --git a/tests/unit/test-bdrv-drain.c b/tests/unit/test-bdrv-drain.c | ||
1295 | index XXXXXXX..XXXXXXX 100644 | ||
1296 | --- a/tests/unit/test-bdrv-drain.c | ||
1297 | +++ b/tests/unit/test-bdrv-drain.c | ||
1298 | @@ -XXX,XX +XXX,XX @@ static void bdrv_test_top_close(BlockDriverState *bs) | ||
1299 | } | ||
1300 | } | ||
1301 | |||
1302 | -static int coroutine_fn bdrv_test_top_co_preadv(BlockDriverState *bs, | ||
1303 | - int64_t offset, int64_t bytes, | ||
1304 | - QEMUIOVector *qiov, | ||
1305 | - BdrvRequestFlags flags) | ||
1306 | +static int coroutine_fn GRAPH_RDLOCK | ||
1307 | +bdrv_test_top_co_preadv(BlockDriverState *bs, int64_t offset, int64_t bytes, | ||
1308 | + QEMUIOVector *qiov, BdrvRequestFlags flags) | ||
1309 | { | ||
1310 | BDRVTestTopState *tts = bs->opaque; | ||
1311 | return bdrv_co_preadv(tts->wait_child, offset, bytes, qiov, flags); | ||
1312 | @@ -XXX,XX +XXX,XX @@ static void coroutine_fn test_co_delete_by_drain(void *opaque) | ||
1313 | void *buffer = g_malloc(65536); | ||
1314 | QEMUIOVector qiov = QEMU_IOVEC_INIT_BUF(qiov, buffer, 65536); | ||
1315 | |||
1316 | + GRAPH_RDLOCK_GUARD(); | ||
1317 | + | ||
1318 | /* Pretend some internal write operation from parent to child. | ||
1319 | * Important: We have to read from the child, not from the parent! | ||
1320 | * Draining works by first propagating it all up the tree to the | ||
1321 | @@ -XXX,XX +XXX,XX @@ static void bdrv_replace_test_close(BlockDriverState *bs) | ||
1322 | * Otherwise: | ||
1323 | * Set .has_read to true and return success. | ||
1324 | */ | ||
1325 | -static int coroutine_fn bdrv_replace_test_co_preadv(BlockDriverState *bs, | ||
1326 | - int64_t offset, | ||
1327 | - int64_t bytes, | ||
1328 | - QEMUIOVector *qiov, | ||
1329 | - BdrvRequestFlags flags) | ||
1330 | +static int coroutine_fn GRAPH_RDLOCK | ||
1331 | +bdrv_replace_test_co_preadv(BlockDriverState *bs, int64_t offset, int64_t bytes, | ||
1332 | + QEMUIOVector *qiov, BdrvRequestFlags flags) | ||
1333 | { | ||
1334 | BDRVReplaceTestState *s = bs->opaque; | ||
1335 | |||
1336 | @@ -XXX,XX +XXX,XX @@ static void coroutine_fn bdrv_replace_test_read_entry(void *opaque) | ||
1337 | int ret; | ||
1338 | |||
1339 | /* Queue a read request post-drain */ | ||
1340 | + bdrv_graph_co_rdlock(); | ||
1341 | ret = bdrv_replace_test_co_preadv(bs, 0, 1, &qiov, 0); | ||
1342 | + bdrv_graph_co_rdunlock(); | ||
1343 | + | ||
1344 | g_assert(ret >= 0); | ||
1345 | bdrv_dec_in_flight(bs); | ||
1346 | } | ||
1347 | -- | ||
1348 | 2.39.2 | diff view generated by jsdifflib |
Deleted patch | |||
---|---|---|---|
1 | This adds GRAPH_RDLOCK annotations to declare that callers of | ||
2 | bdrv_co_pwrite_sync() need to hold a reader lock for the graph. | ||
3 | 1 | ||
4 | For some places, we know that they will hold the lock, but we don't have | ||
5 | the GRAPH_RDLOCK annotations yet. In this case, add assume_graph_lock() | ||
6 | with a FIXME comment. These places will be removed once everything is | ||
7 | properly annotated. | ||
8 | |||
9 | Signed-off-by: Kevin Wolf <kwolf@redhat.com> | ||
10 | Message-Id: <20230203152202.49054-13-kwolf@redhat.com> | ||
11 | Reviewed-by: Emanuele Giuseppe Esposito <eesposit@redhat.com> | ||
12 | Signed-off-by: Kevin Wolf <kwolf@redhat.com> | ||
13 | --- | ||
14 | block/qcow2.h | 2 +- | ||
15 | include/block/block-io.h | 7 ++++--- | ||
16 | block/io.c | 3 +-- | ||
17 | 3 files changed, 6 insertions(+), 6 deletions(-) | ||
18 | |||
19 | diff --git a/block/qcow2.h b/block/qcow2.h | ||
20 | index XXXXXXX..XXXXXXX 100644 | ||
21 | --- a/block/qcow2.h | ||
22 | +++ b/block/qcow2.h | ||
23 | @@ -XXX,XX +XXX,XX @@ int qcow2_inc_refcounts_imrt(BlockDriverState *bs, BdrvCheckResult *res, | ||
24 | int qcow2_change_refcount_order(BlockDriverState *bs, int refcount_order, | ||
25 | BlockDriverAmendStatusCB *status_cb, | ||
26 | void *cb_opaque, Error **errp); | ||
27 | -int coroutine_fn qcow2_shrink_reftable(BlockDriverState *bs); | ||
28 | +int coroutine_fn GRAPH_RDLOCK qcow2_shrink_reftable(BlockDriverState *bs); | ||
29 | int64_t qcow2_get_last_cluster(BlockDriverState *bs, int64_t size); | ||
30 | int coroutine_fn qcow2_detect_metadata_preallocation(BlockDriverState *bs); | ||
31 | |||
32 | diff --git a/include/block/block-io.h b/include/block/block-io.h | ||
33 | index XXXXXXX..XXXXXXX 100644 | ||
34 | --- a/include/block/block-io.h | ||
35 | +++ b/include/block/block-io.h | ||
36 | @@ -XXX,XX +XXX,XX @@ int co_wrapper_mixed_bdrv_rdlock | ||
37 | bdrv_pwrite_sync(BdrvChild *child, int64_t offset, int64_t bytes, | ||
38 | const void *buf, BdrvRequestFlags flags); | ||
39 | |||
40 | -int coroutine_fn bdrv_co_pwrite_sync(BdrvChild *child, int64_t offset, | ||
41 | - int64_t bytes, const void *buf, | ||
42 | - BdrvRequestFlags flags); | ||
43 | +int coroutine_fn GRAPH_RDLOCK | ||
44 | +bdrv_co_pwrite_sync(BdrvChild *child, int64_t offset, int64_t bytes, | ||
45 | + const void *buf, BdrvRequestFlags flags); | ||
46 | + | ||
47 | /* | ||
48 | * Efficiently zero a region of the disk image. Note that this is a regular | ||
49 | * I/O request like read or write and should have a reasonable size. This | ||
50 | diff --git a/block/io.c b/block/io.c | ||
51 | index XXXXXXX..XXXXXXX 100644 | ||
52 | --- a/block/io.c | ||
53 | +++ b/block/io.c | ||
54 | @@ -XXX,XX +XXX,XX @@ int coroutine_fn bdrv_co_pwrite_sync(BdrvChild *child, int64_t offset, | ||
55 | { | ||
56 | int ret; | ||
57 | IO_CODE(); | ||
58 | - | ||
59 | - assume_graph_lock(); /* FIXME */ | ||
60 | + assert_bdrv_graph_readable(); | ||
61 | |||
62 | ret = bdrv_co_pwrite(child, offset, bytes, buf, flags); | ||
63 | if (ret < 0) { | ||
64 | -- | ||
65 | 2.39.2 | diff view generated by jsdifflib |
Deleted patch | |||
---|---|---|---|
1 | All callers are already GRAPH_RDLOCK, so just add the annotation and | ||
2 | remove assume_graph_lock(). | ||
3 | 1 | ||
4 | Signed-off-by: Kevin Wolf <kwolf@redhat.com> | ||
5 | Message-Id: <20230203152202.49054-14-kwolf@redhat.com> | ||
6 | Reviewed-by: Emanuele Giuseppe Esposito <eesposit@redhat.com> | ||
7 | Signed-off-by: Kevin Wolf <kwolf@redhat.com> | ||
8 | --- | ||
9 | block/io.c | 7 +++---- | ||
10 | 1 file changed, 3 insertions(+), 4 deletions(-) | ||
11 | |||
12 | diff --git a/block/io.c b/block/io.c | ||
13 | index XXXXXXX..XXXXXXX 100644 | ||
14 | --- a/block/io.c | ||
15 | +++ b/block/io.c | ||
16 | @@ -XXX,XX +XXX,XX @@ fail: | ||
17 | return ret; | ||
18 | } | ||
19 | |||
20 | -static int coroutine_fn bdrv_co_do_pwrite_zeroes(BlockDriverState *bs, | ||
21 | - int64_t offset, int64_t bytes, BdrvRequestFlags flags) | ||
22 | +static int coroutine_fn GRAPH_RDLOCK | ||
23 | +bdrv_co_do_pwrite_zeroes(BlockDriverState *bs, int64_t offset, int64_t bytes, | ||
24 | + BdrvRequestFlags flags) | ||
25 | { | ||
26 | BlockDriver *drv = bs->drv; | ||
27 | QEMUIOVector qiov; | ||
28 | @@ -XXX,XX +XXX,XX @@ static int coroutine_fn bdrv_co_do_pwrite_zeroes(BlockDriverState *bs, | ||
29 | int head = 0; | ||
30 | int tail = 0; | ||
31 | |||
32 | - assume_graph_lock(); /* FIXME */ | ||
33 | - | ||
34 | int64_t max_write_zeroes = MIN_NON_ZERO(bs->bl.max_pwrite_zeroes, | ||
35 | INT64_MAX); | ||
36 | int alignment = MAX(bs->bl.pwrite_zeroes_alignment, | ||
37 | -- | ||
38 | 2.39.2 | diff view generated by jsdifflib |
Deleted patch | |||
---|---|---|---|
1 | From: Emanuele Giuseppe Esposito <eesposit@redhat.com> | ||
2 | 1 | ||
3 | This adds GRAPH_RDLOCK annotations to declare that callers of | ||
4 | bdrv_co_copy_range() need to hold a reader lock for the graph. | ||
5 | |||
6 | Signed-off-by: Emanuele Giuseppe Esposito <eesposit@redhat.com> | ||
7 | Signed-off-by: Kevin Wolf <kwolf@redhat.com> | ||
8 | Message-Id: <20230203152202.49054-15-kwolf@redhat.com> | ||
9 | Reviewed-by: Emanuele Giuseppe Esposito <eesposit@redhat.com> | ||
10 | Signed-off-by: Kevin Wolf <kwolf@redhat.com> | ||
11 | --- | ||
12 | include/block/block-io.h | 9 +++++---- | ||
13 | include/block/block_int-common.h | 24 ++++++++---------------- | ||
14 | include/block/block_int-io.h | 20 ++++++++++---------- | ||
15 | block/block-backend.c | 2 ++ | ||
16 | block/file-posix.c | 16 +++++++--------- | ||
17 | block/io.c | 7 +++++-- | ||
18 | block/iscsi.c | 28 ++++++++++++---------------- | ||
19 | block/qcow2.c | 5 ++--- | ||
20 | block/raw-format.c | 28 ++++++++++++---------------- | ||
21 | qemu-img.c | 4 +++- | ||
22 | 10 files changed, 66 insertions(+), 77 deletions(-) | ||
23 | |||
24 | diff --git a/include/block/block-io.h b/include/block/block-io.h | ||
25 | index XXXXXXX..XXXXXXX 100644 | ||
26 | --- a/include/block/block-io.h | ||
27 | +++ b/include/block/block-io.h | ||
28 | @@ -XXX,XX +XXX,XX @@ bool co_wrapper bdrv_can_store_new_dirty_bitmap(BlockDriverState *bs, | ||
29 | * | ||
30 | * Returns: 0 if succeeded; negative error code if failed. | ||
31 | **/ | ||
32 | -int coroutine_fn bdrv_co_copy_range(BdrvChild *src, int64_t src_offset, | ||
33 | - BdrvChild *dst, int64_t dst_offset, | ||
34 | - int64_t bytes, BdrvRequestFlags read_flags, | ||
35 | - BdrvRequestFlags write_flags); | ||
36 | +int coroutine_fn GRAPH_RDLOCK | ||
37 | +bdrv_co_copy_range(BdrvChild *src, int64_t src_offset, | ||
38 | + BdrvChild *dst, int64_t dst_offset, | ||
39 | + int64_t bytes, BdrvRequestFlags read_flags, | ||
40 | + BdrvRequestFlags write_flags); | ||
41 | |||
42 | /* | ||
43 | * "I/O or GS" API functions. These functions can run without | ||
44 | diff --git a/include/block/block_int-common.h b/include/block/block_int-common.h | ||
45 | index XXXXXXX..XXXXXXX 100644 | ||
46 | --- a/include/block/block_int-common.h | ||
47 | +++ b/include/block/block_int-common.h | ||
48 | @@ -XXX,XX +XXX,XX @@ struct BlockDriver { | ||
49 | * See the comment of bdrv_co_copy_range for the parameter and return value | ||
50 | * semantics. | ||
51 | */ | ||
52 | - int coroutine_fn (*bdrv_co_copy_range_from)(BlockDriverState *bs, | ||
53 | - BdrvChild *src, | ||
54 | - int64_t offset, | ||
55 | - BdrvChild *dst, | ||
56 | - int64_t dst_offset, | ||
57 | - int64_t bytes, | ||
58 | - BdrvRequestFlags read_flags, | ||
59 | - BdrvRequestFlags write_flags); | ||
60 | + int coroutine_fn GRAPH_RDLOCK_PTR (*bdrv_co_copy_range_from)( | ||
61 | + BlockDriverState *bs, BdrvChild *src, int64_t offset, | ||
62 | + BdrvChild *dst, int64_t dst_offset, int64_t bytes, | ||
63 | + BdrvRequestFlags read_flags, BdrvRequestFlags write_flags); | ||
64 | |||
65 | /* | ||
66 | * Map [offset, offset + nbytes) range onto a child of bs to copy data to, | ||
67 | @@ -XXX,XX +XXX,XX @@ struct BlockDriver { | ||
68 | * See the comment of bdrv_co_copy_range for the parameter and return value | ||
69 | * semantics. | ||
70 | */ | ||
71 | - int coroutine_fn (*bdrv_co_copy_range_to)(BlockDriverState *bs, | ||
72 | - BdrvChild *src, | ||
73 | - int64_t src_offset, | ||
74 | - BdrvChild *dst, | ||
75 | - int64_t dst_offset, | ||
76 | - int64_t bytes, | ||
77 | - BdrvRequestFlags read_flags, | ||
78 | - BdrvRequestFlags write_flags); | ||
79 | + int coroutine_fn GRAPH_RDLOCK_PTR (*bdrv_co_copy_range_to)( | ||
80 | + BlockDriverState *bs, BdrvChild *src, int64_t src_offset, | ||
81 | + BdrvChild *dst, int64_t dst_offset, int64_t bytes, | ||
82 | + BdrvRequestFlags read_flags, BdrvRequestFlags write_flags); | ||
83 | |||
84 | /* | ||
85 | * Building block for bdrv_block_status[_above] and | ||
86 | diff --git a/include/block/block_int-io.h b/include/block/block_int-io.h | ||
87 | index XXXXXXX..XXXXXXX 100644 | ||
88 | --- a/include/block/block_int-io.h | ||
89 | +++ b/include/block/block_int-io.h | ||
90 | @@ -XXX,XX +XXX,XX @@ void bdrv_dirty_bitmap_merge_internal(BdrvDirtyBitmap *dest, | ||
91 | void bdrv_inc_in_flight(BlockDriverState *bs); | ||
92 | void bdrv_dec_in_flight(BlockDriverState *bs); | ||
93 | |||
94 | -int coroutine_fn bdrv_co_copy_range_from(BdrvChild *src, int64_t src_offset, | ||
95 | - BdrvChild *dst, int64_t dst_offset, | ||
96 | - int64_t bytes, | ||
97 | - BdrvRequestFlags read_flags, | ||
98 | - BdrvRequestFlags write_flags); | ||
99 | -int coroutine_fn bdrv_co_copy_range_to(BdrvChild *src, int64_t src_offset, | ||
100 | - BdrvChild *dst, int64_t dst_offset, | ||
101 | - int64_t bytes, | ||
102 | - BdrvRequestFlags read_flags, | ||
103 | - BdrvRequestFlags write_flags); | ||
104 | +int coroutine_fn GRAPH_RDLOCK | ||
105 | +bdrv_co_copy_range_from(BdrvChild *src, int64_t src_offset, | ||
106 | + BdrvChild *dst, int64_t dst_offset, | ||
107 | + int64_t bytes, BdrvRequestFlags read_flags, | ||
108 | + BdrvRequestFlags write_flags); | ||
109 | +int coroutine_fn GRAPH_RDLOCK | ||
110 | +bdrv_co_copy_range_to(BdrvChild *src, int64_t src_offset, | ||
111 | + BdrvChild *dst, int64_t dst_offset, | ||
112 | + int64_t bytes, BdrvRequestFlags read_flags, | ||
113 | + BdrvRequestFlags write_flags); | ||
114 | |||
115 | int coroutine_fn bdrv_co_refresh_total_sectors(BlockDriverState *bs, | ||
116 | int64_t hint); | ||
117 | diff --git a/block/block-backend.c b/block/block-backend.c | ||
118 | index XXXXXXX..XXXXXXX 100644 | ||
119 | --- a/block/block-backend.c | ||
120 | +++ b/block/block-backend.c | ||
121 | @@ -XXX,XX +XXX,XX @@ int coroutine_fn blk_co_copy_range(BlockBackend *blk_in, int64_t off_in, | ||
122 | if (r) { | ||
123 | return r; | ||
124 | } | ||
125 | + | ||
126 | + GRAPH_RDLOCK_GUARD(); | ||
127 | return bdrv_co_copy_range(blk_in->root, off_in, | ||
128 | blk_out->root, off_out, | ||
129 | bytes, read_flags, write_flags); | ||
130 | diff --git a/block/file-posix.c b/block/file-posix.c | ||
131 | index XXXXXXX..XXXXXXX 100644 | ||
132 | --- a/block/file-posix.c | ||
133 | +++ b/block/file-posix.c | ||
134 | @@ -XXX,XX +XXX,XX @@ static void raw_abort_perm_update(BlockDriverState *bs) | ||
135 | raw_handle_perm_lock(bs, RAW_PL_ABORT, 0, 0, NULL); | ||
136 | } | ||
137 | |||
138 | -static int coroutine_fn raw_co_copy_range_from( | ||
139 | +static int coroutine_fn GRAPH_RDLOCK raw_co_copy_range_from( | ||
140 | BlockDriverState *bs, BdrvChild *src, int64_t src_offset, | ||
141 | BdrvChild *dst, int64_t dst_offset, int64_t bytes, | ||
142 | BdrvRequestFlags read_flags, BdrvRequestFlags write_flags) | ||
143 | @@ -XXX,XX +XXX,XX @@ static int coroutine_fn raw_co_copy_range_from( | ||
144 | read_flags, write_flags); | ||
145 | } | ||
146 | |||
147 | -static int coroutine_fn raw_co_copy_range_to(BlockDriverState *bs, | ||
148 | - BdrvChild *src, | ||
149 | - int64_t src_offset, | ||
150 | - BdrvChild *dst, | ||
151 | - int64_t dst_offset, | ||
152 | - int64_t bytes, | ||
153 | - BdrvRequestFlags read_flags, | ||
154 | - BdrvRequestFlags write_flags) | ||
155 | +static int coroutine_fn GRAPH_RDLOCK | ||
156 | +raw_co_copy_range_to(BlockDriverState *bs, | ||
157 | + BdrvChild *src, int64_t src_offset, | ||
158 | + BdrvChild *dst, int64_t dst_offset, | ||
159 | + int64_t bytes, BdrvRequestFlags read_flags, | ||
160 | + BdrvRequestFlags write_flags) | ||
161 | { | ||
162 | RawPosixAIOData acb; | ||
163 | BDRVRawState *s = bs->opaque; | ||
164 | diff --git a/block/io.c b/block/io.c | ||
165 | index XXXXXXX..XXXXXXX 100644 | ||
166 | --- a/block/io.c | ||
167 | +++ b/block/io.c | ||
168 | @@ -XXX,XX +XXX,XX @@ static int coroutine_fn GRAPH_RDLOCK bdrv_co_copy_range_internal( | ||
169 | { | ||
170 | BdrvTrackedRequest req; | ||
171 | int ret; | ||
172 | + assert_bdrv_graph_readable(); | ||
173 | |||
174 | /* TODO We can support BDRV_REQ_NO_FALLBACK here */ | ||
175 | assert(!(read_flags & BDRV_REQ_NO_FALLBACK)); | ||
176 | @@ -XXX,XX +XXX,XX @@ int coroutine_fn bdrv_co_copy_range_from(BdrvChild *src, int64_t src_offset, | ||
177 | BdrvRequestFlags write_flags) | ||
178 | { | ||
179 | IO_CODE(); | ||
180 | - assume_graph_lock(); /* FIXME */ | ||
181 | + assert_bdrv_graph_readable(); | ||
182 | trace_bdrv_co_copy_range_from(src, src_offset, dst, dst_offset, bytes, | ||
183 | read_flags, write_flags); | ||
184 | return bdrv_co_copy_range_internal(src, src_offset, dst, dst_offset, | ||
185 | @@ -XXX,XX +XXX,XX @@ int coroutine_fn bdrv_co_copy_range_to(BdrvChild *src, int64_t src_offset, | ||
186 | BdrvRequestFlags write_flags) | ||
187 | { | ||
188 | IO_CODE(); | ||
189 | - assume_graph_lock(); /* FIXME */ | ||
190 | + assert_bdrv_graph_readable(); | ||
191 | trace_bdrv_co_copy_range_to(src, src_offset, dst, dst_offset, bytes, | ||
192 | read_flags, write_flags); | ||
193 | return bdrv_co_copy_range_internal(src, src_offset, dst, dst_offset, | ||
194 | @@ -XXX,XX +XXX,XX @@ int coroutine_fn bdrv_co_copy_range(BdrvChild *src, int64_t src_offset, | ||
195 | BdrvRequestFlags write_flags) | ||
196 | { | ||
197 | IO_CODE(); | ||
198 | + assert_bdrv_graph_readable(); | ||
199 | + | ||
200 | return bdrv_co_copy_range_from(src, src_offset, | ||
201 | dst, dst_offset, | ||
202 | bytes, read_flags, write_flags); | ||
203 | diff --git a/block/iscsi.c b/block/iscsi.c | ||
204 | index XXXXXXX..XXXXXXX 100644 | ||
205 | --- a/block/iscsi.c | ||
206 | +++ b/block/iscsi.c | ||
207 | @@ -XXX,XX +XXX,XX @@ static void coroutine_fn iscsi_co_invalidate_cache(BlockDriverState *bs, | ||
208 | iscsi_allocmap_invalidate(iscsilun); | ||
209 | } | ||
210 | |||
211 | -static int coroutine_fn iscsi_co_copy_range_from(BlockDriverState *bs, | ||
212 | - BdrvChild *src, | ||
213 | - int64_t src_offset, | ||
214 | - BdrvChild *dst, | ||
215 | - int64_t dst_offset, | ||
216 | - int64_t bytes, | ||
217 | - BdrvRequestFlags read_flags, | ||
218 | - BdrvRequestFlags write_flags) | ||
219 | +static int coroutine_fn GRAPH_RDLOCK | ||
220 | +iscsi_co_copy_range_from(BlockDriverState *bs, | ||
221 | + BdrvChild *src, int64_t src_offset, | ||
222 | + BdrvChild *dst, int64_t dst_offset, | ||
223 | + int64_t bytes, BdrvRequestFlags read_flags, | ||
224 | + BdrvRequestFlags write_flags) | ||
225 | { | ||
226 | return bdrv_co_copy_range_to(src, src_offset, dst, dst_offset, bytes, | ||
227 | read_flags, write_flags); | ||
228 | @@ -XXX,XX +XXX,XX @@ static void iscsi_xcopy_data(struct iscsi_data *data, | ||
229 | src_lba, dst_lba); | ||
230 | } | ||
231 | |||
232 | -static int coroutine_fn iscsi_co_copy_range_to(BlockDriverState *bs, | ||
233 | - BdrvChild *src, | ||
234 | - int64_t src_offset, | ||
235 | - BdrvChild *dst, | ||
236 | - int64_t dst_offset, | ||
237 | - int64_t bytes, | ||
238 | - BdrvRequestFlags read_flags, | ||
239 | - BdrvRequestFlags write_flags) | ||
240 | +static int coroutine_fn GRAPH_RDLOCK | ||
241 | +iscsi_co_copy_range_to(BlockDriverState *bs, | ||
242 | + BdrvChild *src, int64_t src_offset, | ||
243 | + BdrvChild *dst, int64_t dst_offset, | ||
244 | + int64_t bytes, BdrvRequestFlags read_flags, | ||
245 | + BdrvRequestFlags write_flags) | ||
246 | { | ||
247 | IscsiLun *dst_lun = dst->bs->opaque; | ||
248 | IscsiLun *src_lun; | ||
249 | diff --git a/block/qcow2.c b/block/qcow2.c | ||
250 | index XXXXXXX..XXXXXXX 100644 | ||
251 | --- a/block/qcow2.c | ||
252 | +++ b/block/qcow2.c | ||
253 | @@ -XXX,XX +XXX,XX @@ static coroutine_fn int qcow2_co_pdiscard(BlockDriverState *bs, | ||
254 | return ret; | ||
255 | } | ||
256 | |||
257 | -static int coroutine_fn | ||
258 | +static int coroutine_fn GRAPH_RDLOCK | ||
259 | qcow2_co_copy_range_from(BlockDriverState *bs, | ||
260 | BdrvChild *src, int64_t src_offset, | ||
261 | BdrvChild *dst, int64_t dst_offset, | ||
262 | @@ -XXX,XX +XXX,XX @@ out: | ||
263 | return ret; | ||
264 | } | ||
265 | |||
266 | -static int coroutine_fn | ||
267 | +static int coroutine_fn GRAPH_RDLOCK | ||
268 | qcow2_co_copy_range_to(BlockDriverState *bs, | ||
269 | BdrvChild *src, int64_t src_offset, | ||
270 | BdrvChild *dst, int64_t dst_offset, | ||
271 | @@ -XXX,XX +XXX,XX @@ qcow2_co_copy_range_to(BlockDriverState *bs, | ||
272 | uint64_t host_offset; | ||
273 | QCowL2Meta *l2meta = NULL; | ||
274 | |||
275 | - assume_graph_lock(); /* FIXME */ | ||
276 | assert(!bs->encrypted); | ||
277 | |||
278 | qemu_co_mutex_lock(&s->lock); | ||
279 | diff --git a/block/raw-format.c b/block/raw-format.c | ||
280 | index XXXXXXX..XXXXXXX 100644 | ||
281 | --- a/block/raw-format.c | ||
282 | +++ b/block/raw-format.c | ||
283 | @@ -XXX,XX +XXX,XX @@ static int raw_probe_geometry(BlockDriverState *bs, HDGeometry *geo) | ||
284 | return bdrv_probe_geometry(bs->file->bs, geo); | ||
285 | } | ||
286 | |||
287 | -static int coroutine_fn raw_co_copy_range_from(BlockDriverState *bs, | ||
288 | - BdrvChild *src, | ||
289 | - int64_t src_offset, | ||
290 | - BdrvChild *dst, | ||
291 | - int64_t dst_offset, | ||
292 | - int64_t bytes, | ||
293 | - BdrvRequestFlags read_flags, | ||
294 | - BdrvRequestFlags write_flags) | ||
295 | +static int coroutine_fn GRAPH_RDLOCK | ||
296 | +raw_co_copy_range_from(BlockDriverState *bs, | ||
297 | + BdrvChild *src, int64_t src_offset, | ||
298 | + BdrvChild *dst, int64_t dst_offset, | ||
299 | + int64_t bytes, BdrvRequestFlags read_flags, | ||
300 | + BdrvRequestFlags write_flags) | ||
301 | { | ||
302 | int ret; | ||
303 | |||
304 | @@ -XXX,XX +XXX,XX @@ static int coroutine_fn raw_co_copy_range_from(BlockDriverState *bs, | ||
305 | bytes, read_flags, write_flags); | ||
306 | } | ||
307 | |||
308 | -static int coroutine_fn raw_co_copy_range_to(BlockDriverState *bs, | ||
309 | - BdrvChild *src, | ||
310 | - int64_t src_offset, | ||
311 | - BdrvChild *dst, | ||
312 | - int64_t dst_offset, | ||
313 | - int64_t bytes, | ||
314 | - BdrvRequestFlags read_flags, | ||
315 | - BdrvRequestFlags write_flags) | ||
316 | +static int coroutine_fn GRAPH_RDLOCK | ||
317 | +raw_co_copy_range_to(BlockDriverState *bs, | ||
318 | + BdrvChild *src, int64_t src_offset, | ||
319 | + BdrvChild *dst, int64_t dst_offset, | ||
320 | + int64_t bytes, BdrvRequestFlags read_flags, | ||
321 | + BdrvRequestFlags write_flags) | ||
322 | { | ||
323 | int ret; | ||
324 | |||
325 | diff --git a/qemu-img.c b/qemu-img.c | ||
326 | index XXXXXXX..XXXXXXX 100644 | ||
327 | --- a/qemu-img.c | ||
328 | +++ b/qemu-img.c | ||
329 | @@ -XXX,XX +XXX,XX @@ retry: | ||
330 | |||
331 | if (s->ret == -EINPROGRESS) { | ||
332 | if (copy_range) { | ||
333 | - ret = convert_co_copy_range(s, sector_num, n); | ||
334 | + WITH_GRAPH_RDLOCK_GUARD() { | ||
335 | + ret = convert_co_copy_range(s, sector_num, n); | ||
336 | + } | ||
337 | if (ret) { | ||
338 | s->copy_range = false; | ||
339 | goto retry; | ||
340 | -- | ||
341 | 2.39.2 | diff view generated by jsdifflib |
Deleted patch | |||
---|---|---|---|
1 | Signed-off-by: Kevin Wolf <kwolf@redhat.com> | ||
2 | Message-Id: <20230203152202.49054-16-kwolf@redhat.com> | ||
3 | Reviewed-by: Emanuele Giuseppe Esposito <eesposit@redhat.com> | ||
4 | Signed-off-by: Kevin Wolf <kwolf@redhat.com> | ||
5 | --- | ||
6 | include/block/block_int-common.h | 12 +++++++----- | ||
7 | include/block/block_int-io.h | 8 ++++---- | ||
8 | block/copy-before-write.c | 6 ++---- | ||
9 | block/io.c | 2 ++ | ||
10 | block/snapshot-access.c | 4 ++-- | ||
11 | 5 files changed, 17 insertions(+), 15 deletions(-) | ||
12 | 1 | ||
13 | diff --git a/include/block/block_int-common.h b/include/block/block_int-common.h | ||
14 | index XXXXXXX..XXXXXXX 100644 | ||
15 | --- a/include/block/block_int-common.h | ||
16 | +++ b/include/block/block_int-common.h | ||
17 | @@ -XXX,XX +XXX,XX @@ struct BlockDriver { | ||
18 | * - receive the snapshot's actual length (which may differ from bs's | ||
19 | * length) | ||
20 | */ | ||
21 | - int coroutine_fn (*bdrv_co_preadv_snapshot)(BlockDriverState *bs, | ||
22 | - int64_t offset, int64_t bytes, QEMUIOVector *qiov, size_t qiov_offset); | ||
23 | - int coroutine_fn (*bdrv_co_snapshot_block_status)(BlockDriverState *bs, | ||
24 | - bool want_zero, int64_t offset, int64_t bytes, int64_t *pnum, | ||
25 | - int64_t *map, BlockDriverState **file); | ||
26 | + int coroutine_fn GRAPH_RDLOCK_PTR (*bdrv_co_preadv_snapshot)( | ||
27 | + BlockDriverState *bs, int64_t offset, int64_t bytes, | ||
28 | + QEMUIOVector *qiov, size_t qiov_offset); | ||
29 | + | ||
30 | + int coroutine_fn GRAPH_RDLOCK_PTR (*bdrv_co_snapshot_block_status)( | ||
31 | + BlockDriverState *bs, bool want_zero, int64_t offset, int64_t bytes, | ||
32 | + int64_t *pnum, int64_t *map, BlockDriverState **file); | ||
33 | |||
34 | int coroutine_fn GRAPH_RDLOCK_PTR (*bdrv_co_pdiscard_snapshot)( | ||
35 | BlockDriverState *bs, int64_t offset, int64_t bytes); | ||
36 | diff --git a/include/block/block_int-io.h b/include/block/block_int-io.h | ||
37 | index XXXXXXX..XXXXXXX 100644 | ||
38 | --- a/include/block/block_int-io.h | ||
39 | +++ b/include/block/block_int-io.h | ||
40 | @@ -XXX,XX +XXX,XX @@ | ||
41 | * the I/O API. | ||
42 | */ | ||
43 | |||
44 | -int coroutine_fn bdrv_co_preadv_snapshot(BdrvChild *child, | ||
45 | +int coroutine_fn GRAPH_RDLOCK bdrv_co_preadv_snapshot(BdrvChild *child, | ||
46 | int64_t offset, int64_t bytes, QEMUIOVector *qiov, size_t qiov_offset); | ||
47 | -int coroutine_fn bdrv_co_snapshot_block_status(BlockDriverState *bs, | ||
48 | - bool want_zero, int64_t offset, int64_t bytes, int64_t *pnum, | ||
49 | - int64_t *map, BlockDriverState **file); | ||
50 | +int coroutine_fn GRAPH_RDLOCK bdrv_co_snapshot_block_status( | ||
51 | + BlockDriverState *bs, bool want_zero, int64_t offset, int64_t bytes, | ||
52 | + int64_t *pnum, int64_t *map, BlockDriverState **file); | ||
53 | int coroutine_fn GRAPH_RDLOCK bdrv_co_pdiscard_snapshot(BlockDriverState *bs, | ||
54 | int64_t offset, int64_t bytes); | ||
55 | |||
56 | diff --git a/block/copy-before-write.c b/block/copy-before-write.c | ||
57 | index XXXXXXX..XXXXXXX 100644 | ||
58 | --- a/block/copy-before-write.c | ||
59 | +++ b/block/copy-before-write.c | ||
60 | @@ -XXX,XX +XXX,XX @@ cbw_snapshot_read_unlock(BlockDriverState *bs, BlockReq *req) | ||
61 | g_free(req); | ||
62 | } | ||
63 | |||
64 | -static coroutine_fn int | ||
65 | +static int coroutine_fn GRAPH_RDLOCK | ||
66 | cbw_co_preadv_snapshot(BlockDriverState *bs, int64_t offset, int64_t bytes, | ||
67 | QEMUIOVector *qiov, size_t qiov_offset) | ||
68 | { | ||
69 | @@ -XXX,XX +XXX,XX @@ cbw_co_preadv_snapshot(BlockDriverState *bs, int64_t offset, int64_t bytes, | ||
70 | BdrvChild *file; | ||
71 | int ret; | ||
72 | |||
73 | - assume_graph_lock(); /* FIXME */ | ||
74 | - | ||
75 | /* TODO: upgrade to async loop using AioTask */ | ||
76 | while (bytes) { | ||
77 | int64_t cur_bytes; | ||
78 | @@ -XXX,XX +XXX,XX @@ cbw_co_preadv_snapshot(BlockDriverState *bs, int64_t offset, int64_t bytes, | ||
79 | return 0; | ||
80 | } | ||
81 | |||
82 | -static int coroutine_fn | ||
83 | +static int coroutine_fn GRAPH_RDLOCK | ||
84 | cbw_co_snapshot_block_status(BlockDriverState *bs, | ||
85 | bool want_zero, int64_t offset, int64_t bytes, | ||
86 | int64_t *pnum, int64_t *map, | ||
87 | diff --git a/block/io.c b/block/io.c | ||
88 | index XXXXXXX..XXXXXXX 100644 | ||
89 | --- a/block/io.c | ||
90 | +++ b/block/io.c | ||
91 | @@ -XXX,XX +XXX,XX @@ bdrv_co_preadv_snapshot(BdrvChild *child, int64_t offset, int64_t bytes, | ||
92 | BlockDriver *drv = bs->drv; | ||
93 | int ret; | ||
94 | IO_CODE(); | ||
95 | + assert_bdrv_graph_readable(); | ||
96 | |||
97 | if (!drv) { | ||
98 | return -ENOMEDIUM; | ||
99 | @@ -XXX,XX +XXX,XX @@ bdrv_co_snapshot_block_status(BlockDriverState *bs, | ||
100 | BlockDriver *drv = bs->drv; | ||
101 | int ret; | ||
102 | IO_CODE(); | ||
103 | + assert_bdrv_graph_readable(); | ||
104 | |||
105 | if (!drv) { | ||
106 | return -ENOMEDIUM; | ||
107 | diff --git a/block/snapshot-access.c b/block/snapshot-access.c | ||
108 | index XXXXXXX..XXXXXXX 100644 | ||
109 | --- a/block/snapshot-access.c | ||
110 | +++ b/block/snapshot-access.c | ||
111 | @@ -XXX,XX +XXX,XX @@ | ||
112 | #include "qemu/cutils.h" | ||
113 | #include "block/block_int.h" | ||
114 | |||
115 | -static coroutine_fn int | ||
116 | +static int coroutine_fn GRAPH_RDLOCK | ||
117 | snapshot_access_co_preadv_part(BlockDriverState *bs, | ||
118 | int64_t offset, int64_t bytes, | ||
119 | QEMUIOVector *qiov, size_t qiov_offset, | ||
120 | @@ -XXX,XX +XXX,XX @@ snapshot_access_co_preadv_part(BlockDriverState *bs, | ||
121 | return bdrv_co_preadv_snapshot(bs->file, offset, bytes, qiov, qiov_offset); | ||
122 | } | ||
123 | |||
124 | -static int coroutine_fn | ||
125 | +static int coroutine_fn GRAPH_RDLOCK | ||
126 | snapshot_access_co_block_status(BlockDriverState *bs, | ||
127 | bool want_zero, int64_t offset, | ||
128 | int64_t bytes, int64_t *pnum, | ||
129 | -- | ||
130 | 2.39.2 | diff view generated by jsdifflib |
Deleted patch | |||
---|---|---|---|
1 | This adds GRAPH_RDLOCK annotations to declare that callers of | ||
2 | bdrv_co_create() need to hold a reader lock for the graph. | ||
3 | 1 | ||
4 | Signed-off-by: Emanuele Giuseppe Esposito <eesposit@redhat.com> | ||
5 | Signed-off-by: Kevin Wolf <kwolf@redhat.com> | ||
6 | Message-Id: <20230203152202.49054-17-kwolf@redhat.com> | ||
7 | Reviewed-by: Emanuele Giuseppe Esposito <eesposit@redhat.com> | ||
8 | Signed-off-by: Kevin Wolf <kwolf@redhat.com> | ||
9 | --- | ||
10 | include/block/block-global-state.h | 14 ++++--- | ||
11 | include/block/block_int-common.h | 11 +++--- | ||
12 | block.c | 1 + | ||
13 | block/create.c | 9 ++++- | ||
14 | block/crypto.c | 7 ++-- | ||
15 | block/file-posix.c | 7 ++-- | ||
16 | block/file-win32.c | 7 ++-- | ||
17 | block/parallels.c | 7 ++-- | ||
18 | block/qcow.c | 6 +-- | ||
19 | block/qcow2.c | 7 ++-- | ||
20 | block/qed.c | 7 ++-- | ||
21 | block/raw-format.c | 7 ++-- | ||
22 | block/vdi.c | 7 ++-- | ||
23 | block/vhdx.c | 7 ++-- | ||
24 | block/vmdk.c | 63 ++++++++++++++---------------- | ||
25 | block/vpc.c | 7 ++-- | ||
26 | 16 files changed, 84 insertions(+), 90 deletions(-) | ||
27 | |||
28 | diff --git a/include/block/block-global-state.h b/include/block/block-global-state.h | ||
29 | index XXXXXXX..XXXXXXX 100644 | ||
30 | --- a/include/block/block-global-state.h | ||
31 | +++ b/include/block/block-global-state.h | ||
32 | @@ -XXX,XX +XXX,XX @@ BlockDriver *bdrv_find_protocol(const char *filename, | ||
33 | Error **errp); | ||
34 | BlockDriver *bdrv_find_format(const char *format_name); | ||
35 | |||
36 | -int coroutine_fn bdrv_co_create(BlockDriver *drv, const char *filename, | ||
37 | - QemuOpts *opts, Error **errp); | ||
38 | -int co_wrapper bdrv_create(BlockDriver *drv, const char *filename, | ||
39 | - QemuOpts *opts, Error **errp); | ||
40 | +int coroutine_fn GRAPH_RDLOCK | ||
41 | +bdrv_co_create(BlockDriver *drv, const char *filename, QemuOpts *opts, | ||
42 | + Error **errp); | ||
43 | |||
44 | -int coroutine_fn bdrv_co_create_file(const char *filename, QemuOpts *opts, | ||
45 | - Error **errp); | ||
46 | +int co_wrapper_bdrv_rdlock bdrv_create(BlockDriver *drv, const char *filename, | ||
47 | + QemuOpts *opts, Error **errp); | ||
48 | + | ||
49 | +int coroutine_fn GRAPH_RDLOCK | ||
50 | +bdrv_co_create_file(const char *filename, QemuOpts *opts, Error **errp); | ||
51 | |||
52 | BlockDriverState *bdrv_new(void); | ||
53 | int bdrv_append(BlockDriverState *bs_new, BlockDriverState *bs_top, | ||
54 | diff --git a/include/block/block_int-common.h b/include/block/block_int-common.h | ||
55 | index XXXXXXX..XXXXXXX 100644 | ||
56 | --- a/include/block/block_int-common.h | ||
57 | +++ b/include/block/block_int-common.h | ||
58 | @@ -XXX,XX +XXX,XX @@ struct BlockDriver { | ||
59 | Error **errp); | ||
60 | void (*bdrv_close)(BlockDriverState *bs); | ||
61 | |||
62 | - int coroutine_fn (*bdrv_co_create)(BlockdevCreateOptions *opts, | ||
63 | - Error **errp); | ||
64 | - int coroutine_fn (*bdrv_co_create_opts)(BlockDriver *drv, | ||
65 | - const char *filename, | ||
66 | - QemuOpts *opts, | ||
67 | - Error **errp); | ||
68 | + int coroutine_fn GRAPH_RDLOCK_PTR (*bdrv_co_create)( | ||
69 | + BlockdevCreateOptions *opts, Error **errp); | ||
70 | + | ||
71 | + int coroutine_fn GRAPH_RDLOCK_PTR (*bdrv_co_create_opts)( | ||
72 | + BlockDriver *drv, const char *filename, QemuOpts *opts, Error **errp); | ||
73 | |||
74 | int (*bdrv_amend_options)(BlockDriverState *bs, | ||
75 | QemuOpts *opts, | ||
76 | diff --git a/block.c b/block.c | ||
77 | index XXXXXXX..XXXXXXX 100644 | ||
78 | --- a/block.c | ||
79 | +++ b/block.c | ||
80 | @@ -XXX,XX +XXX,XX @@ int coroutine_fn bdrv_co_create(BlockDriver *drv, const char *filename, | ||
81 | int ret; | ||
82 | GLOBAL_STATE_CODE(); | ||
83 | ERRP_GUARD(); | ||
84 | + assert_bdrv_graph_readable(); | ||
85 | |||
86 | if (!drv->bdrv_co_create_opts) { | ||
87 | error_setg(errp, "Driver '%s' does not support image creation", | ||
88 | diff --git a/block/create.c b/block/create.c | ||
89 | index XXXXXXX..XXXXXXX 100644 | ||
90 | --- a/block/create.c | ||
91 | +++ b/block/create.c | ||
92 | @@ -XXX,XX +XXX,XX @@ static int coroutine_fn blockdev_create_run(Job *job, Error **errp) | ||
93 | int ret; | ||
94 | |||
95 | GLOBAL_STATE_CODE(); | ||
96 | + GRAPH_RDLOCK_GUARD(); | ||
97 | |||
98 | job_progress_set_remaining(&s->common, 1); | ||
99 | ret = s->drv->bdrv_co_create(s->opts, errp); | ||
100 | @@ -XXX,XX +XXX,XX @@ static const JobDriver blockdev_create_job_driver = { | ||
101 | .run = blockdev_create_run, | ||
102 | }; | ||
103 | |||
104 | +/* Checking whether the function is present doesn't require the graph lock */ | ||
105 | +static inline bool TSA_NO_TSA has_bdrv_co_create(BlockDriver *drv) | ||
106 | +{ | ||
107 | + return drv->bdrv_co_create; | ||
108 | +} | ||
109 | + | ||
110 | void qmp_blockdev_create(const char *job_id, BlockdevCreateOptions *options, | ||
111 | Error **errp) | ||
112 | { | ||
113 | @@ -XXX,XX +XXX,XX @@ void qmp_blockdev_create(const char *job_id, BlockdevCreateOptions *options, | ||
114 | } | ||
115 | |||
116 | /* Error out if the driver doesn't support .bdrv_co_create */ | ||
117 | - if (!drv->bdrv_co_create) { | ||
118 | + if (!has_bdrv_co_create(drv)) { | ||
119 | error_setg(errp, "Driver does not support blockdev-create"); | ||
120 | return; | ||
121 | } | ||
122 | diff --git a/block/crypto.c b/block/crypto.c | ||
123 | index XXXXXXX..XXXXXXX 100644 | ||
124 | --- a/block/crypto.c | ||
125 | +++ b/block/crypto.c | ||
126 | @@ -XXX,XX +XXX,XX @@ fail: | ||
127 | return ret; | ||
128 | } | ||
129 | |||
130 | -static int coroutine_fn block_crypto_co_create_opts_luks(BlockDriver *drv, | ||
131 | - const char *filename, | ||
132 | - QemuOpts *opts, | ||
133 | - Error **errp) | ||
134 | +static int coroutine_fn GRAPH_RDLOCK | ||
135 | +block_crypto_co_create_opts_luks(BlockDriver *drv, const char *filename, | ||
136 | + QemuOpts *opts, Error **errp) | ||
137 | { | ||
138 | QCryptoBlockCreateOptions *create_opts = NULL; | ||
139 | BlockDriverState *bs = NULL; | ||
140 | diff --git a/block/file-posix.c b/block/file-posix.c | ||
141 | index XXXXXXX..XXXXXXX 100644 | ||
142 | --- a/block/file-posix.c | ||
143 | +++ b/block/file-posix.c | ||
144 | @@ -XXX,XX +XXX,XX @@ out: | ||
145 | return result; | ||
146 | } | ||
147 | |||
148 | -static int coroutine_fn raw_co_create_opts(BlockDriver *drv, | ||
149 | - const char *filename, | ||
150 | - QemuOpts *opts, | ||
151 | - Error **errp) | ||
152 | +static int coroutine_fn GRAPH_RDLOCK | ||
153 | +raw_co_create_opts(BlockDriver *drv, const char *filename, | ||
154 | + QemuOpts *opts, Error **errp) | ||
155 | { | ||
156 | BlockdevCreateOptions options; | ||
157 | int64_t total_size = 0; | ||
158 | diff --git a/block/file-win32.c b/block/file-win32.c | ||
159 | index XXXXXXX..XXXXXXX 100644 | ||
160 | --- a/block/file-win32.c | ||
161 | +++ b/block/file-win32.c | ||
162 | @@ -XXX,XX +XXX,XX @@ static int raw_co_create(BlockdevCreateOptions *options, Error **errp) | ||
163 | return 0; | ||
164 | } | ||
165 | |||
166 | -static int coroutine_fn raw_co_create_opts(BlockDriver *drv, | ||
167 | - const char *filename, | ||
168 | - QemuOpts *opts, | ||
169 | - Error **errp) | ||
170 | +static int coroutine_fn GRAPH_RDLOCK | ||
171 | +raw_co_create_opts(BlockDriver *drv, const char *filename, | ||
172 | + QemuOpts *opts, Error **errp) | ||
173 | { | ||
174 | BlockdevCreateOptions options; | ||
175 | int64_t total_size = 0; | ||
176 | diff --git a/block/parallels.c b/block/parallels.c | ||
177 | index XXXXXXX..XXXXXXX 100644 | ||
178 | --- a/block/parallels.c | ||
179 | +++ b/block/parallels.c | ||
180 | @@ -XXX,XX +XXX,XX @@ exit: | ||
181 | goto out; | ||
182 | } | ||
183 | |||
184 | -static int coroutine_fn parallels_co_create_opts(BlockDriver *drv, | ||
185 | - const char *filename, | ||
186 | - QemuOpts *opts, | ||
187 | - Error **errp) | ||
188 | +static int coroutine_fn GRAPH_RDLOCK | ||
189 | +parallels_co_create_opts(BlockDriver *drv, const char *filename, | ||
190 | + QemuOpts *opts, Error **errp) | ||
191 | { | ||
192 | BlockdevCreateOptions *create_options = NULL; | ||
193 | BlockDriverState *bs = NULL; | ||
194 | diff --git a/block/qcow.c b/block/qcow.c | ||
195 | index XXXXXXX..XXXXXXX 100644 | ||
196 | --- a/block/qcow.c | ||
197 | +++ b/block/qcow.c | ||
198 | @@ -XXX,XX +XXX,XX @@ exit: | ||
199 | return ret; | ||
200 | } | ||
201 | |||
202 | -static int coroutine_fn qcow_co_create_opts(BlockDriver *drv, | ||
203 | - const char *filename, | ||
204 | - QemuOpts *opts, Error **errp) | ||
205 | +static int coroutine_fn GRAPH_RDLOCK | ||
206 | +qcow_co_create_opts(BlockDriver *drv, const char *filename, | ||
207 | + QemuOpts *opts, Error **errp) | ||
208 | { | ||
209 | BlockdevCreateOptions *create_options = NULL; | ||
210 | BlockDriverState *bs = NULL; | ||
211 | diff --git a/block/qcow2.c b/block/qcow2.c | ||
212 | index XXXXXXX..XXXXXXX 100644 | ||
213 | --- a/block/qcow2.c | ||
214 | +++ b/block/qcow2.c | ||
215 | @@ -XXX,XX +XXX,XX @@ out: | ||
216 | return ret; | ||
217 | } | ||
218 | |||
219 | -static int coroutine_fn qcow2_co_create_opts(BlockDriver *drv, | ||
220 | - const char *filename, | ||
221 | - QemuOpts *opts, | ||
222 | - Error **errp) | ||
223 | +static int coroutine_fn GRAPH_RDLOCK | ||
224 | +qcow2_co_create_opts(BlockDriver *drv, const char *filename, QemuOpts *opts, | ||
225 | + Error **errp) | ||
226 | { | ||
227 | BlockdevCreateOptions *create_options = NULL; | ||
228 | QDict *qdict; | ||
229 | diff --git a/block/qed.c b/block/qed.c | ||
230 | index XXXXXXX..XXXXXXX 100644 | ||
231 | --- a/block/qed.c | ||
232 | +++ b/block/qed.c | ||
233 | @@ -XXX,XX +XXX,XX @@ out: | ||
234 | return ret; | ||
235 | } | ||
236 | |||
237 | -static int coroutine_fn bdrv_qed_co_create_opts(BlockDriver *drv, | ||
238 | - const char *filename, | ||
239 | - QemuOpts *opts, | ||
240 | - Error **errp) | ||
241 | +static int coroutine_fn GRAPH_RDLOCK | ||
242 | +bdrv_qed_co_create_opts(BlockDriver *drv, const char *filename, | ||
243 | + QemuOpts *opts, Error **errp) | ||
244 | { | ||
245 | BlockdevCreateOptions *create_options = NULL; | ||
246 | QDict *qdict; | ||
247 | diff --git a/block/raw-format.c b/block/raw-format.c | ||
248 | index XXXXXXX..XXXXXXX 100644 | ||
249 | --- a/block/raw-format.c | ||
250 | +++ b/block/raw-format.c | ||
251 | @@ -XXX,XX +XXX,XX @@ static int raw_has_zero_init(BlockDriverState *bs) | ||
252 | return bdrv_has_zero_init(bs->file->bs); | ||
253 | } | ||
254 | |||
255 | -static int coroutine_fn raw_co_create_opts(BlockDriver *drv, | ||
256 | - const char *filename, | ||
257 | - QemuOpts *opts, | ||
258 | - Error **errp) | ||
259 | +static int coroutine_fn GRAPH_RDLOCK | ||
260 | +raw_co_create_opts(BlockDriver *drv, const char *filename, | ||
261 | + QemuOpts *opts, Error **errp) | ||
262 | { | ||
263 | return bdrv_co_create_file(filename, opts, errp); | ||
264 | } | ||
265 | diff --git a/block/vdi.c b/block/vdi.c | ||
266 | index XXXXXXX..XXXXXXX 100644 | ||
267 | --- a/block/vdi.c | ||
268 | +++ b/block/vdi.c | ||
269 | @@ -XXX,XX +XXX,XX @@ static int coroutine_fn vdi_co_create(BlockdevCreateOptions *create_options, | ||
270 | return vdi_co_do_create(create_options, DEFAULT_CLUSTER_SIZE, errp); | ||
271 | } | ||
272 | |||
273 | -static int coroutine_fn vdi_co_create_opts(BlockDriver *drv, | ||
274 | - const char *filename, | ||
275 | - QemuOpts *opts, | ||
276 | - Error **errp) | ||
277 | +static int coroutine_fn GRAPH_RDLOCK | ||
278 | +vdi_co_create_opts(BlockDriver *drv, const char *filename, | ||
279 | + QemuOpts *opts, Error **errp) | ||
280 | { | ||
281 | QDict *qdict = NULL; | ||
282 | BlockdevCreateOptions *create_options = NULL; | ||
283 | diff --git a/block/vhdx.c b/block/vhdx.c | ||
284 | index XXXXXXX..XXXXXXX 100644 | ||
285 | --- a/block/vhdx.c | ||
286 | +++ b/block/vhdx.c | ||
287 | @@ -XXX,XX +XXX,XX @@ delete_and_exit: | ||
288 | return ret; | ||
289 | } | ||
290 | |||
291 | -static int coroutine_fn vhdx_co_create_opts(BlockDriver *drv, | ||
292 | - const char *filename, | ||
293 | - QemuOpts *opts, | ||
294 | - Error **errp) | ||
295 | +static int coroutine_fn GRAPH_RDLOCK | ||
296 | +vhdx_co_create_opts(BlockDriver *drv, const char *filename, | ||
297 | + QemuOpts *opts, Error **errp) | ||
298 | { | ||
299 | BlockdevCreateOptions *create_options = NULL; | ||
300 | QDict *qdict; | ||
301 | diff --git a/block/vmdk.c b/block/vmdk.c | ||
302 | index XXXXXXX..XXXXXXX 100644 | ||
303 | --- a/block/vmdk.c | ||
304 | +++ b/block/vmdk.c | ||
305 | @@ -XXX,XX +XXX,XX @@ exit: | ||
306 | return ret; | ||
307 | } | ||
308 | |||
309 | -static int coroutine_fn vmdk_create_extent(const char *filename, | ||
310 | - int64_t filesize, bool flat, | ||
311 | - bool compress, bool zeroed_grain, | ||
312 | - BlockBackend **pbb, | ||
313 | - QemuOpts *opts, Error **errp) | ||
314 | +static int coroutine_fn GRAPH_RDLOCK | ||
315 | +vmdk_create_extent(const char *filename, int64_t filesize, bool flat, | ||
316 | + bool compress, bool zeroed_grain, BlockBackend **pbb, | ||
317 | + QemuOpts *opts, Error **errp) | ||
318 | { | ||
319 | int ret; | ||
320 | BlockBackend *blk = NULL; | ||
321 | @@ -XXX,XX +XXX,XX @@ static int filename_decompose(const char *filename, char *path, char *prefix, | ||
322 | * non-split format. | ||
323 | * idx >= 1: get the n-th extent if in a split subformat | ||
324 | */ | ||
325 | -typedef BlockBackend * coroutine_fn (*vmdk_create_extent_fn)(int64_t size, | ||
326 | - int idx, | ||
327 | - bool flat, | ||
328 | - bool split, | ||
329 | - bool compress, | ||
330 | - bool zeroed_grain, | ||
331 | - void *opaque, | ||
332 | - Error **errp); | ||
333 | +typedef BlockBackend * coroutine_fn /* GRAPH_RDLOCK */ | ||
334 | + (*vmdk_create_extent_fn)(int64_t size, int idx, bool flat, bool split, | ||
335 | + bool compress, bool zeroed_grain, void *opaque, | ||
336 | + Error **errp); | ||
337 | |||
338 | static void vmdk_desc_add_extent(GString *desc, | ||
339 | const char *extent_line_fmt, | ||
340 | @@ -XXX,XX +XXX,XX @@ static void vmdk_desc_add_extent(GString *desc, | ||
341 | g_free(basename); | ||
342 | } | ||
343 | |||
344 | -static int coroutine_fn vmdk_co_do_create(int64_t size, | ||
345 | - BlockdevVmdkSubformat subformat, | ||
346 | - BlockdevVmdkAdapterType adapter_type, | ||
347 | - const char *backing_file, | ||
348 | - const char *hw_version, | ||
349 | - const char *toolsversion, | ||
350 | - bool compat6, | ||
351 | - bool zeroed_grain, | ||
352 | - vmdk_create_extent_fn extent_fn, | ||
353 | - void *opaque, | ||
354 | - Error **errp) | ||
355 | +static int coroutine_fn GRAPH_RDLOCK | ||
356 | +vmdk_co_do_create(int64_t size, | ||
357 | + BlockdevVmdkSubformat subformat, | ||
358 | + BlockdevVmdkAdapterType adapter_type, | ||
359 | + const char *backing_file, | ||
360 | + const char *hw_version, | ||
361 | + const char *toolsversion, | ||
362 | + bool compat6, | ||
363 | + bool zeroed_grain, | ||
364 | + vmdk_create_extent_fn extent_fn, | ||
365 | + void *opaque, | ||
366 | + Error **errp) | ||
367 | { | ||
368 | int extent_idx; | ||
369 | BlockBackend *blk = NULL; | ||
370 | @@ -XXX,XX +XXX,XX @@ typedef struct { | ||
371 | QemuOpts *opts; | ||
372 | } VMDKCreateOptsData; | ||
373 | |||
374 | -static BlockBackend * coroutine_fn vmdk_co_create_opts_cb(int64_t size, int idx, | ||
375 | - bool flat, bool split, bool compress, | ||
376 | - bool zeroed_grain, void *opaque, | ||
377 | - Error **errp) | ||
378 | +static BlockBackend * coroutine_fn GRAPH_RDLOCK | ||
379 | +vmdk_co_create_opts_cb(int64_t size, int idx, bool flat, bool split, | ||
380 | + bool compress, bool zeroed_grain, void *opaque, | ||
381 | + Error **errp) | ||
382 | { | ||
383 | BlockBackend *blk = NULL; | ||
384 | BlockDriverState *bs = NULL; | ||
385 | @@ -XXX,XX +XXX,XX @@ exit: | ||
386 | return blk; | ||
387 | } | ||
388 | |||
389 | -static int coroutine_fn vmdk_co_create_opts(BlockDriver *drv, | ||
390 | - const char *filename, | ||
391 | - QemuOpts *opts, | ||
392 | - Error **errp) | ||
393 | +static int coroutine_fn GRAPH_RDLOCK | ||
394 | +vmdk_co_create_opts(BlockDriver *drv, const char *filename, | ||
395 | + QemuOpts *opts, Error **errp) | ||
396 | { | ||
397 | Error *local_err = NULL; | ||
398 | char *desc = NULL; | ||
399 | @@ -XXX,XX +XXX,XX @@ static BlockBackend * coroutine_fn vmdk_co_create_cb(int64_t size, int idx, | ||
400 | return blk; | ||
401 | } | ||
402 | |||
403 | -static int coroutine_fn vmdk_co_create(BlockdevCreateOptions *create_options, | ||
404 | - Error **errp) | ||
405 | +static int coroutine_fn GRAPH_RDLOCK | ||
406 | +vmdk_co_create(BlockdevCreateOptions *create_options, Error **errp) | ||
407 | { | ||
408 | BlockdevCreateOptionsVmdk *opts; | ||
409 | |||
410 | diff --git a/block/vpc.c b/block/vpc.c | ||
411 | index XXXXXXX..XXXXXXX 100644 | ||
412 | --- a/block/vpc.c | ||
413 | +++ b/block/vpc.c | ||
414 | @@ -XXX,XX +XXX,XX @@ out: | ||
415 | return ret; | ||
416 | } | ||
417 | |||
418 | -static int coroutine_fn vpc_co_create_opts(BlockDriver *drv, | ||
419 | - const char *filename, | ||
420 | - QemuOpts *opts, | ||
421 | - Error **errp) | ||
422 | +static int coroutine_fn GRAPH_RDLOCK | ||
423 | +vpc_co_create_opts(BlockDriver *drv, const char *filename, | ||
424 | + QemuOpts *opts, Error **errp) | ||
425 | { | ||
426 | BlockdevCreateOptions *create_options = NULL; | ||
427 | QDict *qdict; | ||
428 | -- | ||
429 | 2.39.2 | diff view generated by jsdifflib |
Deleted patch | |||
---|---|---|---|
1 | This adds GRAPH_RDLOCK annotations to declare that callers of | ||
2 | bdrv_co_io_plug() and bdrv_co_io_unplug() need to hold a reader lock for | ||
3 | the graph. | ||
4 | 1 | ||
5 | Signed-off-by: Kevin Wolf <kwolf@redhat.com> | ||
6 | Message-Id: <20230203152202.49054-18-kwolf@redhat.com> | ||
7 | Reviewed-by: Emanuele Giuseppe Esposito <eesposit@redhat.com> | ||
8 | Signed-off-by: Kevin Wolf <kwolf@redhat.com> | ||
9 | --- | ||
10 | include/block/block-io.h | 4 ++-- | ||
11 | include/block/block_int-common.h | 5 +++-- | ||
12 | block/block-backend.c | 2 ++ | ||
13 | block/io.c | 2 ++ | ||
14 | 4 files changed, 9 insertions(+), 4 deletions(-) | ||
15 | |||
16 | diff --git a/include/block/block-io.h b/include/block/block-io.h | ||
17 | index XXXXXXX..XXXXXXX 100644 | ||
18 | --- a/include/block/block-io.h | ||
19 | +++ b/include/block/block-io.h | ||
20 | @@ -XXX,XX +XXX,XX @@ void coroutine_fn bdrv_co_leave(BlockDriverState *bs, AioContext *old_ctx); | ||
21 | |||
22 | AioContext *child_of_bds_get_parent_aio_context(BdrvChild *c); | ||
23 | |||
24 | -void coroutine_fn bdrv_co_io_plug(BlockDriverState *bs); | ||
25 | -void coroutine_fn bdrv_co_io_unplug(BlockDriverState *bs); | ||
26 | +void coroutine_fn GRAPH_RDLOCK bdrv_co_io_plug(BlockDriverState *bs); | ||
27 | +void coroutine_fn GRAPH_RDLOCK bdrv_co_io_unplug(BlockDriverState *bs); | ||
28 | |||
29 | bool coroutine_fn bdrv_co_can_store_new_dirty_bitmap(BlockDriverState *bs, | ||
30 | const char *name, | ||
31 | diff --git a/include/block/block_int-common.h b/include/block/block_int-common.h | ||
32 | index XXXXXXX..XXXXXXX 100644 | ||
33 | --- a/include/block/block_int-common.h | ||
34 | +++ b/include/block/block_int-common.h | ||
35 | @@ -XXX,XX +XXX,XX @@ struct BlockDriver { | ||
36 | BlkdebugEvent event); | ||
37 | |||
38 | /* io queue for linux-aio */ | ||
39 | - void coroutine_fn (*bdrv_co_io_plug)(BlockDriverState *bs); | ||
40 | - void coroutine_fn (*bdrv_co_io_unplug)(BlockDriverState *bs); | ||
41 | + void coroutine_fn GRAPH_RDLOCK_PTR (*bdrv_co_io_plug)(BlockDriverState *bs); | ||
42 | + void coroutine_fn GRAPH_RDLOCK_PTR (*bdrv_co_io_unplug)( | ||
43 | + BlockDriverState *bs); | ||
44 | |||
45 | /** | ||
46 | * bdrv_drain_begin is called if implemented in the beginning of a | ||
47 | diff --git a/block/block-backend.c b/block/block-backend.c | ||
48 | index XXXXXXX..XXXXXXX 100644 | ||
49 | --- a/block/block-backend.c | ||
50 | +++ b/block/block-backend.c | ||
51 | @@ -XXX,XX +XXX,XX @@ void coroutine_fn blk_co_io_plug(BlockBackend *blk) | ||
52 | { | ||
53 | BlockDriverState *bs = blk_bs(blk); | ||
54 | IO_CODE(); | ||
55 | + GRAPH_RDLOCK_GUARD(); | ||
56 | |||
57 | if (bs) { | ||
58 | bdrv_co_io_plug(bs); | ||
59 | @@ -XXX,XX +XXX,XX @@ void coroutine_fn blk_co_io_unplug(BlockBackend *blk) | ||
60 | { | ||
61 | BlockDriverState *bs = blk_bs(blk); | ||
62 | IO_CODE(); | ||
63 | + GRAPH_RDLOCK_GUARD(); | ||
64 | |||
65 | if (bs) { | ||
66 | bdrv_co_io_unplug(bs); | ||
67 | diff --git a/block/io.c b/block/io.c | ||
68 | index XXXXXXX..XXXXXXX 100644 | ||
69 | --- a/block/io.c | ||
70 | +++ b/block/io.c | ||
71 | @@ -XXX,XX +XXX,XX @@ void coroutine_fn bdrv_co_io_plug(BlockDriverState *bs) | ||
72 | { | ||
73 | BdrvChild *child; | ||
74 | IO_CODE(); | ||
75 | + assert_bdrv_graph_readable(); | ||
76 | |||
77 | QLIST_FOREACH(child, &bs->children, next) { | ||
78 | bdrv_co_io_plug(child->bs); | ||
79 | @@ -XXX,XX +XXX,XX @@ void coroutine_fn bdrv_co_io_unplug(BlockDriverState *bs) | ||
80 | { | ||
81 | BdrvChild *child; | ||
82 | IO_CODE(); | ||
83 | + assert_bdrv_graph_readable(); | ||
84 | |||
85 | assert(bs->io_plugged); | ||
86 | if (qatomic_fetch_dec(&bs->io_plugged) == 1) { | ||
87 | -- | ||
88 | 2.39.2 | diff view generated by jsdifflib |
Deleted patch | |||
---|---|---|---|
1 | From: Emanuele Giuseppe Esposito <eesposit@redhat.com> | ||
2 | 1 | ||
3 | This adds GRAPH_RDLOCK annotations to declare that callers of | ||
4 | bdrv_co_is_inserted() need to hold a reader lock for the graph. | ||
5 | |||
6 | blk_is_inserted() is done as a co_wrapper_mixed_bdrv_rdlock (unlike most | ||
7 | other blk_* functions) because it is called a lot from other blk_co_*() | ||
8 | functions that already hold the lock. These calls go through | ||
9 | blk_is_available(), which becomes a co_wrapper_mixed_bdrv_rdlock, too, | ||
10 | for the same reason. | ||
11 | |||
12 | Functions that run in a coroutine and can call bdrv_co_is_available() | ||
13 | directly are changed to do so, which results in better TSA coverage. | ||
14 | |||
15 | Signed-off-by: Emanuele Giuseppe Esposito <eesposit@redhat.com> | ||
16 | Signed-off-by: Kevin Wolf <kwolf@redhat.com> | ||
17 | Message-Id: <20230203152202.49054-19-kwolf@redhat.com> | ||
18 | Reviewed-by: Emanuele Giuseppe Esposito <eesposit@redhat.com> | ||
19 | Signed-off-by: Kevin Wolf <kwolf@redhat.com> | ||
20 | --- | ||
21 | include/block/block-io.h | 4 ++-- | ||
22 | include/block/block_int-common.h | 3 ++- | ||
23 | include/sysemu/block-backend-io.h | 7 ++++--- | ||
24 | block.c | 1 + | ||
25 | block/block-backend.c | 25 ++++++++++++++----------- | ||
26 | 5 files changed, 23 insertions(+), 17 deletions(-) | ||
27 | |||
28 | diff --git a/include/block/block-io.h b/include/block/block-io.h | ||
29 | index XXXXXXX..XXXXXXX 100644 | ||
30 | --- a/include/block/block-io.h | ||
31 | +++ b/include/block/block-io.h | ||
32 | @@ -XXX,XX +XXX,XX @@ bool bdrv_is_writable(BlockDriverState *bs); | ||
33 | bool bdrv_is_sg(BlockDriverState *bs); | ||
34 | int bdrv_get_flags(BlockDriverState *bs); | ||
35 | |||
36 | -bool coroutine_fn bdrv_co_is_inserted(BlockDriverState *bs); | ||
37 | -bool co_wrapper bdrv_is_inserted(BlockDriverState *bs); | ||
38 | +bool coroutine_fn GRAPH_RDLOCK bdrv_co_is_inserted(BlockDriverState *bs); | ||
39 | +bool co_wrapper_bdrv_rdlock bdrv_is_inserted(BlockDriverState *bs); | ||
40 | |||
41 | void coroutine_fn bdrv_co_lock_medium(BlockDriverState *bs, bool locked); | ||
42 | void coroutine_fn bdrv_co_eject(BlockDriverState *bs, bool eject_flag); | ||
43 | diff --git a/include/block/block_int-common.h b/include/block/block_int-common.h | ||
44 | index XXXXXXX..XXXXXXX 100644 | ||
45 | --- a/include/block/block_int-common.h | ||
46 | +++ b/include/block/block_int-common.h | ||
47 | @@ -XXX,XX +XXX,XX @@ struct BlockDriver { | ||
48 | BlockDriverState *bs, QEMUIOVector *qiov, int64_t pos); | ||
49 | |||
50 | /* removable device specific */ | ||
51 | - bool coroutine_fn (*bdrv_co_is_inserted)(BlockDriverState *bs); | ||
52 | + bool coroutine_fn GRAPH_RDLOCK_PTR (*bdrv_co_is_inserted)( | ||
53 | + BlockDriverState *bs); | ||
54 | void coroutine_fn (*bdrv_co_eject)(BlockDriverState *bs, bool eject_flag); | ||
55 | void coroutine_fn (*bdrv_co_lock_medium)(BlockDriverState *bs, bool locked); | ||
56 | |||
57 | diff --git a/include/sysemu/block-backend-io.h b/include/sysemu/block-backend-io.h | ||
58 | index XXXXXXX..XXXXXXX 100644 | ||
59 | --- a/include/sysemu/block-backend-io.h | ||
60 | +++ b/include/sysemu/block-backend-io.h | ||
61 | @@ -XXX,XX +XXX,XX @@ BlockAIOCB *blk_aio_ioctl(BlockBackend *blk, unsigned long int req, void *buf, | ||
62 | void blk_inc_in_flight(BlockBackend *blk); | ||
63 | void blk_dec_in_flight(BlockBackend *blk); | ||
64 | |||
65 | -bool coroutine_fn blk_co_is_inserted(BlockBackend *blk); | ||
66 | -bool co_wrapper_mixed blk_is_inserted(BlockBackend *blk); | ||
67 | +bool coroutine_fn GRAPH_RDLOCK blk_co_is_inserted(BlockBackend *blk); | ||
68 | +bool co_wrapper_mixed_bdrv_rdlock blk_is_inserted(BlockBackend *blk); | ||
69 | |||
70 | -bool blk_is_available(BlockBackend *blk); | ||
71 | +bool coroutine_fn GRAPH_RDLOCK blk_co_is_available(BlockBackend *blk); | ||
72 | +bool co_wrapper_mixed_bdrv_rdlock blk_is_available(BlockBackend *blk); | ||
73 | |||
74 | void coroutine_fn blk_co_lock_medium(BlockBackend *blk, bool locked); | ||
75 | void co_wrapper blk_lock_medium(BlockBackend *blk, bool locked); | ||
76 | diff --git a/block.c b/block.c | ||
77 | index XXXXXXX..XXXXXXX 100644 | ||
78 | --- a/block.c | ||
79 | +++ b/block.c | ||
80 | @@ -XXX,XX +XXX,XX @@ bool coroutine_fn bdrv_co_is_inserted(BlockDriverState *bs) | ||
81 | BlockDriver *drv = bs->drv; | ||
82 | BdrvChild *child; | ||
83 | IO_CODE(); | ||
84 | + assert_bdrv_graph_readable(); | ||
85 | |||
86 | if (!drv) { | ||
87 | return false; | ||
88 | diff --git a/block/block-backend.c b/block/block-backend.c | ||
89 | index XXXXXXX..XXXXXXX 100644 | ||
90 | --- a/block/block-backend.c | ||
91 | +++ b/block/block-backend.c | ||
92 | @@ -XXX,XX +XXX,XX @@ void blk_set_disable_request_queuing(BlockBackend *blk, bool disable) | ||
93 | blk->disable_request_queuing = disable; | ||
94 | } | ||
95 | |||
96 | -static coroutine_fn int blk_check_byte_request(BlockBackend *blk, | ||
97 | - int64_t offset, int64_t bytes) | ||
98 | +static int coroutine_fn GRAPH_RDLOCK | ||
99 | +blk_check_byte_request(BlockBackend *blk, int64_t offset, int64_t bytes) | ||
100 | { | ||
101 | int64_t len; | ||
102 | |||
103 | @@ -XXX,XX +XXX,XX @@ static coroutine_fn int blk_check_byte_request(BlockBackend *blk, | ||
104 | return -EIO; | ||
105 | } | ||
106 | |||
107 | - if (!blk_is_available(blk)) { | ||
108 | + if (!blk_co_is_available(blk)) { | ||
109 | return -ENOMEDIUM; | ||
110 | } | ||
111 | |||
112 | @@ -XXX,XX +XXX,XX @@ BlockAIOCB *blk_aio_pwrite_zeroes(BlockBackend *blk, int64_t offset, | ||
113 | int64_t coroutine_fn blk_co_getlength(BlockBackend *blk) | ||
114 | { | ||
115 | IO_CODE(); | ||
116 | + GRAPH_RDLOCK_GUARD(); | ||
117 | |||
118 | - if (!blk_is_available(blk)) { | ||
119 | + if (!blk_co_is_available(blk)) { | ||
120 | return -ENOMEDIUM; | ||
121 | } | ||
122 | |||
123 | @@ -XXX,XX +XXX,XX @@ void blk_get_geometry(BlockBackend *blk, uint64_t *nb_sectors_ptr) | ||
124 | int64_t coroutine_fn blk_co_nb_sectors(BlockBackend *blk) | ||
125 | { | ||
126 | IO_CODE(); | ||
127 | + GRAPH_RDLOCK_GUARD(); | ||
128 | |||
129 | - if (!blk_is_available(blk)) { | ||
130 | + if (!blk_co_is_available(blk)) { | ||
131 | return -ENOMEDIUM; | ||
132 | } | ||
133 | |||
134 | @@ -XXX,XX +XXX,XX @@ blk_co_do_ioctl(BlockBackend *blk, unsigned long int req, void *buf) | ||
135 | blk_wait_while_drained(blk); | ||
136 | GRAPH_RDLOCK_GUARD(); | ||
137 | |||
138 | - if (!blk_is_available(blk)) { | ||
139 | + if (!blk_co_is_available(blk)) { | ||
140 | return -ENOMEDIUM; | ||
141 | } | ||
142 | |||
143 | @@ -XXX,XX +XXX,XX @@ static int coroutine_fn blk_co_do_flush(BlockBackend *blk) | ||
144 | blk_wait_while_drained(blk); | ||
145 | GRAPH_RDLOCK_GUARD(); | ||
146 | |||
147 | - if (!blk_is_available(blk)) { | ||
148 | + if (!blk_co_is_available(blk)) { | ||
149 | return -ENOMEDIUM; | ||
150 | } | ||
151 | |||
152 | @@ -XXX,XX +XXX,XX @@ bool coroutine_fn blk_co_is_inserted(BlockBackend *blk) | ||
153 | { | ||
154 | BlockDriverState *bs = blk_bs(blk); | ||
155 | IO_CODE(); | ||
156 | + assert_bdrv_graph_readable(); | ||
157 | |||
158 | return bs && bdrv_co_is_inserted(bs); | ||
159 | } | ||
160 | |||
161 | -bool blk_is_available(BlockBackend *blk) | ||
162 | +bool coroutine_fn blk_co_is_available(BlockBackend *blk) | ||
163 | { | ||
164 | IO_CODE(); | ||
165 | - return blk_is_inserted(blk) && !blk_dev_is_tray_open(blk); | ||
166 | + return blk_co_is_inserted(blk) && !blk_dev_is_tray_open(blk); | ||
167 | } | ||
168 | |||
169 | void coroutine_fn blk_co_lock_medium(BlockBackend *blk, bool locked) | ||
170 | @@ -XXX,XX +XXX,XX @@ int coroutine_fn blk_co_truncate(BlockBackend *blk, int64_t offset, bool exact, | ||
171 | { | ||
172 | IO_OR_GS_CODE(); | ||
173 | GRAPH_RDLOCK_GUARD(); | ||
174 | - if (!blk_is_available(blk)) { | ||
175 | + if (!blk_co_is_available(blk)) { | ||
176 | error_setg(errp, "No medium inserted"); | ||
177 | return -ENOMEDIUM; | ||
178 | } | ||
179 | @@ -XXX,XX +XXX,XX @@ int coroutine_fn blk_co_copy_range(BlockBackend *blk_in, int64_t off_in, | ||
180 | { | ||
181 | int r; | ||
182 | IO_CODE(); | ||
183 | + GRAPH_RDLOCK_GUARD(); | ||
184 | |||
185 | r = blk_check_byte_request(blk_in, off_in, bytes); | ||
186 | if (r) { | ||
187 | @@ -XXX,XX +XXX,XX @@ int coroutine_fn blk_co_copy_range(BlockBackend *blk_in, int64_t off_in, | ||
188 | return r; | ||
189 | } | ||
190 | |||
191 | - GRAPH_RDLOCK_GUARD(); | ||
192 | return bdrv_co_copy_range(blk_in->root, off_in, | ||
193 | blk_out->root, off_out, | ||
194 | bytes, read_flags, write_flags); | ||
195 | -- | ||
196 | 2.39.2 | diff view generated by jsdifflib |
Deleted patch | |||
---|---|---|---|
1 | This adds GRAPH_RDLOCK annotations to declare that callers of | ||
2 | bdrv_co_eject() and bdrv_co_lock_medium() need to hold a reader lock for | ||
3 | the graph. | ||
4 | 1 | ||
5 | Signed-off-by: Emanuele Giuseppe Esposito <eesposit@redhat.com> | ||
6 | Signed-off-by: Kevin Wolf <kwolf@redhat.com> | ||
7 | Message-Id: <20230203152202.49054-20-kwolf@redhat.com> | ||
8 | Reviewed-by: Emanuele Giuseppe Esposito <eesposit@redhat.com> | ||
9 | Signed-off-by: Kevin Wolf <kwolf@redhat.com> | ||
10 | --- | ||
11 | include/block/block-io.h | 7 +++++-- | ||
12 | include/block/block_int-common.h | 6 ++++-- | ||
13 | block.c | 2 ++ | ||
14 | block/block-backend.c | 2 ++ | ||
15 | block/copy-on-read.c | 6 ++++-- | ||
16 | block/filter-compress.c | 4 ++-- | ||
17 | block/raw-format.c | 6 ++++-- | ||
18 | 7 files changed, 23 insertions(+), 10 deletions(-) | ||
19 | |||
20 | diff --git a/include/block/block-io.h b/include/block/block-io.h | ||
21 | index XXXXXXX..XXXXXXX 100644 | ||
22 | --- a/include/block/block-io.h | ||
23 | +++ b/include/block/block-io.h | ||
24 | @@ -XXX,XX +XXX,XX @@ int bdrv_get_flags(BlockDriverState *bs); | ||
25 | bool coroutine_fn GRAPH_RDLOCK bdrv_co_is_inserted(BlockDriverState *bs); | ||
26 | bool co_wrapper_bdrv_rdlock bdrv_is_inserted(BlockDriverState *bs); | ||
27 | |||
28 | -void coroutine_fn bdrv_co_lock_medium(BlockDriverState *bs, bool locked); | ||
29 | -void coroutine_fn bdrv_co_eject(BlockDriverState *bs, bool eject_flag); | ||
30 | +void coroutine_fn GRAPH_RDLOCK | ||
31 | +bdrv_co_lock_medium(BlockDriverState *bs, bool locked); | ||
32 | + | ||
33 | +void coroutine_fn GRAPH_RDLOCK | ||
34 | +bdrv_co_eject(BlockDriverState *bs, bool eject_flag); | ||
35 | |||
36 | const char *bdrv_get_format_name(BlockDriverState *bs); | ||
37 | |||
38 | diff --git a/include/block/block_int-common.h b/include/block/block_int-common.h | ||
39 | index XXXXXXX..XXXXXXX 100644 | ||
40 | --- a/include/block/block_int-common.h | ||
41 | +++ b/include/block/block_int-common.h | ||
42 | @@ -XXX,XX +XXX,XX @@ struct BlockDriver { | ||
43 | /* removable device specific */ | ||
44 | bool coroutine_fn GRAPH_RDLOCK_PTR (*bdrv_co_is_inserted)( | ||
45 | BlockDriverState *bs); | ||
46 | - void coroutine_fn (*bdrv_co_eject)(BlockDriverState *bs, bool eject_flag); | ||
47 | - void coroutine_fn (*bdrv_co_lock_medium)(BlockDriverState *bs, bool locked); | ||
48 | + void coroutine_fn GRAPH_RDLOCK_PTR (*bdrv_co_eject)( | ||
49 | + BlockDriverState *bs, bool eject_flag); | ||
50 | + void coroutine_fn GRAPH_RDLOCK_PTR (*bdrv_co_lock_medium)( | ||
51 | + BlockDriverState *bs, bool locked); | ||
52 | |||
53 | /* to control generic scsi devices */ | ||
54 | BlockAIOCB *coroutine_fn GRAPH_RDLOCK_PTR (*bdrv_aio_ioctl)( | ||
55 | diff --git a/block.c b/block.c | ||
56 | index XXXXXXX..XXXXXXX 100644 | ||
57 | --- a/block.c | ||
58 | +++ b/block.c | ||
59 | @@ -XXX,XX +XXX,XX @@ void coroutine_fn bdrv_co_eject(BlockDriverState *bs, bool eject_flag) | ||
60 | { | ||
61 | BlockDriver *drv = bs->drv; | ||
62 | IO_CODE(); | ||
63 | + assert_bdrv_graph_readable(); | ||
64 | |||
65 | if (drv && drv->bdrv_co_eject) { | ||
66 | drv->bdrv_co_eject(bs, eject_flag); | ||
67 | @@ -XXX,XX +XXX,XX @@ void coroutine_fn bdrv_co_lock_medium(BlockDriverState *bs, bool locked) | ||
68 | { | ||
69 | BlockDriver *drv = bs->drv; | ||
70 | IO_CODE(); | ||
71 | + assert_bdrv_graph_readable(); | ||
72 | trace_bdrv_lock_medium(bs, locked); | ||
73 | |||
74 | if (drv && drv->bdrv_co_lock_medium) { | ||
75 | diff --git a/block/block-backend.c b/block/block-backend.c | ||
76 | index XXXXXXX..XXXXXXX 100644 | ||
77 | --- a/block/block-backend.c | ||
78 | +++ b/block/block-backend.c | ||
79 | @@ -XXX,XX +XXX,XX @@ void coroutine_fn blk_co_lock_medium(BlockBackend *blk, bool locked) | ||
80 | { | ||
81 | BlockDriverState *bs = blk_bs(blk); | ||
82 | IO_CODE(); | ||
83 | + GRAPH_RDLOCK_GUARD(); | ||
84 | |||
85 | if (bs) { | ||
86 | bdrv_co_lock_medium(bs, locked); | ||
87 | @@ -XXX,XX +XXX,XX @@ void coroutine_fn blk_co_eject(BlockBackend *blk, bool eject_flag) | ||
88 | BlockDriverState *bs = blk_bs(blk); | ||
89 | char *id; | ||
90 | IO_CODE(); | ||
91 | + GRAPH_RDLOCK_GUARD(); | ||
92 | |||
93 | if (bs) { | ||
94 | bdrv_co_eject(bs, eject_flag); | ||
95 | diff --git a/block/copy-on-read.c b/block/copy-on-read.c | ||
96 | index XXXXXXX..XXXXXXX 100644 | ||
97 | --- a/block/copy-on-read.c | ||
98 | +++ b/block/copy-on-read.c | ||
99 | @@ -XXX,XX +XXX,XX @@ cor_co_pwritev_compressed(BlockDriverState *bs, int64_t offset, int64_t bytes, | ||
100 | } | ||
101 | |||
102 | |||
103 | -static void coroutine_fn cor_co_eject(BlockDriverState *bs, bool eject_flag) | ||
104 | +static void coroutine_fn GRAPH_RDLOCK | ||
105 | +cor_co_eject(BlockDriverState *bs, bool eject_flag) | ||
106 | { | ||
107 | bdrv_co_eject(bs->file->bs, eject_flag); | ||
108 | } | ||
109 | |||
110 | |||
111 | -static void coroutine_fn cor_co_lock_medium(BlockDriverState *bs, bool locked) | ||
112 | +static void coroutine_fn GRAPH_RDLOCK | ||
113 | +cor_co_lock_medium(BlockDriverState *bs, bool locked) | ||
114 | { | ||
115 | bdrv_co_lock_medium(bs->file->bs, locked); | ||
116 | } | ||
117 | diff --git a/block/filter-compress.c b/block/filter-compress.c | ||
118 | index XXXXXXX..XXXXXXX 100644 | ||
119 | --- a/block/filter-compress.c | ||
120 | +++ b/block/filter-compress.c | ||
121 | @@ -XXX,XX +XXX,XX @@ static void compress_refresh_limits(BlockDriverState *bs, Error **errp) | ||
122 | } | ||
123 | |||
124 | |||
125 | -static void coroutine_fn | ||
126 | +static void coroutine_fn GRAPH_RDLOCK | ||
127 | compress_co_eject(BlockDriverState *bs, bool eject_flag) | ||
128 | { | ||
129 | bdrv_co_eject(bs->file->bs, eject_flag); | ||
130 | } | ||
131 | |||
132 | |||
133 | -static void coroutine_fn | ||
134 | +static void coroutine_fn GRAPH_RDLOCK | ||
135 | compress_co_lock_medium(BlockDriverState *bs, bool locked) | ||
136 | { | ||
137 | bdrv_co_lock_medium(bs->file->bs, locked); | ||
138 | diff --git a/block/raw-format.c b/block/raw-format.c | ||
139 | index XXXXXXX..XXXXXXX 100644 | ||
140 | --- a/block/raw-format.c | ||
141 | +++ b/block/raw-format.c | ||
142 | @@ -XXX,XX +XXX,XX @@ raw_co_truncate(BlockDriverState *bs, int64_t offset, bool exact, | ||
143 | return bdrv_co_truncate(bs->file, offset, exact, prealloc, flags, errp); | ||
144 | } | ||
145 | |||
146 | -static void coroutine_fn raw_co_eject(BlockDriverState *bs, bool eject_flag) | ||
147 | +static void coroutine_fn GRAPH_RDLOCK | ||
148 | +raw_co_eject(BlockDriverState *bs, bool eject_flag) | ||
149 | { | ||
150 | bdrv_co_eject(bs->file->bs, eject_flag); | ||
151 | } | ||
152 | |||
153 | -static void coroutine_fn raw_co_lock_medium(BlockDriverState *bs, bool locked) | ||
154 | +static void coroutine_fn GRAPH_RDLOCK | ||
155 | +raw_co_lock_medium(BlockDriverState *bs, bool locked) | ||
156 | { | ||
157 | bdrv_co_lock_medium(bs->file->bs, locked); | ||
158 | } | ||
159 | -- | ||
160 | 2.39.2 | diff view generated by jsdifflib |
Deleted patch | |||
---|---|---|---|
1 | This adds GRAPH_RDLOCK annotations to declare that callers of | ||
2 | bdrv_register_buf() and bdrv_unregister_buf() need to hold a reader lock | ||
3 | for the graph. | ||
4 | 1 | ||
5 | Signed-off-by: Kevin Wolf <kwolf@redhat.com> | ||
6 | Message-Id: <20230203152202.49054-21-kwolf@redhat.com> | ||
7 | Reviewed-by: Emanuele Giuseppe Esposito <eesposit@redhat.com> | ||
8 | Signed-off-by: Kevin Wolf <kwolf@redhat.com> | ||
9 | --- | ||
10 | include/block/block_int-common.h | 7 ++++--- | ||
11 | block/io.c | 14 ++++++++++---- | ||
12 | 2 files changed, 14 insertions(+), 7 deletions(-) | ||
13 | |||
14 | diff --git a/include/block/block_int-common.h b/include/block/block_int-common.h | ||
15 | index XXXXXXX..XXXXXXX 100644 | ||
16 | --- a/include/block/block_int-common.h | ||
17 | +++ b/include/block/block_int-common.h | ||
18 | @@ -XXX,XX +XXX,XX @@ struct BlockDriver { | ||
19 | * | ||
20 | * Returns: true on success, false on failure | ||
21 | */ | ||
22 | - bool (*bdrv_register_buf)(BlockDriverState *bs, void *host, size_t size, | ||
23 | - Error **errp); | ||
24 | - void (*bdrv_unregister_buf)(BlockDriverState *bs, void *host, size_t size); | ||
25 | + bool GRAPH_RDLOCK_PTR (*bdrv_register_buf)( | ||
26 | + BlockDriverState *bs, void *host, size_t size, Error **errp); | ||
27 | + void GRAPH_RDLOCK_PTR (*bdrv_unregister_buf)( | ||
28 | + BlockDriverState *bs, void *host, size_t size); | ||
29 | |||
30 | /* | ||
31 | * This field is modified only under the BQL, and is part of | ||
32 | diff --git a/block/io.c b/block/io.c | ||
33 | index XXXXXXX..XXXXXXX 100644 | ||
34 | --- a/block/io.c | ||
35 | +++ b/block/io.c | ||
36 | @@ -XXX,XX +XXX,XX @@ void coroutine_fn bdrv_co_io_unplug(BlockDriverState *bs) | ||
37 | } | ||
38 | |||
39 | /* Helper that undoes bdrv_register_buf() when it fails partway through */ | ||
40 | -static void bdrv_register_buf_rollback(BlockDriverState *bs, | ||
41 | - void *host, | ||
42 | - size_t size, | ||
43 | - BdrvChild *final_child) | ||
44 | +static void GRAPH_RDLOCK | ||
45 | +bdrv_register_buf_rollback(BlockDriverState *bs, void *host, size_t size, | ||
46 | + BdrvChild *final_child) | ||
47 | { | ||
48 | BdrvChild *child; | ||
49 | |||
50 | + GLOBAL_STATE_CODE(); | ||
51 | + assert_bdrv_graph_readable(); | ||
52 | + | ||
53 | QLIST_FOREACH(child, &bs->children, next) { | ||
54 | if (child == final_child) { | ||
55 | break; | ||
56 | @@ -XXX,XX +XXX,XX @@ bool bdrv_register_buf(BlockDriverState *bs, void *host, size_t size, | ||
57 | BdrvChild *child; | ||
58 | |||
59 | GLOBAL_STATE_CODE(); | ||
60 | + GRAPH_RDLOCK_GUARD_MAINLOOP(); | ||
61 | + | ||
62 | if (bs->drv && bs->drv->bdrv_register_buf) { | ||
63 | if (!bs->drv->bdrv_register_buf(bs, host, size, errp)) { | ||
64 | return false; | ||
65 | @@ -XXX,XX +XXX,XX @@ void bdrv_unregister_buf(BlockDriverState *bs, void *host, size_t size) | ||
66 | BdrvChild *child; | ||
67 | |||
68 | GLOBAL_STATE_CODE(); | ||
69 | + GRAPH_RDLOCK_GUARD_MAINLOOP(); | ||
70 | + | ||
71 | if (bs->drv && bs->drv->bdrv_unregister_buf) { | ||
72 | bs->drv->bdrv_unregister_buf(bs, host, size); | ||
73 | } | ||
74 | -- | ||
75 | 2.39.2 | diff view generated by jsdifflib |
Deleted patch | |||
---|---|---|---|
1 | This adds GRAPH_RDLOCK annotations to declare that callers of | ||
2 | bdrv_co_delete_file() need to hold a reader lock for the graph. | ||
3 | 1 | ||
4 | Signed-off-by: Kevin Wolf <kwolf@redhat.com> | ||
5 | Message-Id: <20230203152202.49054-22-kwolf@redhat.com> | ||
6 | Reviewed-by: Emanuele Giuseppe Esposito <eesposit@redhat.com> | ||
7 | Signed-off-by: Kevin Wolf <kwolf@redhat.com> | ||
8 | --- | ||
9 | include/block/block-io.h | 8 ++++++-- | ||
10 | include/block/block_int-common.h | 4 ++-- | ||
11 | block.c | 1 + | ||
12 | 3 files changed, 9 insertions(+), 4 deletions(-) | ||
13 | |||
14 | diff --git a/include/block/block-io.h b/include/block/block-io.h | ||
15 | index XXXXXXX..XXXXXXX 100644 | ||
16 | --- a/include/block/block-io.h | ||
17 | +++ b/include/block/block-io.h | ||
18 | @@ -XXX,XX +XXX,XX @@ int64_t co_wrapper bdrv_get_allocated_file_size(BlockDriverState *bs); | ||
19 | BlockMeasureInfo *bdrv_measure(BlockDriver *drv, QemuOpts *opts, | ||
20 | BlockDriverState *in_bs, Error **errp); | ||
21 | void bdrv_get_geometry(BlockDriverState *bs, uint64_t *nb_sectors_ptr); | ||
22 | -int coroutine_fn bdrv_co_delete_file(BlockDriverState *bs, Error **errp); | ||
23 | -void coroutine_fn bdrv_co_delete_file_noerr(BlockDriverState *bs); | ||
24 | + | ||
25 | +int coroutine_fn GRAPH_RDLOCK | ||
26 | +bdrv_co_delete_file(BlockDriverState *bs, Error **errp); | ||
27 | + | ||
28 | +void coroutine_fn GRAPH_RDLOCK | ||
29 | +bdrv_co_delete_file_noerr(BlockDriverState *bs); | ||
30 | |||
31 | |||
32 | /* async block I/O */ | ||
33 | diff --git a/include/block/block_int-common.h b/include/block/block_int-common.h | ||
34 | index XXXXXXX..XXXXXXX 100644 | ||
35 | --- a/include/block/block_int-common.h | ||
36 | +++ b/include/block/block_int-common.h | ||
37 | @@ -XXX,XX +XXX,XX @@ struct BlockDriver { | ||
38 | int coroutine_fn GRAPH_RDLOCK_PTR (*bdrv_co_flush)(BlockDriverState *bs); | ||
39 | |||
40 | /* Delete a created file. */ | ||
41 | - int coroutine_fn (*bdrv_co_delete_file)(BlockDriverState *bs, | ||
42 | - Error **errp); | ||
43 | + int coroutine_fn GRAPH_RDLOCK_PTR (*bdrv_co_delete_file)( | ||
44 | + BlockDriverState *bs, Error **errp); | ||
45 | |||
46 | /* | ||
47 | * Flushes all data that was already written to the OS all the way down to | ||
48 | diff --git a/block.c b/block.c | ||
49 | index XXXXXXX..XXXXXXX 100644 | ||
50 | --- a/block.c | ||
51 | +++ b/block.c | ||
52 | @@ -XXX,XX +XXX,XX @@ int coroutine_fn bdrv_co_delete_file(BlockDriverState *bs, Error **errp) | ||
53 | |||
54 | IO_CODE(); | ||
55 | assert(bs != NULL); | ||
56 | + assert_bdrv_graph_readable(); | ||
57 | |||
58 | if (!bs->drv) { | ||
59 | error_setg(errp, "Block node '%s' is not opened", bs->filename); | ||
60 | -- | ||
61 | 2.39.2 | diff view generated by jsdifflib |
Deleted patch | |||
---|---|---|---|
1 | This adds GRAPH_RDLOCK annotations to declare that callers of | ||
2 | bdrv_*_dirty_bitmap() need to hold a reader lock for the graph. | ||
3 | 1 | ||
4 | Signed-off-by: Kevin Wolf <kwolf@redhat.com> | ||
5 | Message-Id: <20230203152202.49054-23-kwolf@redhat.com> | ||
6 | Reviewed-by: Emanuele Giuseppe Esposito <eesposit@redhat.com> | ||
7 | Signed-off-by: Kevin Wolf <kwolf@redhat.com> | ||
8 | --- | ||
9 | include/block/block-io.h | 14 ++++++-------- | ||
10 | include/block/block_int-common.h | 6 ++++-- | ||
11 | include/block/dirty-bitmap.h | 12 ++++++------ | ||
12 | block/dirty-bitmap.c | 2 ++ | ||
13 | 4 files changed, 18 insertions(+), 16 deletions(-) | ||
14 | |||
15 | diff --git a/include/block/block-io.h b/include/block/block-io.h | ||
16 | index XXXXXXX..XXXXXXX 100644 | ||
17 | --- a/include/block/block-io.h | ||
18 | +++ b/include/block/block-io.h | ||
19 | @@ -XXX,XX +XXX,XX @@ AioContext *child_of_bds_get_parent_aio_context(BdrvChild *c); | ||
20 | void coroutine_fn GRAPH_RDLOCK bdrv_co_io_plug(BlockDriverState *bs); | ||
21 | void coroutine_fn GRAPH_RDLOCK bdrv_co_io_unplug(BlockDriverState *bs); | ||
22 | |||
23 | -bool coroutine_fn bdrv_co_can_store_new_dirty_bitmap(BlockDriverState *bs, | ||
24 | - const char *name, | ||
25 | - uint32_t granularity, | ||
26 | - Error **errp); | ||
27 | -bool co_wrapper bdrv_can_store_new_dirty_bitmap(BlockDriverState *bs, | ||
28 | - const char *name, | ||
29 | - uint32_t granularity, | ||
30 | - Error **errp); | ||
31 | +bool coroutine_fn GRAPH_RDLOCK | ||
32 | +bdrv_co_can_store_new_dirty_bitmap(BlockDriverState *bs, const char *name, | ||
33 | + uint32_t granularity, Error **errp); | ||
34 | +bool co_wrapper_bdrv_rdlock | ||
35 | +bdrv_can_store_new_dirty_bitmap(BlockDriverState *bs, const char *name, | ||
36 | + uint32_t granularity, Error **errp); | ||
37 | |||
38 | /** | ||
39 | * | ||
40 | diff --git a/include/block/block_int-common.h b/include/block/block_int-common.h | ||
41 | index XXXXXXX..XXXXXXX 100644 | ||
42 | --- a/include/block/block_int-common.h | ||
43 | +++ b/include/block/block_int-common.h | ||
44 | @@ -XXX,XX +XXX,XX @@ struct BlockDriver { | ||
45 | void (*bdrv_drain_end)(BlockDriverState *bs); | ||
46 | |||
47 | bool (*bdrv_supports_persistent_dirty_bitmap)(BlockDriverState *bs); | ||
48 | - bool coroutine_fn (*bdrv_co_can_store_new_dirty_bitmap)( | ||
49 | + | ||
50 | + bool coroutine_fn GRAPH_RDLOCK_PTR (*bdrv_co_can_store_new_dirty_bitmap)( | ||
51 | BlockDriverState *bs, const char *name, uint32_t granularity, | ||
52 | Error **errp); | ||
53 | - int coroutine_fn (*bdrv_co_remove_persistent_dirty_bitmap)( | ||
54 | + | ||
55 | + int coroutine_fn GRAPH_RDLOCK_PTR (*bdrv_co_remove_persistent_dirty_bitmap)( | ||
56 | BlockDriverState *bs, const char *name, Error **errp); | ||
57 | }; | ||
58 | |||
59 | diff --git a/include/block/dirty-bitmap.h b/include/block/dirty-bitmap.h | ||
60 | index XXXXXXX..XXXXXXX 100644 | ||
61 | --- a/include/block/dirty-bitmap.h | ||
62 | +++ b/include/block/dirty-bitmap.h | ||
63 | @@ -XXX,XX +XXX,XX @@ int bdrv_dirty_bitmap_check(const BdrvDirtyBitmap *bitmap, uint32_t flags, | ||
64 | void bdrv_release_dirty_bitmap(BdrvDirtyBitmap *bitmap); | ||
65 | void bdrv_release_named_dirty_bitmaps(BlockDriverState *bs); | ||
66 | |||
67 | -int coroutine_fn bdrv_co_remove_persistent_dirty_bitmap(BlockDriverState *bs, | ||
68 | - const char *name, | ||
69 | - Error **errp); | ||
70 | -int co_wrapper bdrv_remove_persistent_dirty_bitmap(BlockDriverState *bs, | ||
71 | - const char *name, | ||
72 | - Error **errp); | ||
73 | +int coroutine_fn GRAPH_RDLOCK | ||
74 | +bdrv_co_remove_persistent_dirty_bitmap(BlockDriverState *bs, const char *name, | ||
75 | + Error **errp); | ||
76 | +int co_wrapper_bdrv_rdlock | ||
77 | +bdrv_remove_persistent_dirty_bitmap(BlockDriverState *bs, const char *name, | ||
78 | + Error **errp); | ||
79 | |||
80 | void bdrv_disable_dirty_bitmap(BdrvDirtyBitmap *bitmap); | ||
81 | void bdrv_enable_dirty_bitmap(BdrvDirtyBitmap *bitmap); | ||
82 | diff --git a/block/dirty-bitmap.c b/block/dirty-bitmap.c | ||
83 | index XXXXXXX..XXXXXXX 100644 | ||
84 | --- a/block/dirty-bitmap.c | ||
85 | +++ b/block/dirty-bitmap.c | ||
86 | @@ -XXX,XX +XXX,XX @@ int coroutine_fn | ||
87 | bdrv_co_remove_persistent_dirty_bitmap(BlockDriverState *bs, const char *name, | ||
88 | Error **errp) | ||
89 | { | ||
90 | + assert_bdrv_graph_readable(); | ||
91 | if (bs->drv && bs->drv->bdrv_co_remove_persistent_dirty_bitmap) { | ||
92 | return bs->drv->bdrv_co_remove_persistent_dirty_bitmap(bs, name, errp); | ||
93 | } | ||
94 | @@ -XXX,XX +XXX,XX @@ bdrv_co_can_store_new_dirty_bitmap(BlockDriverState *bs, const char *name, | ||
95 | uint32_t granularity, Error **errp) | ||
96 | { | ||
97 | BlockDriver *drv = bs->drv; | ||
98 | + assert_bdrv_graph_readable(); | ||
99 | |||
100 | if (!drv) { | ||
101 | error_setg_errno(errp, ENOMEDIUM, | ||
102 | -- | ||
103 | 2.39.2 | diff view generated by jsdifflib |
Deleted patch | |||
---|---|---|---|
1 | This adds GRAPH_RDLOCK annotations to declare that callers of | ||
2 | bdrv_co_refresh_total_sectors() need to hold a reader lock for the | ||
3 | graph. | ||
4 | 1 | ||
5 | Signed-off-by: Kevin Wolf <kwolf@redhat.com> | ||
6 | Message-Id: <20230203152202.49054-24-kwolf@redhat.com> | ||
7 | Reviewed-by: Emanuele Giuseppe Esposito <eesposit@redhat.com> | ||
8 | Signed-off-by: Kevin Wolf <kwolf@redhat.com> | ||
9 | --- | ||
10 | include/block/block-io.h | 8 ++++---- | ||
11 | include/block/block_int-common.h | 4 +++- | ||
12 | include/block/block_int-io.h | 7 ++++--- | ||
13 | block.c | 3 +++ | ||
14 | block/blkdebug.c | 3 ++- | ||
15 | block/blklogwrites.c | 3 ++- | ||
16 | block/blkreplay.c | 3 ++- | ||
17 | block/blkverify.c | 3 ++- | ||
18 | block/copy-on-read.c | 2 +- | ||
19 | block/crypto.c | 3 ++- | ||
20 | block/filter-compress.c | 3 ++- | ||
21 | block/mirror.c | 3 +++ | ||
22 | block/preallocate.c | 3 ++- | ||
23 | block/quorum.c | 3 ++- | ||
24 | block/raw-format.c | 3 ++- | ||
25 | block/replication.c | 3 ++- | ||
26 | block/stream.c | 8 +++++--- | ||
27 | block/throttle.c | 3 ++- | ||
28 | 18 files changed, 45 insertions(+), 23 deletions(-) | ||
29 | |||
30 | diff --git a/include/block/block-io.h b/include/block/block-io.h | ||
31 | index XXXXXXX..XXXXXXX 100644 | ||
32 | --- a/include/block/block-io.h | ||
33 | +++ b/include/block/block-io.h | ||
34 | @@ -XXX,XX +XXX,XX @@ int coroutine_fn GRAPH_RDLOCK | ||
35 | bdrv_co_truncate(BdrvChild *child, int64_t offset, bool exact, | ||
36 | PreallocMode prealloc, BdrvRequestFlags flags, Error **errp); | ||
37 | |||
38 | -int64_t coroutine_fn bdrv_co_nb_sectors(BlockDriverState *bs); | ||
39 | -int64_t co_wrapper_mixed bdrv_nb_sectors(BlockDriverState *bs); | ||
40 | +int64_t coroutine_fn GRAPH_RDLOCK bdrv_co_nb_sectors(BlockDriverState *bs); | ||
41 | +int64_t co_wrapper_mixed_bdrv_rdlock bdrv_nb_sectors(BlockDriverState *bs); | ||
42 | |||
43 | -int64_t coroutine_fn bdrv_co_getlength(BlockDriverState *bs); | ||
44 | -int64_t co_wrapper_mixed bdrv_getlength(BlockDriverState *bs); | ||
45 | +int64_t coroutine_fn GRAPH_RDLOCK bdrv_co_getlength(BlockDriverState *bs); | ||
46 | +int64_t co_wrapper_mixed_bdrv_rdlock bdrv_getlength(BlockDriverState *bs); | ||
47 | |||
48 | int64_t coroutine_fn bdrv_co_get_allocated_file_size(BlockDriverState *bs); | ||
49 | int64_t co_wrapper bdrv_get_allocated_file_size(BlockDriverState *bs); | ||
50 | diff --git a/include/block/block_int-common.h b/include/block/block_int-common.h | ||
51 | index XXXXXXX..XXXXXXX 100644 | ||
52 | --- a/include/block/block_int-common.h | ||
53 | +++ b/include/block/block_int-common.h | ||
54 | @@ -XXX,XX +XXX,XX @@ struct BlockDriver { | ||
55 | BlockDriverState *bs, int64_t offset, bool exact, | ||
56 | PreallocMode prealloc, BdrvRequestFlags flags, Error **errp); | ||
57 | |||
58 | - int64_t coroutine_fn (*bdrv_co_getlength)(BlockDriverState *bs); | ||
59 | + int64_t coroutine_fn GRAPH_RDLOCK_PTR (*bdrv_co_getlength)( | ||
60 | + BlockDriverState *bs); | ||
61 | + | ||
62 | int64_t coroutine_fn (*bdrv_co_get_allocated_file_size)( | ||
63 | BlockDriverState *bs); | ||
64 | |||
65 | diff --git a/include/block/block_int-io.h b/include/block/block_int-io.h | ||
66 | index XXXXXXX..XXXXXXX 100644 | ||
67 | --- a/include/block/block_int-io.h | ||
68 | +++ b/include/block/block_int-io.h | ||
69 | @@ -XXX,XX +XXX,XX @@ bdrv_co_copy_range_to(BdrvChild *src, int64_t src_offset, | ||
70 | int64_t bytes, BdrvRequestFlags read_flags, | ||
71 | BdrvRequestFlags write_flags); | ||
72 | |||
73 | -int coroutine_fn bdrv_co_refresh_total_sectors(BlockDriverState *bs, | ||
74 | - int64_t hint); | ||
75 | -int co_wrapper_mixed | ||
76 | +int coroutine_fn GRAPH_RDLOCK | ||
77 | +bdrv_co_refresh_total_sectors(BlockDriverState *bs, int64_t hint); | ||
78 | + | ||
79 | +int co_wrapper_mixed_bdrv_rdlock | ||
80 | bdrv_refresh_total_sectors(BlockDriverState *bs, int64_t hint); | ||
81 | |||
82 | BdrvChild *bdrv_cow_child(BlockDriverState *bs); | ||
83 | diff --git a/block.c b/block.c | ||
84 | index XXXXXXX..XXXXXXX 100644 | ||
85 | --- a/block.c | ||
86 | +++ b/block.c | ||
87 | @@ -XXX,XX +XXX,XX @@ int coroutine_fn bdrv_co_refresh_total_sectors(BlockDriverState *bs, | ||
88 | { | ||
89 | BlockDriver *drv = bs->drv; | ||
90 | IO_CODE(); | ||
91 | + assert_bdrv_graph_readable(); | ||
92 | |||
93 | if (!drv) { | ||
94 | return -ENOMEDIUM; | ||
95 | @@ -XXX,XX +XXX,XX @@ int64_t coroutine_fn bdrv_co_nb_sectors(BlockDriverState *bs) | ||
96 | { | ||
97 | BlockDriver *drv = bs->drv; | ||
98 | IO_CODE(); | ||
99 | + assert_bdrv_graph_readable(); | ||
100 | |||
101 | if (!drv) | ||
102 | return -ENOMEDIUM; | ||
103 | @@ -XXX,XX +XXX,XX @@ int64_t coroutine_fn bdrv_co_getlength(BlockDriverState *bs) | ||
104 | { | ||
105 | int64_t ret; | ||
106 | IO_CODE(); | ||
107 | + assert_bdrv_graph_readable(); | ||
108 | |||
109 | ret = bdrv_co_nb_sectors(bs); | ||
110 | if (ret < 0) { | ||
111 | diff --git a/block/blkdebug.c b/block/blkdebug.c | ||
112 | index XXXXXXX..XXXXXXX 100644 | ||
113 | --- a/block/blkdebug.c | ||
114 | +++ b/block/blkdebug.c | ||
115 | @@ -XXX,XX +XXX,XX @@ static bool blkdebug_debug_is_suspended(BlockDriverState *bs, const char *tag) | ||
116 | return false; | ||
117 | } | ||
118 | |||
119 | -static int64_t coroutine_fn blkdebug_co_getlength(BlockDriverState *bs) | ||
120 | +static int64_t coroutine_fn GRAPH_RDLOCK | ||
121 | +blkdebug_co_getlength(BlockDriverState *bs) | ||
122 | { | ||
123 | return bdrv_co_getlength(bs->file->bs); | ||
124 | } | ||
125 | diff --git a/block/blklogwrites.c b/block/blklogwrites.c | ||
126 | index XXXXXXX..XXXXXXX 100644 | ||
127 | --- a/block/blklogwrites.c | ||
128 | +++ b/block/blklogwrites.c | ||
129 | @@ -XXX,XX +XXX,XX @@ static void blk_log_writes_close(BlockDriverState *bs) | ||
130 | s->log_file = NULL; | ||
131 | } | ||
132 | |||
133 | -static int64_t coroutine_fn blk_log_writes_co_getlength(BlockDriverState *bs) | ||
134 | +static int64_t coroutine_fn GRAPH_RDLOCK | ||
135 | +blk_log_writes_co_getlength(BlockDriverState *bs) | ||
136 | { | ||
137 | return bdrv_co_getlength(bs->file->bs); | ||
138 | } | ||
139 | diff --git a/block/blkreplay.c b/block/blkreplay.c | ||
140 | index XXXXXXX..XXXXXXX 100644 | ||
141 | --- a/block/blkreplay.c | ||
142 | +++ b/block/blkreplay.c | ||
143 | @@ -XXX,XX +XXX,XX @@ fail: | ||
144 | return ret; | ||
145 | } | ||
146 | |||
147 | -static int64_t coroutine_fn blkreplay_co_getlength(BlockDriverState *bs) | ||
148 | +static int64_t coroutine_fn GRAPH_RDLOCK | ||
149 | +blkreplay_co_getlength(BlockDriverState *bs) | ||
150 | { | ||
151 | return bdrv_co_getlength(bs->file->bs); | ||
152 | } | ||
153 | diff --git a/block/blkverify.c b/block/blkverify.c | ||
154 | index XXXXXXX..XXXXXXX 100644 | ||
155 | --- a/block/blkverify.c | ||
156 | +++ b/block/blkverify.c | ||
157 | @@ -XXX,XX +XXX,XX @@ static void blkverify_close(BlockDriverState *bs) | ||
158 | s->test_file = NULL; | ||
159 | } | ||
160 | |||
161 | -static int64_t coroutine_fn blkverify_co_getlength(BlockDriverState *bs) | ||
162 | +static int64_t coroutine_fn GRAPH_RDLOCK | ||
163 | +blkverify_co_getlength(BlockDriverState *bs) | ||
164 | { | ||
165 | BDRVBlkverifyState *s = bs->opaque; | ||
166 | |||
167 | diff --git a/block/copy-on-read.c b/block/copy-on-read.c | ||
168 | index XXXXXXX..XXXXXXX 100644 | ||
169 | --- a/block/copy-on-read.c | ||
170 | +++ b/block/copy-on-read.c | ||
171 | @@ -XXX,XX +XXX,XX @@ static void cor_child_perm(BlockDriverState *bs, BdrvChild *c, | ||
172 | } | ||
173 | |||
174 | |||
175 | -static int64_t coroutine_fn cor_co_getlength(BlockDriverState *bs) | ||
176 | +static int64_t coroutine_fn GRAPH_RDLOCK cor_co_getlength(BlockDriverState *bs) | ||
177 | { | ||
178 | return bdrv_co_getlength(bs->file->bs); | ||
179 | } | ||
180 | diff --git a/block/crypto.c b/block/crypto.c | ||
181 | index XXXXXXX..XXXXXXX 100644 | ||
182 | --- a/block/crypto.c | ||
183 | +++ b/block/crypto.c | ||
184 | @@ -XXX,XX +XXX,XX @@ static void block_crypto_refresh_limits(BlockDriverState *bs, Error **errp) | ||
185 | } | ||
186 | |||
187 | |||
188 | -static int64_t coroutine_fn block_crypto_co_getlength(BlockDriverState *bs) | ||
189 | +static int64_t coroutine_fn GRAPH_RDLOCK | ||
190 | +block_crypto_co_getlength(BlockDriverState *bs) | ||
191 | { | ||
192 | BlockCrypto *crypto = bs->opaque; | ||
193 | int64_t len = bdrv_co_getlength(bs->file->bs); | ||
194 | diff --git a/block/filter-compress.c b/block/filter-compress.c | ||
195 | index XXXXXXX..XXXXXXX 100644 | ||
196 | --- a/block/filter-compress.c | ||
197 | +++ b/block/filter-compress.c | ||
198 | @@ -XXX,XX +XXX,XX @@ static int compress_open(BlockDriverState *bs, QDict *options, int flags, | ||
199 | } | ||
200 | |||
201 | |||
202 | -static int64_t coroutine_fn compress_co_getlength(BlockDriverState *bs) | ||
203 | +static int64_t coroutine_fn GRAPH_RDLOCK | ||
204 | +compress_co_getlength(BlockDriverState *bs) | ||
205 | { | ||
206 | return bdrv_co_getlength(bs->file->bs); | ||
207 | } | ||
208 | diff --git a/block/mirror.c b/block/mirror.c | ||
209 | index XXXXXXX..XXXXXXX 100644 | ||
210 | --- a/block/mirror.c | ||
211 | +++ b/block/mirror.c | ||
212 | @@ -XXX,XX +XXX,XX @@ static int coroutine_fn mirror_run(Job *job, Error **errp) | ||
213 | goto immediate_exit; | ||
214 | } | ||
215 | |||
216 | + bdrv_graph_co_rdlock(); | ||
217 | s->bdev_length = bdrv_co_getlength(bs); | ||
218 | + bdrv_graph_co_rdunlock(); | ||
219 | + | ||
220 | if (s->bdev_length < 0) { | ||
221 | ret = s->bdev_length; | ||
222 | goto immediate_exit; | ||
223 | diff --git a/block/preallocate.c b/block/preallocate.c | ||
224 | index XXXXXXX..XXXXXXX 100644 | ||
225 | --- a/block/preallocate.c | ||
226 | +++ b/block/preallocate.c | ||
227 | @@ -XXX,XX +XXX,XX @@ static int coroutine_fn GRAPH_RDLOCK preallocate_co_flush(BlockDriverState *bs) | ||
228 | return bdrv_co_flush(bs->file->bs); | ||
229 | } | ||
230 | |||
231 | -static int64_t coroutine_fn preallocate_co_getlength(BlockDriverState *bs) | ||
232 | +static int64_t coroutine_fn GRAPH_RDLOCK | ||
233 | +preallocate_co_getlength(BlockDriverState *bs) | ||
234 | { | ||
235 | int64_t ret; | ||
236 | BDRVPreallocateState *s = bs->opaque; | ||
237 | diff --git a/block/quorum.c b/block/quorum.c | ||
238 | index XXXXXXX..XXXXXXX 100644 | ||
239 | --- a/block/quorum.c | ||
240 | +++ b/block/quorum.c | ||
241 | @@ -XXX,XX +XXX,XX @@ quorum_co_pwrite_zeroes(BlockDriverState *bs, int64_t offset, int64_t bytes, | ||
242 | flags | BDRV_REQ_ZERO_WRITE); | ||
243 | } | ||
244 | |||
245 | -static int64_t coroutine_fn quorum_co_getlength(BlockDriverState *bs) | ||
246 | +static int64_t coroutine_fn GRAPH_RDLOCK | ||
247 | +quorum_co_getlength(BlockDriverState *bs) | ||
248 | { | ||
249 | BDRVQuorumState *s = bs->opaque; | ||
250 | int64_t result; | ||
251 | diff --git a/block/raw-format.c b/block/raw-format.c | ||
252 | index XXXXXXX..XXXXXXX 100644 | ||
253 | --- a/block/raw-format.c | ||
254 | +++ b/block/raw-format.c | ||
255 | @@ -XXX,XX +XXX,XX @@ raw_co_pdiscard(BlockDriverState *bs, int64_t offset, int64_t bytes) | ||
256 | return bdrv_co_pdiscard(bs->file, offset, bytes); | ||
257 | } | ||
258 | |||
259 | -static int64_t coroutine_fn raw_co_getlength(BlockDriverState *bs) | ||
260 | +static int64_t coroutine_fn GRAPH_RDLOCK | ||
261 | +raw_co_getlength(BlockDriverState *bs) | ||
262 | { | ||
263 | int64_t len; | ||
264 | BDRVRawState *s = bs->opaque; | ||
265 | diff --git a/block/replication.c b/block/replication.c | ||
266 | index XXXXXXX..XXXXXXX 100644 | ||
267 | --- a/block/replication.c | ||
268 | +++ b/block/replication.c | ||
269 | @@ -XXX,XX +XXX,XX @@ static void replication_child_perm(BlockDriverState *bs, BdrvChild *c, | ||
270 | return; | ||
271 | } | ||
272 | |||
273 | -static int64_t coroutine_fn replication_co_getlength(BlockDriverState *bs) | ||
274 | +static int64_t coroutine_fn GRAPH_RDLOCK | ||
275 | +replication_co_getlength(BlockDriverState *bs) | ||
276 | { | ||
277 | return bdrv_co_getlength(bs->file->bs); | ||
278 | } | ||
279 | diff --git a/block/stream.c b/block/stream.c | ||
280 | index XXXXXXX..XXXXXXX 100644 | ||
281 | --- a/block/stream.c | ||
282 | +++ b/block/stream.c | ||
283 | @@ -XXX,XX +XXX,XX @@ static int coroutine_fn stream_run(Job *job, Error **errp) | ||
284 | return 0; | ||
285 | } | ||
286 | |||
287 | - len = bdrv_getlength(s->target_bs); | ||
288 | - if (len < 0) { | ||
289 | - return len; | ||
290 | + WITH_GRAPH_RDLOCK_GUARD() { | ||
291 | + len = bdrv_co_getlength(s->target_bs); | ||
292 | + if (len < 0) { | ||
293 | + return len; | ||
294 | + } | ||
295 | } | ||
296 | job_progress_set_remaining(&s->common.job, len); | ||
297 | |||
298 | diff --git a/block/throttle.c b/block/throttle.c | ||
299 | index XXXXXXX..XXXXXXX 100644 | ||
300 | --- a/block/throttle.c | ||
301 | +++ b/block/throttle.c | ||
302 | @@ -XXX,XX +XXX,XX @@ static void throttle_close(BlockDriverState *bs) | ||
303 | } | ||
304 | |||
305 | |||
306 | -static int64_t coroutine_fn throttle_co_getlength(BlockDriverState *bs) | ||
307 | +static int64_t coroutine_fn GRAPH_RDLOCK | ||
308 | +throttle_co_getlength(BlockDriverState *bs) | ||
309 | { | ||
310 | return bdrv_co_getlength(bs->file->bs); | ||
311 | } | ||
312 | -- | ||
313 | 2.39.2 | diff view generated by jsdifflib |
Deleted patch | |||
---|---|---|---|
1 | From: Stefan Hajnoczi <stefanha@redhat.com> | ||
2 | 1 | ||
3 | If requests are being processed in the IOThread when a SCSIDevice is | ||
4 | unplugged, scsi_device_purge_requests() -> scsi_req_cancel_async() races | ||
5 | with I/O completion callbacks. Both threads load and store req->aiocb. | ||
6 | This can lead to assert(r->req.aiocb == NULL) failures and undefined | ||
7 | behavior. | ||
8 | |||
9 | Protect r->req.aiocb with the AioContext lock to prevent the race. | ||
10 | |||
11 | Reviewed-by: Eric Blake <eblake@redhat.com> | ||
12 | Reviewed-by: Kevin Wolf <kwolf@redhat.com> | ||
13 | Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com> | ||
14 | Message-Id: <20230221212218.1378734-2-stefanha@redhat.com> | ||
15 | Signed-off-by: Kevin Wolf <kwolf@redhat.com> | ||
16 | --- | ||
17 | hw/scsi/scsi-disk.c | 23 ++++++++++++++++------- | ||
18 | hw/scsi/scsi-generic.c | 11 ++++++----- | ||
19 | 2 files changed, 22 insertions(+), 12 deletions(-) | ||
20 | |||
21 | diff --git a/hw/scsi/scsi-disk.c b/hw/scsi/scsi-disk.c | ||
22 | index XXXXXXX..XXXXXXX 100644 | ||
23 | --- a/hw/scsi/scsi-disk.c | ||
24 | +++ b/hw/scsi/scsi-disk.c | ||
25 | @@ -XXX,XX +XXX,XX @@ static void scsi_aio_complete(void *opaque, int ret) | ||
26 | SCSIDiskReq *r = (SCSIDiskReq *)opaque; | ||
27 | SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, r->req.dev); | ||
28 | |||
29 | + aio_context_acquire(blk_get_aio_context(s->qdev.conf.blk)); | ||
30 | + | ||
31 | assert(r->req.aiocb != NULL); | ||
32 | r->req.aiocb = NULL; | ||
33 | - aio_context_acquire(blk_get_aio_context(s->qdev.conf.blk)); | ||
34 | + | ||
35 | if (scsi_disk_req_check_error(r, ret, true)) { | ||
36 | goto done; | ||
37 | } | ||
38 | @@ -XXX,XX +XXX,XX @@ static void scsi_dma_complete(void *opaque, int ret) | ||
39 | SCSIDiskReq *r = (SCSIDiskReq *)opaque; | ||
40 | SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, r->req.dev); | ||
41 | |||
42 | + aio_context_acquire(blk_get_aio_context(s->qdev.conf.blk)); | ||
43 | + | ||
44 | assert(r->req.aiocb != NULL); | ||
45 | r->req.aiocb = NULL; | ||
46 | |||
47 | - aio_context_acquire(blk_get_aio_context(s->qdev.conf.blk)); | ||
48 | if (ret < 0) { | ||
49 | block_acct_failed(blk_get_stats(s->qdev.conf.blk), &r->acct); | ||
50 | } else { | ||
51 | @@ -XXX,XX +XXX,XX @@ static void scsi_read_complete(void *opaque, int ret) | ||
52 | SCSIDiskReq *r = (SCSIDiskReq *)opaque; | ||
53 | SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, r->req.dev); | ||
54 | |||
55 | + aio_context_acquire(blk_get_aio_context(s->qdev.conf.blk)); | ||
56 | + | ||
57 | assert(r->req.aiocb != NULL); | ||
58 | r->req.aiocb = NULL; | ||
59 | |||
60 | - aio_context_acquire(blk_get_aio_context(s->qdev.conf.blk)); | ||
61 | if (ret < 0) { | ||
62 | block_acct_failed(blk_get_stats(s->qdev.conf.blk), &r->acct); | ||
63 | } else { | ||
64 | @@ -XXX,XX +XXX,XX @@ static void scsi_do_read_cb(void *opaque, int ret) | ||
65 | SCSIDiskReq *r = (SCSIDiskReq *)opaque; | ||
66 | SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, r->req.dev); | ||
67 | |||
68 | + aio_context_acquire(blk_get_aio_context(s->qdev.conf.blk)); | ||
69 | + | ||
70 | assert (r->req.aiocb != NULL); | ||
71 | r->req.aiocb = NULL; | ||
72 | |||
73 | - aio_context_acquire(blk_get_aio_context(s->qdev.conf.blk)); | ||
74 | if (ret < 0) { | ||
75 | block_acct_failed(blk_get_stats(s->qdev.conf.blk), &r->acct); | ||
76 | } else { | ||
77 | @@ -XXX,XX +XXX,XX @@ static void scsi_write_complete(void * opaque, int ret) | ||
78 | SCSIDiskReq *r = (SCSIDiskReq *)opaque; | ||
79 | SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, r->req.dev); | ||
80 | |||
81 | + aio_context_acquire(blk_get_aio_context(s->qdev.conf.blk)); | ||
82 | + | ||
83 | assert (r->req.aiocb != NULL); | ||
84 | r->req.aiocb = NULL; | ||
85 | |||
86 | - aio_context_acquire(blk_get_aio_context(s->qdev.conf.blk)); | ||
87 | if (ret < 0) { | ||
88 | block_acct_failed(blk_get_stats(s->qdev.conf.blk), &r->acct); | ||
89 | } else { | ||
90 | @@ -XXX,XX +XXX,XX @@ static void scsi_unmap_complete(void *opaque, int ret) | ||
91 | SCSIDiskReq *r = data->r; | ||
92 | SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, r->req.dev); | ||
93 | |||
94 | + aio_context_acquire(blk_get_aio_context(s->qdev.conf.blk)); | ||
95 | + | ||
96 | assert(r->req.aiocb != NULL); | ||
97 | r->req.aiocb = NULL; | ||
98 | |||
99 | - aio_context_acquire(blk_get_aio_context(s->qdev.conf.blk)); | ||
100 | if (scsi_disk_req_check_error(r, ret, true)) { | ||
101 | scsi_req_unref(&r->req); | ||
102 | g_free(data); | ||
103 | @@ -XXX,XX +XXX,XX @@ static void scsi_write_same_complete(void *opaque, int ret) | ||
104 | SCSIDiskReq *r = data->r; | ||
105 | SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, r->req.dev); | ||
106 | |||
107 | + aio_context_acquire(blk_get_aio_context(s->qdev.conf.blk)); | ||
108 | + | ||
109 | assert(r->req.aiocb != NULL); | ||
110 | r->req.aiocb = NULL; | ||
111 | - aio_context_acquire(blk_get_aio_context(s->qdev.conf.blk)); | ||
112 | + | ||
113 | if (scsi_disk_req_check_error(r, ret, true)) { | ||
114 | goto done; | ||
115 | } | ||
116 | diff --git a/hw/scsi/scsi-generic.c b/hw/scsi/scsi-generic.c | ||
117 | index XXXXXXX..XXXXXXX 100644 | ||
118 | --- a/hw/scsi/scsi-generic.c | ||
119 | +++ b/hw/scsi/scsi-generic.c | ||
120 | @@ -XXX,XX +XXX,XX @@ static void scsi_command_complete(void *opaque, int ret) | ||
121 | SCSIGenericReq *r = (SCSIGenericReq *)opaque; | ||
122 | SCSIDevice *s = r->req.dev; | ||
123 | |||
124 | + aio_context_acquire(blk_get_aio_context(s->conf.blk)); | ||
125 | + | ||
126 | assert(r->req.aiocb != NULL); | ||
127 | r->req.aiocb = NULL; | ||
128 | |||
129 | - aio_context_acquire(blk_get_aio_context(s->conf.blk)); | ||
130 | scsi_command_complete_noio(r, ret); | ||
131 | aio_context_release(blk_get_aio_context(s->conf.blk)); | ||
132 | } | ||
133 | @@ -XXX,XX +XXX,XX @@ static void scsi_read_complete(void * opaque, int ret) | ||
134 | SCSIDevice *s = r->req.dev; | ||
135 | int len; | ||
136 | |||
137 | + aio_context_acquire(blk_get_aio_context(s->conf.blk)); | ||
138 | + | ||
139 | assert(r->req.aiocb != NULL); | ||
140 | r->req.aiocb = NULL; | ||
141 | |||
142 | - aio_context_acquire(blk_get_aio_context(s->conf.blk)); | ||
143 | - | ||
144 | if (ret || r->req.io_canceled) { | ||
145 | scsi_command_complete_noio(r, ret); | ||
146 | goto done; | ||
147 | @@ -XXX,XX +XXX,XX @@ static void scsi_write_complete(void * opaque, int ret) | ||
148 | |||
149 | trace_scsi_generic_write_complete(ret); | ||
150 | |||
151 | + aio_context_acquire(blk_get_aio_context(s->conf.blk)); | ||
152 | + | ||
153 | assert(r->req.aiocb != NULL); | ||
154 | r->req.aiocb = NULL; | ||
155 | |||
156 | - aio_context_acquire(blk_get_aio_context(s->conf.blk)); | ||
157 | - | ||
158 | if (ret || r->req.io_canceled) { | ||
159 | scsi_command_complete_noio(r, ret); | ||
160 | goto done; | ||
161 | -- | ||
162 | 2.39.2 | diff view generated by jsdifflib |
Deleted patch | |||
---|---|---|---|
1 | From: Stefan Hajnoczi <stefanha@redhat.com> | ||
2 | 1 | ||
3 | dma_blk_cb() only takes the AioContext lock around ->io_func(). That | ||
4 | means the rest of dma_blk_cb() is not protected. In particular, the | ||
5 | DMAAIOCB field accesses happen outside the lock. | ||
6 | |||
7 | There is a race when the main loop thread holds the AioContext lock and | ||
8 | invokes scsi_device_purge_requests() -> bdrv_aio_cancel() -> | ||
9 | dma_aio_cancel() while an IOThread executes dma_blk_cb(). The dbs->acb | ||
10 | field determines how cancellation proceeds. If dma_aio_cancel() sees | ||
11 | dbs->acb == NULL while dma_blk_cb() is still running, the request can be | ||
12 | completed twice (-ECANCELED and the actual return value). | ||
13 | |||
14 | The following assertion can occur with virtio-scsi when an IOThread is | ||
15 | used: | ||
16 | |||
17 | ../hw/scsi/scsi-disk.c:368: scsi_dma_complete: Assertion `r->req.aiocb != NULL' failed. | ||
18 | |||
19 | Fix the race by holding the AioContext across dma_blk_cb(). Now | ||
20 | dma_aio_cancel() under the AioContext lock will not see | ||
21 | inconsistent/intermediate states. | ||
22 | |||
23 | Cc: Paolo Bonzini <pbonzini@redhat.com> | ||
24 | Reviewed-by: Eric Blake <eblake@redhat.com> | ||
25 | Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com> | ||
26 | Message-Id: <20230221212218.1378734-3-stefanha@redhat.com> | ||
27 | Signed-off-by: Kevin Wolf <kwolf@redhat.com> | ||
28 | --- | ||
29 | hw/scsi/scsi-disk.c | 4 +--- | ||
30 | softmmu/dma-helpers.c | 12 +++++++----- | ||
31 | 2 files changed, 8 insertions(+), 8 deletions(-) | ||
32 | |||
33 | diff --git a/hw/scsi/scsi-disk.c b/hw/scsi/scsi-disk.c | ||
34 | index XXXXXXX..XXXXXXX 100644 | ||
35 | --- a/hw/scsi/scsi-disk.c | ||
36 | +++ b/hw/scsi/scsi-disk.c | ||
37 | @@ -XXX,XX +XXX,XX @@ done: | ||
38 | scsi_req_unref(&r->req); | ||
39 | } | ||
40 | |||
41 | +/* Called with AioContext lock held */ | ||
42 | static void scsi_dma_complete(void *opaque, int ret) | ||
43 | { | ||
44 | SCSIDiskReq *r = (SCSIDiskReq *)opaque; | ||
45 | SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, r->req.dev); | ||
46 | |||
47 | - aio_context_acquire(blk_get_aio_context(s->qdev.conf.blk)); | ||
48 | - | ||
49 | assert(r->req.aiocb != NULL); | ||
50 | r->req.aiocb = NULL; | ||
51 | |||
52 | @@ -XXX,XX +XXX,XX @@ static void scsi_dma_complete(void *opaque, int ret) | ||
53 | block_acct_done(blk_get_stats(s->qdev.conf.blk), &r->acct); | ||
54 | } | ||
55 | scsi_dma_complete_noio(r, ret); | ||
56 | - aio_context_release(blk_get_aio_context(s->qdev.conf.blk)); | ||
57 | } | ||
58 | |||
59 | static void scsi_read_complete_noio(SCSIDiskReq *r, int ret) | ||
60 | diff --git a/softmmu/dma-helpers.c b/softmmu/dma-helpers.c | ||
61 | index XXXXXXX..XXXXXXX 100644 | ||
62 | --- a/softmmu/dma-helpers.c | ||
63 | +++ b/softmmu/dma-helpers.c | ||
64 | @@ -XXX,XX +XXX,XX @@ static void dma_complete(DMAAIOCB *dbs, int ret) | ||
65 | static void dma_blk_cb(void *opaque, int ret) | ||
66 | { | ||
67 | DMAAIOCB *dbs = (DMAAIOCB *)opaque; | ||
68 | + AioContext *ctx = dbs->ctx; | ||
69 | dma_addr_t cur_addr, cur_len; | ||
70 | void *mem; | ||
71 | |||
72 | trace_dma_blk_cb(dbs, ret); | ||
73 | |||
74 | + aio_context_acquire(ctx); | ||
75 | dbs->acb = NULL; | ||
76 | dbs->offset += dbs->iov.size; | ||
77 | |||
78 | if (dbs->sg_cur_index == dbs->sg->nsg || ret < 0) { | ||
79 | dma_complete(dbs, ret); | ||
80 | - return; | ||
81 | + goto out; | ||
82 | } | ||
83 | dma_blk_unmap(dbs); | ||
84 | |||
85 | @@ -XXX,XX +XXX,XX @@ static void dma_blk_cb(void *opaque, int ret) | ||
86 | |||
87 | if (dbs->iov.size == 0) { | ||
88 | trace_dma_map_wait(dbs); | ||
89 | - dbs->bh = aio_bh_new(dbs->ctx, reschedule_dma, dbs); | ||
90 | + dbs->bh = aio_bh_new(ctx, reschedule_dma, dbs); | ||
91 | cpu_register_map_client(dbs->bh); | ||
92 | - return; | ||
93 | + goto out; | ||
94 | } | ||
95 | |||
96 | if (!QEMU_IS_ALIGNED(dbs->iov.size, dbs->align)) { | ||
97 | @@ -XXX,XX +XXX,XX @@ static void dma_blk_cb(void *opaque, int ret) | ||
98 | QEMU_ALIGN_DOWN(dbs->iov.size, dbs->align)); | ||
99 | } | ||
100 | |||
101 | - aio_context_acquire(dbs->ctx); | ||
102 | dbs->acb = dbs->io_func(dbs->offset, &dbs->iov, | ||
103 | dma_blk_cb, dbs, dbs->io_func_opaque); | ||
104 | - aio_context_release(dbs->ctx); | ||
105 | assert(dbs->acb); | ||
106 | +out: | ||
107 | + aio_context_release(ctx); | ||
108 | } | ||
109 | |||
110 | static void dma_aio_cancel(BlockAIOCB *acb) | ||
111 | -- | ||
112 | 2.39.2 | diff view generated by jsdifflib |
Deleted patch | |||
---|---|---|---|
1 | From: Stefan Hajnoczi <stefanha@redhat.com> | ||
2 | 1 | ||
3 | When an IOThread is configured, the ctrl virtqueue is processed in the | ||
4 | IOThread. TMFs that reset SCSI devices are currently called directly | ||
5 | from the IOThread and trigger an assertion failure in blk_drain() from | ||
6 | the following call stack: | ||
7 | |||
8 | virtio_scsi_handle_ctrl_req -> virtio_scsi_do_tmf -> device_code_reset | ||
9 | -> scsi_disk_reset -> scsi_device_purge_requests -> blk_drain | ||
10 | |||
11 | ../block/block-backend.c:1780: void blk_drain(BlockBackend *): Assertion `qemu_in_main_thread()' failed. | ||
12 | |||
13 | The blk_drain() function is not designed to be called from an IOThread | ||
14 | because it needs the Big QEMU Lock (BQL). | ||
15 | |||
16 | This patch defers TMFs that reset SCSI devices to a Bottom Half (BH) | ||
17 | that runs in the main loop thread under the BQL. This way it's safe to | ||
18 | call blk_drain() and the assertion failure is avoided. | ||
19 | |||
20 | Introduce s->tmf_bh_list for tracking TMF requests that have been | ||
21 | deferred to the BH. When the BH runs it will grab the entire list and | ||
22 | process all requests. Care must be taken to clear the list when the | ||
23 | virtio-scsi device is reset or unrealized. Otherwise deferred TMF | ||
24 | requests could execute later and lead to use-after-free or other | ||
25 | undefined behavior. | ||
26 | |||
27 | The s->resetting counter that's used by TMFs that reset SCSI devices is | ||
28 | accessed from multiple threads. This patch makes that explicit by using | ||
29 | atomic accessor functions. With this patch applied the counter is only | ||
30 | modified by the main loop thread under the BQL but can be read by any | ||
31 | thread. | ||
32 | |||
33 | Reported-by: Qing Wang <qinwang@redhat.com> | ||
34 | Cc: Paolo Bonzini <pbonzini@redhat.com> | ||
35 | Reviewed-by: Eric Blake <eblake@redhat.com> | ||
36 | Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com> | ||
37 | Message-Id: <20230221212218.1378734-4-stefanha@redhat.com> | ||
38 | Signed-off-by: Kevin Wolf <kwolf@redhat.com> | ||
39 | --- | ||
40 | include/hw/virtio/virtio-scsi.h | 11 ++- | ||
41 | hw/scsi/virtio-scsi.c | 169 +++++++++++++++++++++++++------- | ||
42 | 2 files changed, 143 insertions(+), 37 deletions(-) | ||
43 | |||
44 | diff --git a/include/hw/virtio/virtio-scsi.h b/include/hw/virtio/virtio-scsi.h | ||
45 | index XXXXXXX..XXXXXXX 100644 | ||
46 | --- a/include/hw/virtio/virtio-scsi.h | ||
47 | +++ b/include/hw/virtio/virtio-scsi.h | ||
48 | @@ -XXX,XX +XXX,XX @@ struct VirtIOSCSICommon { | ||
49 | VirtQueue **cmd_vqs; | ||
50 | }; | ||
51 | |||
52 | +struct VirtIOSCSIReq; | ||
53 | + | ||
54 | struct VirtIOSCSI { | ||
55 | VirtIOSCSICommon parent_obj; | ||
56 | |||
57 | SCSIBus bus; | ||
58 | - int resetting; | ||
59 | + int resetting; /* written from main loop thread, read from any thread */ | ||
60 | bool events_dropped; | ||
61 | |||
62 | + /* | ||
63 | + * TMFs deferred to main loop BH. These fields are protected by | ||
64 | + * virtio_scsi_acquire(). | ||
65 | + */ | ||
66 | + QEMUBH *tmf_bh; | ||
67 | + QTAILQ_HEAD(, VirtIOSCSIReq) tmf_bh_list; | ||
68 | + | ||
69 | /* Fields for dataplane below */ | ||
70 | AioContext *ctx; /* one iothread per virtio-scsi-pci for now */ | ||
71 | |||
72 | diff --git a/hw/scsi/virtio-scsi.c b/hw/scsi/virtio-scsi.c | ||
73 | index XXXXXXX..XXXXXXX 100644 | ||
74 | --- a/hw/scsi/virtio-scsi.c | ||
75 | +++ b/hw/scsi/virtio-scsi.c | ||
76 | @@ -XXX,XX +XXX,XX @@ typedef struct VirtIOSCSIReq { | ||
77 | QEMUSGList qsgl; | ||
78 | QEMUIOVector resp_iov; | ||
79 | |||
80 | - union { | ||
81 | - /* Used for two-stage request submission */ | ||
82 | - QTAILQ_ENTRY(VirtIOSCSIReq) next; | ||
83 | + /* Used for two-stage request submission and TMFs deferred to BH */ | ||
84 | + QTAILQ_ENTRY(VirtIOSCSIReq) next; | ||
85 | |||
86 | - /* Used for cancellation of request during TMFs */ | ||
87 | - int remaining; | ||
88 | - }; | ||
89 | + /* Used for cancellation of request during TMFs */ | ||
90 | + int remaining; | ||
91 | |||
92 | SCSIRequest *sreq; | ||
93 | size_t resp_size; | ||
94 | @@ -XXX,XX +XXX,XX @@ static inline void virtio_scsi_ctx_check(VirtIOSCSI *s, SCSIDevice *d) | ||
95 | } | ||
96 | } | ||
97 | |||
98 | +static void virtio_scsi_do_one_tmf_bh(VirtIOSCSIReq *req) | ||
99 | +{ | ||
100 | + VirtIOSCSI *s = req->dev; | ||
101 | + SCSIDevice *d = virtio_scsi_device_get(s, req->req.tmf.lun); | ||
102 | + BusChild *kid; | ||
103 | + int target; | ||
104 | + | ||
105 | + switch (req->req.tmf.subtype) { | ||
106 | + case VIRTIO_SCSI_T_TMF_LOGICAL_UNIT_RESET: | ||
107 | + if (!d) { | ||
108 | + req->resp.tmf.response = VIRTIO_SCSI_S_BAD_TARGET; | ||
109 | + goto out; | ||
110 | + } | ||
111 | + if (d->lun != virtio_scsi_get_lun(req->req.tmf.lun)) { | ||
112 | + req->resp.tmf.response = VIRTIO_SCSI_S_INCORRECT_LUN; | ||
113 | + goto out; | ||
114 | + } | ||
115 | + qatomic_inc(&s->resetting); | ||
116 | + device_cold_reset(&d->qdev); | ||
117 | + qatomic_dec(&s->resetting); | ||
118 | + break; | ||
119 | + | ||
120 | + case VIRTIO_SCSI_T_TMF_I_T_NEXUS_RESET: | ||
121 | + target = req->req.tmf.lun[1]; | ||
122 | + qatomic_inc(&s->resetting); | ||
123 | + | ||
124 | + rcu_read_lock(); | ||
125 | + QTAILQ_FOREACH_RCU(kid, &s->bus.qbus.children, sibling) { | ||
126 | + SCSIDevice *d1 = SCSI_DEVICE(kid->child); | ||
127 | + if (d1->channel == 0 && d1->id == target) { | ||
128 | + device_cold_reset(&d1->qdev); | ||
129 | + } | ||
130 | + } | ||
131 | + rcu_read_unlock(); | ||
132 | + | ||
133 | + qatomic_dec(&s->resetting); | ||
134 | + break; | ||
135 | + | ||
136 | + default: | ||
137 | + g_assert_not_reached(); | ||
138 | + break; | ||
139 | + } | ||
140 | + | ||
141 | +out: | ||
142 | + object_unref(OBJECT(d)); | ||
143 | + | ||
144 | + virtio_scsi_acquire(s); | ||
145 | + virtio_scsi_complete_req(req); | ||
146 | + virtio_scsi_release(s); | ||
147 | +} | ||
148 | + | ||
149 | +/* Some TMFs must be processed from the main loop thread */ | ||
150 | +static void virtio_scsi_do_tmf_bh(void *opaque) | ||
151 | +{ | ||
152 | + VirtIOSCSI *s = opaque; | ||
153 | + QTAILQ_HEAD(, VirtIOSCSIReq) reqs = QTAILQ_HEAD_INITIALIZER(reqs); | ||
154 | + VirtIOSCSIReq *req; | ||
155 | + VirtIOSCSIReq *tmp; | ||
156 | + | ||
157 | + GLOBAL_STATE_CODE(); | ||
158 | + | ||
159 | + virtio_scsi_acquire(s); | ||
160 | + | ||
161 | + QTAILQ_FOREACH_SAFE(req, &s->tmf_bh_list, next, tmp) { | ||
162 | + QTAILQ_REMOVE(&s->tmf_bh_list, req, next); | ||
163 | + QTAILQ_INSERT_TAIL(&reqs, req, next); | ||
164 | + } | ||
165 | + | ||
166 | + qemu_bh_delete(s->tmf_bh); | ||
167 | + s->tmf_bh = NULL; | ||
168 | + | ||
169 | + virtio_scsi_release(s); | ||
170 | + | ||
171 | + QTAILQ_FOREACH_SAFE(req, &reqs, next, tmp) { | ||
172 | + QTAILQ_REMOVE(&reqs, req, next); | ||
173 | + virtio_scsi_do_one_tmf_bh(req); | ||
174 | + } | ||
175 | +} | ||
176 | + | ||
177 | +static void virtio_scsi_reset_tmf_bh(VirtIOSCSI *s) | ||
178 | +{ | ||
179 | + VirtIOSCSIReq *req; | ||
180 | + VirtIOSCSIReq *tmp; | ||
181 | + | ||
182 | + GLOBAL_STATE_CODE(); | ||
183 | + | ||
184 | + virtio_scsi_acquire(s); | ||
185 | + | ||
186 | + if (s->tmf_bh) { | ||
187 | + qemu_bh_delete(s->tmf_bh); | ||
188 | + s->tmf_bh = NULL; | ||
189 | + } | ||
190 | + | ||
191 | + QTAILQ_FOREACH_SAFE(req, &s->tmf_bh_list, next, tmp) { | ||
192 | + QTAILQ_REMOVE(&s->tmf_bh_list, req, next); | ||
193 | + | ||
194 | + /* SAM-6 6.3.2 Hard reset */ | ||
195 | + req->resp.tmf.response = VIRTIO_SCSI_S_TARGET_FAILURE; | ||
196 | + virtio_scsi_complete_req(req); | ||
197 | + } | ||
198 | + | ||
199 | + virtio_scsi_release(s); | ||
200 | +} | ||
201 | + | ||
202 | +static void virtio_scsi_defer_tmf_to_bh(VirtIOSCSIReq *req) | ||
203 | +{ | ||
204 | + VirtIOSCSI *s = req->dev; | ||
205 | + | ||
206 | + QTAILQ_INSERT_TAIL(&s->tmf_bh_list, req, next); | ||
207 | + | ||
208 | + if (!s->tmf_bh) { | ||
209 | + s->tmf_bh = qemu_bh_new(virtio_scsi_do_tmf_bh, s); | ||
210 | + qemu_bh_schedule(s->tmf_bh); | ||
211 | + } | ||
212 | +} | ||
213 | + | ||
214 | /* Return 0 if the request is ready to be completed and return to guest; | ||
215 | * -EINPROGRESS if the request is submitted and will be completed later, in the | ||
216 | * case of async cancellation. */ | ||
217 | @@ -XXX,XX +XXX,XX @@ static int virtio_scsi_do_tmf(VirtIOSCSI *s, VirtIOSCSIReq *req) | ||
218 | { | ||
219 | SCSIDevice *d = virtio_scsi_device_get(s, req->req.tmf.lun); | ||
220 | SCSIRequest *r, *next; | ||
221 | - BusChild *kid; | ||
222 | - int target; | ||
223 | int ret = 0; | ||
224 | |||
225 | virtio_scsi_ctx_check(s, d); | ||
226 | @@ -XXX,XX +XXX,XX @@ static int virtio_scsi_do_tmf(VirtIOSCSI *s, VirtIOSCSIReq *req) | ||
227 | break; | ||
228 | |||
229 | case VIRTIO_SCSI_T_TMF_LOGICAL_UNIT_RESET: | ||
230 | - if (!d) { | ||
231 | - goto fail; | ||
232 | - } | ||
233 | - if (d->lun != virtio_scsi_get_lun(req->req.tmf.lun)) { | ||
234 | - goto incorrect_lun; | ||
235 | - } | ||
236 | - s->resetting++; | ||
237 | - device_cold_reset(&d->qdev); | ||
238 | - s->resetting--; | ||
239 | + case VIRTIO_SCSI_T_TMF_I_T_NEXUS_RESET: | ||
240 | + virtio_scsi_defer_tmf_to_bh(req); | ||
241 | + ret = -EINPROGRESS; | ||
242 | break; | ||
243 | |||
244 | case VIRTIO_SCSI_T_TMF_ABORT_TASK_SET: | ||
245 | @@ -XXX,XX +XXX,XX @@ static int virtio_scsi_do_tmf(VirtIOSCSI *s, VirtIOSCSIReq *req) | ||
246 | } | ||
247 | break; | ||
248 | |||
249 | - case VIRTIO_SCSI_T_TMF_I_T_NEXUS_RESET: | ||
250 | - target = req->req.tmf.lun[1]; | ||
251 | - s->resetting++; | ||
252 | - | ||
253 | - rcu_read_lock(); | ||
254 | - QTAILQ_FOREACH_RCU(kid, &s->bus.qbus.children, sibling) { | ||
255 | - SCSIDevice *d1 = SCSI_DEVICE(kid->child); | ||
256 | - if (d1->channel == 0 && d1->id == target) { | ||
257 | - device_cold_reset(&d1->qdev); | ||
258 | - } | ||
259 | - } | ||
260 | - rcu_read_unlock(); | ||
261 | - | ||
262 | - s->resetting--; | ||
263 | - break; | ||
264 | - | ||
265 | case VIRTIO_SCSI_T_TMF_CLEAR_ACA: | ||
266 | default: | ||
267 | req->resp.tmf.response = VIRTIO_SCSI_S_FUNCTION_REJECTED; | ||
268 | @@ -XXX,XX +XXX,XX @@ static void virtio_scsi_request_cancelled(SCSIRequest *r) | ||
269 | if (!req) { | ||
270 | return; | ||
271 | } | ||
272 | - if (req->dev->resetting) { | ||
273 | + if (qatomic_read(&req->dev->resetting)) { | ||
274 | req->resp.cmd.response = VIRTIO_SCSI_S_RESET; | ||
275 | } else { | ||
276 | req->resp.cmd.response = VIRTIO_SCSI_S_ABORTED; | ||
277 | @@ -XXX,XX +XXX,XX @@ static void virtio_scsi_reset(VirtIODevice *vdev) | ||
278 | VirtIOSCSICommon *vs = VIRTIO_SCSI_COMMON(vdev); | ||
279 | |||
280 | assert(!s->dataplane_started); | ||
281 | - s->resetting++; | ||
282 | + | ||
283 | + virtio_scsi_reset_tmf_bh(s); | ||
284 | + | ||
285 | + qatomic_inc(&s->resetting); | ||
286 | bus_cold_reset(BUS(&s->bus)); | ||
287 | - s->resetting--; | ||
288 | + qatomic_dec(&s->resetting); | ||
289 | |||
290 | vs->sense_size = VIRTIO_SCSI_SENSE_DEFAULT_SIZE; | ||
291 | vs->cdb_size = VIRTIO_SCSI_CDB_DEFAULT_SIZE; | ||
292 | @@ -XXX,XX +XXX,XX @@ static void virtio_scsi_device_realize(DeviceState *dev, Error **errp) | ||
293 | VirtIOSCSI *s = VIRTIO_SCSI(dev); | ||
294 | Error *err = NULL; | ||
295 | |||
296 | + QTAILQ_INIT(&s->tmf_bh_list); | ||
297 | + | ||
298 | virtio_scsi_common_realize(dev, | ||
299 | virtio_scsi_handle_ctrl, | ||
300 | virtio_scsi_handle_event, | ||
301 | @@ -XXX,XX +XXX,XX @@ static void virtio_scsi_device_unrealize(DeviceState *dev) | ||
302 | { | ||
303 | VirtIOSCSI *s = VIRTIO_SCSI(dev); | ||
304 | |||
305 | + virtio_scsi_reset_tmf_bh(s); | ||
306 | + | ||
307 | qbus_set_hotplug_handler(BUS(&s->bus), NULL); | ||
308 | virtio_scsi_common_unrealize(dev); | ||
309 | } | ||
310 | -- | ||
311 | 2.39.2 | diff view generated by jsdifflib |
Deleted patch | |||
---|---|---|---|
1 | From: Or Ozeri <oro@il.ibm.com> | ||
2 | 1 | ||
3 | Signed-off-by: Or Ozeri <oro@il.ibm.com> | ||
4 | Message-Id: <20230129113120.722708-2-oro@oro.sl.cloud9.ibm.com> | ||
5 | Reviewed-by: Ilya Dryomov <idryomov@gmail.com> | ||
6 | Reviewed-by: Kevin Wolf <kwolf@redhat.com> | ||
7 | Signed-off-by: Kevin Wolf <kwolf@redhat.com> | ||
8 | --- | ||
9 | block/rbd.c | 16 ++++++---------- | ||
10 | 1 file changed, 6 insertions(+), 10 deletions(-) | ||
11 | |||
12 | diff --git a/block/rbd.c b/block/rbd.c | ||
13 | index XXXXXXX..XXXXXXX 100644 | ||
14 | --- a/block/rbd.c | ||
15 | +++ b/block/rbd.c | ||
16 | @@ -XXX,XX +XXX,XX @@ static int qemu_rbd_encryption_format(rbd_image_t image, | ||
17 | { | ||
18 | int r = 0; | ||
19 | g_autofree char *passphrase = NULL; | ||
20 | - size_t passphrase_len; | ||
21 | rbd_encryption_format_t format; | ||
22 | rbd_encryption_options_t opts; | ||
23 | rbd_encryption_luks1_format_options_t luks_opts; | ||
24 | @@ -XXX,XX +XXX,XX @@ static int qemu_rbd_encryption_format(rbd_image_t image, | ||
25 | opts_size = sizeof(luks_opts); | ||
26 | r = qemu_rbd_convert_luks_create_options( | ||
27 | qapi_RbdEncryptionCreateOptionsLUKS_base(&encrypt->u.luks), | ||
28 | - &luks_opts.alg, &passphrase, &passphrase_len, errp); | ||
29 | + &luks_opts.alg, &passphrase, &luks_opts.passphrase_size, | ||
30 | + errp); | ||
31 | if (r < 0) { | ||
32 | return r; | ||
33 | } | ||
34 | luks_opts.passphrase = passphrase; | ||
35 | - luks_opts.passphrase_size = passphrase_len; | ||
36 | break; | ||
37 | } | ||
38 | case RBD_IMAGE_ENCRYPTION_FORMAT_LUKS2: { | ||
39 | @@ -XXX,XX +XXX,XX @@ static int qemu_rbd_encryption_format(rbd_image_t image, | ||
40 | r = qemu_rbd_convert_luks_create_options( | ||
41 | qapi_RbdEncryptionCreateOptionsLUKS2_base( | ||
42 | &encrypt->u.luks2), | ||
43 | - &luks2_opts.alg, &passphrase, &passphrase_len, errp); | ||
44 | + &luks2_opts.alg, &passphrase, &luks2_opts.passphrase_size, | ||
45 | + errp); | ||
46 | if (r < 0) { | ||
47 | return r; | ||
48 | } | ||
49 | luks2_opts.passphrase = passphrase; | ||
50 | - luks2_opts.passphrase_size = passphrase_len; | ||
51 | break; | ||
52 | } | ||
53 | default: { | ||
54 | @@ -XXX,XX +XXX,XX @@ static int qemu_rbd_encryption_load(rbd_image_t image, | ||
55 | { | ||
56 | int r = 0; | ||
57 | g_autofree char *passphrase = NULL; | ||
58 | - size_t passphrase_len; | ||
59 | rbd_encryption_luks1_format_options_t luks_opts; | ||
60 | rbd_encryption_luks2_format_options_t luks2_opts; | ||
61 | rbd_encryption_format_t format; | ||
62 | @@ -XXX,XX +XXX,XX @@ static int qemu_rbd_encryption_load(rbd_image_t image, | ||
63 | opts_size = sizeof(luks_opts); | ||
64 | r = qemu_rbd_convert_luks_options( | ||
65 | qapi_RbdEncryptionOptionsLUKS_base(&encrypt->u.luks), | ||
66 | - &passphrase, &passphrase_len, errp); | ||
67 | + &passphrase, &luks_opts.passphrase_size, errp); | ||
68 | if (r < 0) { | ||
69 | return r; | ||
70 | } | ||
71 | luks_opts.passphrase = passphrase; | ||
72 | - luks_opts.passphrase_size = passphrase_len; | ||
73 | break; | ||
74 | } | ||
75 | case RBD_IMAGE_ENCRYPTION_FORMAT_LUKS2: { | ||
76 | @@ -XXX,XX +XXX,XX @@ static int qemu_rbd_encryption_load(rbd_image_t image, | ||
77 | opts_size = sizeof(luks2_opts); | ||
78 | r = qemu_rbd_convert_luks_options( | ||
79 | qapi_RbdEncryptionOptionsLUKS2_base(&encrypt->u.luks2), | ||
80 | - &passphrase, &passphrase_len, errp); | ||
81 | + &passphrase, &luks2_opts.passphrase_size, errp); | ||
82 | if (r < 0) { | ||
83 | return r; | ||
84 | } | ||
85 | luks2_opts.passphrase = passphrase; | ||
86 | - luks2_opts.passphrase_size = passphrase_len; | ||
87 | break; | ||
88 | } | ||
89 | default: { | ||
90 | -- | ||
91 | 2.39.2 | diff view generated by jsdifflib |
Deleted patch | |||
---|---|---|---|
1 | From: Or Ozeri <oro@il.ibm.com> | ||
2 | 1 | ||
3 | Ceph RBD encryption API required specifying the encryption format | ||
4 | for loading encryption. The supported formats were LUKS (v1) and LUKS2. | ||
5 | |||
6 | Starting from Reef release, RBD also supports loading with "luks-any" format, | ||
7 | which works for both versions of LUKS. | ||
8 | |||
9 | This commit extends the qemu rbd driver API to enable qemu users to use | ||
10 | this luks-any wildcard format. | ||
11 | |||
12 | Signed-off-by: Or Ozeri <oro@il.ibm.com> | ||
13 | Message-Id: <20230129113120.722708-3-oro@oro.sl.cloud9.ibm.com> | ||
14 | Reviewed-by: Ilya Dryomov <idryomov@gmail.com> | ||
15 | Reviewed-by: Kevin Wolf <kwolf@redhat.com> | ||
16 | Signed-off-by: Kevin Wolf <kwolf@redhat.com> | ||
17 | --- | ||
18 | qapi/block-core.json | 16 ++++++++++++++-- | ||
19 | block/rbd.c | 19 +++++++++++++++++++ | ||
20 | 2 files changed, 33 insertions(+), 2 deletions(-) | ||
21 | |||
22 | diff --git a/qapi/block-core.json b/qapi/block-core.json | ||
23 | index XXXXXXX..XXXXXXX 100644 | ||
24 | --- a/qapi/block-core.json | ||
25 | +++ b/qapi/block-core.json | ||
26 | @@ -XXX,XX +XXX,XX @@ | ||
27 | ## | ||
28 | # @RbdImageEncryptionFormat: | ||
29 | # | ||
30 | +# @luks-any: Used for opening either luks or luks2 (Since 8.0) | ||
31 | +# | ||
32 | # Since: 6.1 | ||
33 | ## | ||
34 | { 'enum': 'RbdImageEncryptionFormat', | ||
35 | - 'data': [ 'luks', 'luks2' ] } | ||
36 | + 'data': [ 'luks', 'luks2', 'luks-any' ] } | ||
37 | |||
38 | ## | ||
39 | # @RbdEncryptionOptionsLUKSBase: | ||
40 | @@ -XXX,XX +XXX,XX @@ | ||
41 | 'base': 'RbdEncryptionOptionsLUKSBase', | ||
42 | 'data': { } } | ||
43 | |||
44 | +## | ||
45 | +# @RbdEncryptionOptionsLUKSAny: | ||
46 | +# | ||
47 | +# Since: 8.0 | ||
48 | +## | ||
49 | +{ 'struct': 'RbdEncryptionOptionsLUKSAny', | ||
50 | + 'base': 'RbdEncryptionOptionsLUKSBase', | ||
51 | + 'data': { } } | ||
52 | + | ||
53 | ## | ||
54 | # @RbdEncryptionCreateOptionsLUKS: | ||
55 | # | ||
56 | @@ -XXX,XX +XXX,XX @@ | ||
57 | 'base': { 'format': 'RbdImageEncryptionFormat' }, | ||
58 | 'discriminator': 'format', | ||
59 | 'data': { 'luks': 'RbdEncryptionOptionsLUKS', | ||
60 | - 'luks2': 'RbdEncryptionOptionsLUKS2' } } | ||
61 | + 'luks2': 'RbdEncryptionOptionsLUKS2', | ||
62 | + 'luks-any': 'RbdEncryptionOptionsLUKSAny'} } | ||
63 | |||
64 | ## | ||
65 | # @RbdEncryptionCreateOptions: | ||
66 | diff --git a/block/rbd.c b/block/rbd.c | ||
67 | index XXXXXXX..XXXXXXX 100644 | ||
68 | --- a/block/rbd.c | ||
69 | +++ b/block/rbd.c | ||
70 | @@ -XXX,XX +XXX,XX @@ static int qemu_rbd_encryption_load(rbd_image_t image, | ||
71 | g_autofree char *passphrase = NULL; | ||
72 | rbd_encryption_luks1_format_options_t luks_opts; | ||
73 | rbd_encryption_luks2_format_options_t luks2_opts; | ||
74 | +#ifdef LIBRBD_SUPPORTS_ENCRYPTION_LOAD2 | ||
75 | + rbd_encryption_luks_format_options_t luks_any_opts; | ||
76 | +#endif | ||
77 | rbd_encryption_format_t format; | ||
78 | rbd_encryption_options_t opts; | ||
79 | size_t opts_size; | ||
80 | @@ -XXX,XX +XXX,XX @@ static int qemu_rbd_encryption_load(rbd_image_t image, | ||
81 | luks2_opts.passphrase = passphrase; | ||
82 | break; | ||
83 | } | ||
84 | +#ifdef LIBRBD_SUPPORTS_ENCRYPTION_LOAD2 | ||
85 | + case RBD_IMAGE_ENCRYPTION_FORMAT_LUKS_ANY: { | ||
86 | + memset(&luks_any_opts, 0, sizeof(luks_any_opts)); | ||
87 | + format = RBD_ENCRYPTION_FORMAT_LUKS; | ||
88 | + opts = &luks_any_opts; | ||
89 | + opts_size = sizeof(luks_any_opts); | ||
90 | + r = qemu_rbd_convert_luks_options( | ||
91 | + qapi_RbdEncryptionOptionsLUKSAny_base(&encrypt->u.luks_any), | ||
92 | + &passphrase, &luks_any_opts.passphrase_size, errp); | ||
93 | + if (r < 0) { | ||
94 | + return r; | ||
95 | + } | ||
96 | + luks_any_opts.passphrase = passphrase; | ||
97 | + break; | ||
98 | + } | ||
99 | +#endif | ||
100 | default: { | ||
101 | r = -ENOTSUP; | ||
102 | error_setg_errno( | ||
103 | -- | ||
104 | 2.39.2 | diff view generated by jsdifflib |
Deleted patch | |||
---|---|---|---|
1 | From: Or Ozeri <oro@il.ibm.com> | ||
2 | 1 | ||
3 | Starting from ceph Reef, RBD has built-in support for layered encryption, | ||
4 | where each ancestor image (in a cloned image setting) can be possibly | ||
5 | encrypted using a unique passphrase. | ||
6 | |||
7 | A new function, rbd_encryption_load2, was added to librbd API. | ||
8 | This new function supports an array of passphrases (via "spec" structs). | ||
9 | |||
10 | This commit extends the qemu rbd driver API to use this new librbd API, | ||
11 | in order to support this new layered encryption feature. | ||
12 | |||
13 | Signed-off-by: Or Ozeri <oro@il.ibm.com> | ||
14 | Message-Id: <20230129113120.722708-4-oro@oro.sl.cloud9.ibm.com> | ||
15 | Reviewed-by: Ilya Dryomov <idryomov@gmail.com> | ||
16 | Reviewed-by: Kevin Wolf <kwolf@redhat.com> | ||
17 | Signed-off-by: Kevin Wolf <kwolf@redhat.com> | ||
18 | --- | ||
19 | qapi/block-core.json | 11 +++- | ||
20 | block/rbd.c | 153 ++++++++++++++++++++++++++++++++++++++++++- | ||
21 | 2 files changed, 162 insertions(+), 2 deletions(-) | ||
22 | |||
23 | diff --git a/qapi/block-core.json b/qapi/block-core.json | ||
24 | index XXXXXXX..XXXXXXX 100644 | ||
25 | --- a/qapi/block-core.json | ||
26 | +++ b/qapi/block-core.json | ||
27 | @@ -XXX,XX +XXX,XX @@ | ||
28 | ## | ||
29 | # @RbdEncryptionOptions: | ||
30 | # | ||
31 | +# @format: Encryption format. | ||
32 | +# | ||
33 | +# @parent: Parent image encryption options (for cloned images). | ||
34 | +# Can be left unspecified if this cloned image is encrypted | ||
35 | +# using the same format and secret as its parent image (i.e. | ||
36 | +# not explicitly formatted) or if its parent image is not | ||
37 | +# encrypted. (Since 8.0) | ||
38 | +# | ||
39 | # Since: 6.1 | ||
40 | ## | ||
41 | { 'union': 'RbdEncryptionOptions', | ||
42 | - 'base': { 'format': 'RbdImageEncryptionFormat' }, | ||
43 | + 'base': { 'format': 'RbdImageEncryptionFormat', | ||
44 | + '*parent': 'RbdEncryptionOptions' }, | ||
45 | 'discriminator': 'format', | ||
46 | 'data': { 'luks': 'RbdEncryptionOptionsLUKS', | ||
47 | 'luks2': 'RbdEncryptionOptionsLUKS2', | ||
48 | diff --git a/block/rbd.c b/block/rbd.c | ||
49 | index XXXXXXX..XXXXXXX 100644 | ||
50 | --- a/block/rbd.c | ||
51 | +++ b/block/rbd.c | ||
52 | @@ -XXX,XX +XXX,XX @@ static const char rbd_luks2_header_verification[ | ||
53 | 'L', 'U', 'K', 'S', 0xBA, 0xBE, 0, 2 | ||
54 | }; | ||
55 | |||
56 | +static const char rbd_layered_luks_header_verification[ | ||
57 | + RBD_ENCRYPTION_LUKS_HEADER_VERIFICATION_LEN] = { | ||
58 | + 'R', 'B', 'D', 'L', 0xBA, 0xBE, 0, 1 | ||
59 | +}; | ||
60 | + | ||
61 | +static const char rbd_layered_luks2_header_verification[ | ||
62 | + RBD_ENCRYPTION_LUKS_HEADER_VERIFICATION_LEN] = { | ||
63 | + 'R', 'B', 'D', 'L', 0xBA, 0xBE, 0, 2 | ||
64 | +}; | ||
65 | + | ||
66 | typedef enum { | ||
67 | RBD_AIO_READ, | ||
68 | RBD_AIO_WRITE, | ||
69 | @@ -XXX,XX +XXX,XX @@ static int qemu_rbd_encryption_load(rbd_image_t image, | ||
70 | |||
71 | return 0; | ||
72 | } | ||
73 | + | ||
74 | +#ifdef LIBRBD_SUPPORTS_ENCRYPTION_LOAD2 | ||
75 | +static int qemu_rbd_encryption_load2(rbd_image_t image, | ||
76 | + RbdEncryptionOptions *encrypt, | ||
77 | + Error **errp) | ||
78 | +{ | ||
79 | + int r = 0; | ||
80 | + int encrypt_count = 1; | ||
81 | + int i; | ||
82 | + RbdEncryptionOptions *curr_encrypt; | ||
83 | + rbd_encryption_spec_t *specs; | ||
84 | + rbd_encryption_luks1_format_options_t *luks_opts; | ||
85 | + rbd_encryption_luks2_format_options_t *luks2_opts; | ||
86 | + rbd_encryption_luks_format_options_t *luks_any_opts; | ||
87 | + | ||
88 | + /* count encryption options */ | ||
89 | + for (curr_encrypt = encrypt->parent; curr_encrypt; | ||
90 | + curr_encrypt = curr_encrypt->parent) { | ||
91 | + ++encrypt_count; | ||
92 | + } | ||
93 | + | ||
94 | + specs = g_new0(rbd_encryption_spec_t, encrypt_count); | ||
95 | + | ||
96 | + curr_encrypt = encrypt; | ||
97 | + for (i = 0; i < encrypt_count; ++i) { | ||
98 | + switch (curr_encrypt->format) { | ||
99 | + case RBD_IMAGE_ENCRYPTION_FORMAT_LUKS: { | ||
100 | + specs[i].format = RBD_ENCRYPTION_FORMAT_LUKS1; | ||
101 | + | ||
102 | + luks_opts = g_new0(rbd_encryption_luks1_format_options_t, 1); | ||
103 | + specs[i].opts = luks_opts; | ||
104 | + specs[i].opts_size = sizeof(*luks_opts); | ||
105 | + | ||
106 | + r = qemu_rbd_convert_luks_options( | ||
107 | + qapi_RbdEncryptionOptionsLUKS_base( | ||
108 | + &curr_encrypt->u.luks), | ||
109 | + (char **)&luks_opts->passphrase, | ||
110 | + &luks_opts->passphrase_size, | ||
111 | + errp); | ||
112 | + break; | ||
113 | + } | ||
114 | + case RBD_IMAGE_ENCRYPTION_FORMAT_LUKS2: { | ||
115 | + specs[i].format = RBD_ENCRYPTION_FORMAT_LUKS2; | ||
116 | + | ||
117 | + luks2_opts = g_new0(rbd_encryption_luks2_format_options_t, 1); | ||
118 | + specs[i].opts = luks2_opts; | ||
119 | + specs[i].opts_size = sizeof(*luks2_opts); | ||
120 | + | ||
121 | + r = qemu_rbd_convert_luks_options( | ||
122 | + qapi_RbdEncryptionOptionsLUKS2_base( | ||
123 | + &curr_encrypt->u.luks2), | ||
124 | + (char **)&luks2_opts->passphrase, | ||
125 | + &luks2_opts->passphrase_size, | ||
126 | + errp); | ||
127 | + break; | ||
128 | + } | ||
129 | + case RBD_IMAGE_ENCRYPTION_FORMAT_LUKS_ANY: { | ||
130 | + specs[i].format = RBD_ENCRYPTION_FORMAT_LUKS; | ||
131 | + | ||
132 | + luks_any_opts = g_new0(rbd_encryption_luks_format_options_t, 1); | ||
133 | + specs[i].opts = luks_any_opts; | ||
134 | + specs[i].opts_size = sizeof(*luks_any_opts); | ||
135 | + | ||
136 | + r = qemu_rbd_convert_luks_options( | ||
137 | + qapi_RbdEncryptionOptionsLUKSAny_base( | ||
138 | + &curr_encrypt->u.luks_any), | ||
139 | + (char **)&luks_any_opts->passphrase, | ||
140 | + &luks_any_opts->passphrase_size, | ||
141 | + errp); | ||
142 | + break; | ||
143 | + } | ||
144 | + default: { | ||
145 | + r = -ENOTSUP; | ||
146 | + error_setg_errno( | ||
147 | + errp, -r, "unknown image encryption format: %u", | ||
148 | + curr_encrypt->format); | ||
149 | + } | ||
150 | + } | ||
151 | + | ||
152 | + if (r < 0) { | ||
153 | + goto exit; | ||
154 | + } | ||
155 | + | ||
156 | + curr_encrypt = curr_encrypt->parent; | ||
157 | + } | ||
158 | + | ||
159 | + r = rbd_encryption_load2(image, specs, encrypt_count); | ||
160 | + if (r < 0) { | ||
161 | + error_setg_errno(errp, -r, "layered encryption load fail"); | ||
162 | + goto exit; | ||
163 | + } | ||
164 | + | ||
165 | +exit: | ||
166 | + for (i = 0; i < encrypt_count; ++i) { | ||
167 | + if (!specs[i].opts) { | ||
168 | + break; | ||
169 | + } | ||
170 | + | ||
171 | + switch (specs[i].format) { | ||
172 | + case RBD_ENCRYPTION_FORMAT_LUKS1: { | ||
173 | + luks_opts = specs[i].opts; | ||
174 | + g_free((void *)luks_opts->passphrase); | ||
175 | + break; | ||
176 | + } | ||
177 | + case RBD_ENCRYPTION_FORMAT_LUKS2: { | ||
178 | + luks2_opts = specs[i].opts; | ||
179 | + g_free((void *)luks2_opts->passphrase); | ||
180 | + break; | ||
181 | + } | ||
182 | + case RBD_ENCRYPTION_FORMAT_LUKS: { | ||
183 | + luks_any_opts = specs[i].opts; | ||
184 | + g_free((void *)luks_any_opts->passphrase); | ||
185 | + break; | ||
186 | + } | ||
187 | + } | ||
188 | + | ||
189 | + g_free(specs[i].opts); | ||
190 | + } | ||
191 | + g_free(specs); | ||
192 | + return r; | ||
193 | +} | ||
194 | +#endif | ||
195 | #endif | ||
196 | |||
197 | /* FIXME Deprecate and remove keypairs or make it available in QMP. */ | ||
198 | @@ -XXX,XX +XXX,XX @@ static int qemu_rbd_open(BlockDriverState *bs, QDict *options, int flags, | ||
199 | |||
200 | if (opts->encrypt) { | ||
201 | #ifdef LIBRBD_SUPPORTS_ENCRYPTION | ||
202 | - r = qemu_rbd_encryption_load(s->image, opts->encrypt, errp); | ||
203 | + if (opts->encrypt->parent) { | ||
204 | +#ifdef LIBRBD_SUPPORTS_ENCRYPTION_LOAD2 | ||
205 | + r = qemu_rbd_encryption_load2(s->image, opts->encrypt, errp); | ||
206 | +#else | ||
207 | + r = -ENOTSUP; | ||
208 | + error_setg(errp, "RBD library does not support layered encryption"); | ||
209 | +#endif | ||
210 | + } else { | ||
211 | + r = qemu_rbd_encryption_load(s->image, opts->encrypt, errp); | ||
212 | + } | ||
213 | if (r < 0) { | ||
214 | goto failed_post_open; | ||
215 | } | ||
216 | @@ -XXX,XX +XXX,XX @@ static ImageInfoSpecific *qemu_rbd_get_specific_info(BlockDriverState *bs, | ||
217 | spec_info->u.rbd.data->encryption_format = | ||
218 | RBD_IMAGE_ENCRYPTION_FORMAT_LUKS2; | ||
219 | spec_info->u.rbd.data->has_encryption_format = true; | ||
220 | + } else if (memcmp(buf, rbd_layered_luks_header_verification, | ||
221 | + RBD_ENCRYPTION_LUKS_HEADER_VERIFICATION_LEN) == 0) { | ||
222 | + spec_info->u.rbd.data->encryption_format = | ||
223 | + RBD_IMAGE_ENCRYPTION_FORMAT_LUKS; | ||
224 | + spec_info->u.rbd.data->has_encryption_format = true; | ||
225 | + } else if (memcmp(buf, rbd_layered_luks2_header_verification, | ||
226 | + RBD_ENCRYPTION_LUKS_HEADER_VERIFICATION_LEN) == 0) { | ||
227 | + spec_info->u.rbd.data->encryption_format = | ||
228 | + RBD_IMAGE_ENCRYPTION_FORMAT_LUKS2; | ||
229 | + spec_info->u.rbd.data->has_encryption_format = true; | ||
230 | } else { | ||
231 | spec_info->u.rbd.data->has_encryption_format = false; | ||
232 | } | ||
233 | -- | ||
234 | 2.39.2 | diff view generated by jsdifflib |