Skip to content

Commit

Permalink
Merge tag 'for-upstream' of https://repo.or.cz/qemu/kevin into staging
Browse files Browse the repository at this point in the history
Block layer patches

- Graph locking part 6 (bs->file/backing)
- ahci: trigger either error IRQ or regular IRQ, not both

# -----BEGIN PGP SIGNATURE-----
#
# iQJFBAABCAAvFiEE3D3rFZqa+V09dFb+fwmycsiPL9YFAmVKhboRHGt3b2xmQHJl
# ZGhhdC5jb20ACgkQfwmycsiPL9auSxAAhF83zziu2cT2wTKWEJSsg/Obf/DuUsv4
# qIsxEQA5hVPIkkSALlrD8nixwzkg53qrTlZuR+JmSi/59VpOl/bhOUNA17bS1XFz
# 7hsIrZTYlnMFw5U7DLSPCL4nq0g7r/adVNFhdwJp3ESWYHAX8hgVWEcppEG5AmHL
# VuM4CTqoohMUyB4XB0PStt3UAN/VKxGzV9YQdO2hSn03yH+Al3BQKLaR4DEuLLXJ
# W226KdX7N57UPz7kUF6uArBzxsf8gpp/IAgxQwebosODKH3z6iGCh1QCV8WP2rmP
# eHBJxWSWk5Ig3+OIHc1gNXEDsy19PTa8z9cPWIqyGlbMtZFstdWxl0hSalXOXUaw
# zsZLYNotn4/vlLQiwmgkGGKHWpBhlhCadgtBUvP9PiiMSRLjoNtbkb5Fl6Ofpu1/
# GDDgxKwZmsu7tsru33MZO1l+J1xMb0r07FvlIgtaBPQNkHxMqQl2Aid5ra0u2Ec/
# R4eluakxAV7VaxvQO0dy5QcejWAaJwWdEdlIxMqJPQIXAuuoYI+ySs4MDs0cpyTJ
# jd/02ah96i1Worrf1s7VH3qDB1pXs2uMMJbmO7RGVT/tjBxiSvXC58/qjCFhMYf0
# e7xp7rXs6nprGKYST+1Yp1Yk3MeNuK4YQLfPJ4pfFGPDGzQKIJdVJNstVYuVmIdy
# h2qOilgSm/M=
# =GOHe
# -----END PGP SIGNATURE-----
# gpg: Signature made Wed 08 Nov 2023 02:45:14 HKT
# gpg:                using RSA key DC3DEB159A9AF95D3D7456FE7F09B272C88F2FD6
# gpg:                issuer "kwolf@redhat.com"
# gpg: Good signature from "Kevin Wolf <kwolf@redhat.com>" [full]
# Primary key fingerprint: DC3D EB15 9A9A F95D 3D74  56FE 7F09 B272 C88F 2FD6

* tag 'for-upstream' of https://repo.or.cz/qemu/kevin: (25 commits)
  hw/ide/ahci: trigger either error IRQ or regular IRQ, not both
  block: Protect bs->file with graph_lock
  block: Take graph lock for most of .bdrv_open
  vhdx: Take locks for accessing bs->file
  qcow2: Take locks for accessing bs->file
  block: Add missing GRAPH_RDLOCK annotations
  block: Introduce bdrv_co_change_backing_file()
  blkverify: Add locking for request_fn
  block: Protect bs->backing with graph_lock
  block: Mark bdrv_replace_node() GRAPH_WRLOCK
  block: Mark bdrv_replace_node_common() GRAPH_WRLOCK
  block: Inline bdrv_set_backing_noperm()
  block: Mark bdrv_set_backing_hd_drained() GRAPH_WRLOCK
  block: Mark bdrv_cow_child() and callers GRAPH_RDLOCK
  block: Mark bdrv_filter_child() and callers GRAPH_RDLOCK
  block: Mark bdrv_chain_contains() and callers GRAPH_RDLOCK
  block: Mark bdrv_(un)freeze_backing_chain() and callers GRAPH_RDLOCK
  block: Mark bdrv_skip_filters() and callers GRAPH_RDLOCK
  block: Mark bdrv_skip_implicit_filters() and callers GRAPH_RDLOCK
  block: Mark bdrv_filter_or_cow_bs() and callers GRAPH_RDLOCK
  ...

Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
  • Loading branch information
stefanhaRH committed Nov 8, 2023
2 parents a1efea8 + 5d4a508 commit 14e27e3
Show file tree
Hide file tree
Showing 56 changed files with 923 additions and 527 deletions.
192 changes: 110 additions & 82 deletions block.c

Large diffs are not rendered by default.

21 changes: 15 additions & 6 deletions block/backup.c
Original file line number Diff line number Diff line change
Expand Up @@ -374,7 +374,6 @@ BlockJob *backup_job_create(const char *job_id, BlockDriverState *bs,
assert(bs);
assert(target);
GLOBAL_STATE_CODE();
GRAPH_RDLOCK_GUARD_MAINLOOP();

/* QMP interface protects us from these cases */
assert(sync_mode != MIRROR_SYNC_MODE_INCREMENTAL);
Expand All @@ -385,31 +384,33 @@ BlockJob *backup_job_create(const char *job_id, BlockDriverState *bs,
return NULL;
}

bdrv_graph_rdlock_main_loop();
if (!bdrv_is_inserted(bs)) {
error_setg(errp, "Device is not inserted: %s",
bdrv_get_device_name(bs));
return NULL;
goto error_rdlock;
}

if (!bdrv_is_inserted(target)) {
error_setg(errp, "Device is not inserted: %s",
bdrv_get_device_name(target));
return NULL;
goto error_rdlock;
}

if (compress && !bdrv_supports_compressed_writes(target)) {
error_setg(errp, "Compression is not supported for this drive %s",
bdrv_get_device_name(target));
return NULL;
goto error_rdlock;
}

if (bdrv_op_is_blocked(bs, BLOCK_OP_TYPE_BACKUP_SOURCE, errp)) {
return NULL;
goto error_rdlock;
}

if (bdrv_op_is_blocked(target, BLOCK_OP_TYPE_BACKUP_TARGET, errp)) {
return NULL;
goto error_rdlock;
}
bdrv_graph_rdunlock_main_loop();

if (perf->max_workers < 1 || perf->max_workers > INT_MAX) {
error_setg(errp, "max-workers must be between 1 and %d", INT_MAX);
Expand Down Expand Up @@ -437,13 +438,15 @@ BlockJob *backup_job_create(const char *job_id, BlockDriverState *bs,

len = bdrv_getlength(bs);
if (len < 0) {
GRAPH_RDLOCK_GUARD_MAINLOOP();
error_setg_errno(errp, -len, "Unable to get length for '%s'",
bdrv_get_device_or_node_name(bs));
goto error;
}

target_len = bdrv_getlength(target);
if (target_len < 0) {
GRAPH_RDLOCK_GUARD_MAINLOOP();
error_setg_errno(errp, -target_len, "Unable to get length for '%s'",
bdrv_get_device_or_node_name(bs));
goto error;
Expand Down Expand Up @@ -493,8 +496,10 @@ BlockJob *backup_job_create(const char *job_id, BlockDriverState *bs,
block_copy_set_speed(bcs, speed);

/* Required permissions are taken by copy-before-write filter target */
bdrv_graph_wrlock(target);
block_job_add_bdrv(&job->common, "target", target, 0, BLK_PERM_ALL,
&error_abort);
bdrv_graph_wrunlock();

return &job->common;

Expand All @@ -507,4 +512,8 @@ BlockJob *backup_job_create(const char *job_id, BlockDriverState *bs,
}

return NULL;

error_rdlock:
bdrv_graph_rdunlock_main_loop();
return NULL;
}
29 changes: 15 additions & 14 deletions block/blkdebug.c
Original file line number Diff line number Diff line change
Expand Up @@ -508,6 +508,8 @@ static int blkdebug_open(BlockDriverState *bs, QDict *options, int flags,
goto out;
}

bdrv_graph_rdlock_main_loop();

bs->supported_write_flags = BDRV_REQ_WRITE_UNCHANGED |
(BDRV_REQ_FUA & bs->file->bs->supported_write_flags);
bs->supported_zero_flags = BDRV_REQ_WRITE_UNCHANGED |
Expand All @@ -520,7 +522,7 @@ static int blkdebug_open(BlockDriverState *bs, QDict *options, int flags,
if (s->align && (s->align >= INT_MAX || !is_power_of_2(s->align))) {
error_setg(errp, "Cannot meet constraints with align %" PRIu64,
s->align);
goto out;
goto out_rdlock;
}
align = MAX(s->align, bs->file->bs->bl.request_alignment);

Expand All @@ -530,7 +532,7 @@ static int blkdebug_open(BlockDriverState *bs, QDict *options, int flags,
!QEMU_IS_ALIGNED(s->max_transfer, align))) {
error_setg(errp, "Cannot meet constraints with max-transfer %" PRIu64,
s->max_transfer);
goto out;
goto out_rdlock;
}

s->opt_write_zero = qemu_opt_get_size(opts, "opt-write-zero", 0);
Expand All @@ -539,7 +541,7 @@ static int blkdebug_open(BlockDriverState *bs, QDict *options, int flags,
!QEMU_IS_ALIGNED(s->opt_write_zero, align))) {
error_setg(errp, "Cannot meet constraints with opt-write-zero %" PRIu64,
s->opt_write_zero);
goto out;
goto out_rdlock;
}

s->max_write_zero = qemu_opt_get_size(opts, "max-write-zero", 0);
Expand All @@ -549,7 +551,7 @@ static int blkdebug_open(BlockDriverState *bs, QDict *options, int flags,
MAX(s->opt_write_zero, align)))) {
error_setg(errp, "Cannot meet constraints with max-write-zero %" PRIu64,
s->max_write_zero);
goto out;
goto out_rdlock;
}

s->opt_discard = qemu_opt_get_size(opts, "opt-discard", 0);
Expand All @@ -558,7 +560,7 @@ static int blkdebug_open(BlockDriverState *bs, QDict *options, int flags,
!QEMU_IS_ALIGNED(s->opt_discard, align))) {
error_setg(errp, "Cannot meet constraints with opt-discard %" PRIu64,
s->opt_discard);
goto out;
goto out_rdlock;
}

s->max_discard = qemu_opt_get_size(opts, "max-discard", 0);
Expand All @@ -568,12 +570,14 @@ static int blkdebug_open(BlockDriverState *bs, QDict *options, int flags,
MAX(s->opt_discard, align)))) {
error_setg(errp, "Cannot meet constraints with max-discard %" PRIu64,
s->max_discard);
goto out;
goto out_rdlock;
}

bdrv_debug_event(bs, BLKDBG_NONE);

ret = 0;
out_rdlock:
bdrv_graph_rdunlock_main_loop();
out:
if (ret < 0) {
qemu_mutex_destroy(&s->lock);
Expand Down Expand Up @@ -746,13 +750,10 @@ blkdebug_co_pdiscard(BlockDriverState *bs, int64_t offset, int64_t bytes)
return bdrv_co_pdiscard(bs->file, offset, bytes);
}

static int coroutine_fn blkdebug_co_block_status(BlockDriverState *bs,
bool want_zero,
int64_t offset,
int64_t bytes,
int64_t *pnum,
int64_t *map,
BlockDriverState **file)
static int coroutine_fn GRAPH_RDLOCK
blkdebug_co_block_status(BlockDriverState *bs, bool want_zero, int64_t offset,
int64_t bytes, int64_t *pnum, int64_t *map,
BlockDriverState **file)
{
int err;

Expand Down Expand Up @@ -973,7 +974,7 @@ blkdebug_co_getlength(BlockDriverState *bs)
return bdrv_co_getlength(bs->file->bs);
}

static void blkdebug_refresh_filename(BlockDriverState *bs)
static void GRAPH_RDLOCK blkdebug_refresh_filename(BlockDriverState *bs)
{
BDRVBlkdebugState *s = bs->opaque;
const QDictEntry *e;
Expand Down
8 changes: 7 additions & 1 deletion block/blkreplay.c
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,13 @@ static int coroutine_fn GRAPH_RDLOCK blkreplay_co_flush(BlockDriverState *bs)
static int blkreplay_snapshot_goto(BlockDriverState *bs,
const char *snapshot_id)
{
return bdrv_snapshot_goto(bs->file->bs, snapshot_id, NULL);
BlockDriverState *file_bs;

bdrv_graph_rdlock_main_loop();
file_bs = bs->file->bs;
bdrv_graph_rdunlock_main_loop();

return bdrv_snapshot_goto(file_bs, snapshot_id, NULL);
}

static BlockDriver bdrv_blkreplay = {
Expand Down
18 changes: 12 additions & 6 deletions block/blkverify.c
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,8 @@ typedef struct BlkverifyRequest {
uint64_t bytes;
int flags;

int (*request_fn)(BdrvChild *, int64_t, int64_t, QEMUIOVector *,
BdrvRequestFlags);
int GRAPH_RDLOCK_PTR (*request_fn)(
BdrvChild *, int64_t, int64_t, QEMUIOVector *, BdrvRequestFlags);

int ret; /* test image result */
int raw_ret; /* raw image result */
Expand Down Expand Up @@ -170,8 +170,11 @@ static void coroutine_fn blkverify_do_test_req(void *opaque)
BlkverifyRequest *r = opaque;
BDRVBlkverifyState *s = r->bs->opaque;

bdrv_graph_co_rdlock();
r->ret = r->request_fn(s->test_file, r->offset, r->bytes, r->qiov,
r->flags);
bdrv_graph_co_rdunlock();

r->done++;
qemu_coroutine_enter_if_inactive(r->co);
}
Expand All @@ -180,13 +183,16 @@ static void coroutine_fn blkverify_do_raw_req(void *opaque)
{
BlkverifyRequest *r = opaque;

bdrv_graph_co_rdlock();
r->raw_ret = r->request_fn(r->bs->file, r->offset, r->bytes, r->raw_qiov,
r->flags);
bdrv_graph_co_rdunlock();

r->done++;
qemu_coroutine_enter_if_inactive(r->co);
}

static int coroutine_fn
static int coroutine_fn GRAPH_RDLOCK
blkverify_co_prwv(BlockDriverState *bs, BlkverifyRequest *r, uint64_t offset,
uint64_t bytes, QEMUIOVector *qiov, QEMUIOVector *raw_qiov,
int flags, bool is_write)
Expand Down Expand Up @@ -222,7 +228,7 @@ blkverify_co_prwv(BlockDriverState *bs, BlkverifyRequest *r, uint64_t offset,
return r->ret;
}

static int coroutine_fn
static int coroutine_fn GRAPH_RDLOCK
blkverify_co_preadv(BlockDriverState *bs, int64_t offset, int64_t bytes,
QEMUIOVector *qiov, BdrvRequestFlags flags)
{
Expand Down Expand Up @@ -251,7 +257,7 @@ blkverify_co_preadv(BlockDriverState *bs, int64_t offset, int64_t bytes,
return ret;
}

static int coroutine_fn
static int coroutine_fn GRAPH_RDLOCK
blkverify_co_pwritev(BlockDriverState *bs, int64_t offset, int64_t bytes,
QEMUIOVector *qiov, BdrvRequestFlags flags)
{
Expand Down Expand Up @@ -282,7 +288,7 @@ blkverify_recurse_can_replace(BlockDriverState *bs,
bdrv_recurse_can_replace(s->test_file->bs, to_replace);
}

static void blkverify_refresh_filename(BlockDriverState *bs)
static void GRAPH_RDLOCK blkverify_refresh_filename(BlockDriverState *bs)
{
BDRVBlkverifyState *s = bs->opaque;

Expand Down
5 changes: 5 additions & 0 deletions block/block-backend.c
Original file line number Diff line number Diff line change
Expand Up @@ -931,10 +931,12 @@ int blk_insert_bs(BlockBackend *blk, BlockDriverState *bs, Error **errp)
ThrottleGroupMember *tgm = &blk->public.throttle_group_member;
GLOBAL_STATE_CODE();
bdrv_ref(bs);
bdrv_graph_wrlock(bs);
blk->root = bdrv_root_attach_child(bs, "root", &child_root,
BDRV_CHILD_FILTERED | BDRV_CHILD_PRIMARY,
blk->perm, blk->shared_perm,
blk, errp);
bdrv_graph_wrunlock();
if (blk->root == NULL) {
return -EPERM;
}
Expand Down Expand Up @@ -2666,6 +2668,8 @@ int blk_load_vmstate(BlockBackend *blk, uint8_t *buf, int64_t pos, int size)
int blk_probe_blocksizes(BlockBackend *blk, BlockSizes *bsz)
{
GLOBAL_STATE_CODE();
GRAPH_RDLOCK_GUARD_MAINLOOP();

if (!blk_is_available(blk)) {
return -ENOMEDIUM;
}
Expand Down Expand Up @@ -2726,6 +2730,7 @@ int blk_commit_all(void)
{
BlockBackend *blk = NULL;
GLOBAL_STATE_CODE();
GRAPH_RDLOCK_GUARD_MAINLOOP();

while ((blk = blk_all_next(blk)) != NULL) {
AioContext *aio_context = blk_get_aio_context(blk);
Expand Down
11 changes: 10 additions & 1 deletion block/block-copy.c
Original file line number Diff line number Diff line change
Expand Up @@ -313,7 +313,12 @@ static int64_t block_copy_calculate_cluster_size(BlockDriverState *target,
{
int ret;
BlockDriverInfo bdi;
bool target_does_cow = bdrv_backing_chain_next(target);
bool target_does_cow;

GLOBAL_STATE_CODE();
GRAPH_RDLOCK_GUARD_MAINLOOP();

target_does_cow = bdrv_backing_chain_next(target);

/*
* If there is no backing file on the target, we cannot rely on COW if our
Expand Down Expand Up @@ -355,6 +360,8 @@ BlockCopyState *block_copy_state_new(BdrvChild *source, BdrvChild *target,
BdrvDirtyBitmap *copy_bitmap;
bool is_fleecing;

GLOBAL_STATE_CODE();

cluster_size = block_copy_calculate_cluster_size(target->bs, errp);
if (cluster_size < 0) {
return NULL;
Expand Down Expand Up @@ -392,7 +399,9 @@ BlockCopyState *block_copy_state_new(BdrvChild *source, BdrvChild *target,
* For more information see commit f8d59dfb40bb and test
* tests/qemu-iotests/222
*/
bdrv_graph_rdlock_main_loop();
is_fleecing = bdrv_chain_contains(target->bs, source->bs);
bdrv_graph_rdunlock_main_loop();

s = g_new(BlockCopyState, 1);
*s = (BlockCopyState) {
Expand Down
4 changes: 4 additions & 0 deletions block/bochs.c
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,8 @@ static int bochs_open(BlockDriverState *bs, QDict *options, int flags,
struct bochs_header bochs;
int ret;

GLOBAL_STATE_CODE();

/* No write support yet */
bdrv_graph_rdlock_main_loop();
ret = bdrv_apply_auto_read_only(bs, NULL, errp);
Expand All @@ -118,6 +120,8 @@ static int bochs_open(BlockDriverState *bs, QDict *options, int flags,
return ret;
}

GRAPH_RDLOCK_GUARD_MAINLOOP();

ret = bdrv_pread(bs->file, 0, sizeof(bochs), &bochs, 0);
if (ret < 0) {
return ret;
Expand Down
4 changes: 4 additions & 0 deletions block/cloop.c
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,8 @@ static int cloop_open(BlockDriverState *bs, QDict *options, int flags,
uint32_t offsets_size, max_compressed_block_size = 1, i;
int ret;

GLOBAL_STATE_CODE();

bdrv_graph_rdlock_main_loop();
ret = bdrv_apply_auto_read_only(bs, NULL, errp);
bdrv_graph_rdunlock_main_loop();
Expand All @@ -79,6 +81,8 @@ static int cloop_open(BlockDriverState *bs, QDict *options, int flags,
return ret;
}

GRAPH_RDLOCK_GUARD_MAINLOOP();

/* read header */
ret = bdrv_pread(bs->file, 128, 4, &s->block_size, 0);
if (ret < 0) {
Expand Down

0 comments on commit 14e27e3

Please sign in to comment.