diff options
author | Peter Maydell <peter.maydell@linaro.org> | 2017-03-17 13:26:10 +0000 |
---|---|---|
committer | Peter Maydell <peter.maydell@linaro.org> | 2017-03-17 13:26:10 +0000 |
commit | 31d89228366ce79064ac4fdef98ac85b39bf53ba (patch) | |
tree | 7bd64123338972d3ee650aeb26a81a068d630f24 | |
parent | 272d7dee5951f926fad1911f2f072e5915cdcba0 (diff) | |
parent | 11f0f5e553cff93d5fc77d67b98c40adba12b729 (diff) |
Merge remote-tracking branch 'remotes/kevin/tags/for-upstream' into staging
Block layer fixes for 2.9.0-rc1
# gpg: Signature made Fri 17 Mar 2017 12:06:04 GMT
# gpg: using RSA key 0x7F09B272C88F2FD6
# gpg: Good signature from "Kevin Wolf <kwolf@redhat.com>"
# Primary key fingerprint: DC3D EB15 9A9A F95D 3D74 56FE 7F09 B272 C88F 2FD6
* remotes/kevin/tags/for-upstream:
block: quiesce AioContext when detaching from it
thread-pool: add missing qemu_bh_cancel in completion function
block: Propagate error in bdrv_open_backing_file
blockdev: fix bitmap clear undo
block: Always call bdrv_child_check_perm first
file-posix: Don't leak fd in hdev_get_max_segments
replication: clarify permissions
file-posix: clean up max_segments buffer termination
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
-rw-r--r-- | block.c | 21 | ||||
-rw-r--r-- | block/file-posix.c | 5 | ||||
-rw-r--r-- | block/mirror.c | 6 | ||||
-rw-r--r-- | block/replication.c | 14 | ||||
-rw-r--r-- | blockdev.c | 4 | ||||
-rw-r--r-- | include/block/block_int.h | 4 | ||||
-rw-r--r-- | util/thread-pool.c | 7 |
7 files changed, 48 insertions, 13 deletions
@@ -1393,6 +1393,11 @@ static int bdrv_fill_options(QDict **options, const char *filename, return 0; } +static int bdrv_child_check_perm(BdrvChild *c, uint64_t perm, uint64_t shared, + GSList *ignore_children, Error **errp); +static void bdrv_child_abort_perm_update(BdrvChild *c); +static void bdrv_child_set_perm(BdrvChild *c, uint64_t perm, uint64_t shared); + /* * Check whether permissions on this node can be changed in a way that * @cumulative_perms and @cumulative_shared_perms are the new cumulative @@ -1615,8 +1620,8 @@ static int bdrv_check_update_perm(BlockDriverState *bs, uint64_t new_used_perm, /* Needs to be followed by a call to either bdrv_child_set_perm() or * bdrv_child_abort_perm_update(). */ -int bdrv_child_check_perm(BdrvChild *c, uint64_t perm, uint64_t shared, - GSList *ignore_children, Error **errp) +static int bdrv_child_check_perm(BdrvChild *c, uint64_t perm, uint64_t shared, + GSList *ignore_children, Error **errp) { int ret; @@ -1627,7 +1632,7 @@ int bdrv_child_check_perm(BdrvChild *c, uint64_t perm, uint64_t shared, return ret; } -void bdrv_child_set_perm(BdrvChild *c, uint64_t perm, uint64_t shared) +static void bdrv_child_set_perm(BdrvChild *c, uint64_t perm, uint64_t shared) { uint64_t cumulative_perms, cumulative_shared_perms; @@ -1639,7 +1644,7 @@ void bdrv_child_set_perm(BdrvChild *c, uint64_t perm, uint64_t shared) bdrv_set_perm(c->bs, cumulative_perms, cumulative_shared_perms); } -void bdrv_child_abort_perm_update(BdrvChild *c) +static void bdrv_child_abort_perm_update(BdrvChild *c) { bdrv_abort_perm_update(c->bs); } @@ -2025,6 +2030,7 @@ int bdrv_open_backing_file(BlockDriverState *bs, QDict *parent_options, bdrv_set_backing_hd(bs, backing_hd, &local_err); bdrv_unref(backing_hd); if (local_err) { + error_propagate(errp, local_err); ret = -EINVAL; goto free_exit; } @@ -4344,8 +4350,15 @@ void bdrv_attach_aio_context(BlockDriverState *bs, void bdrv_set_aio_context(BlockDriverState *bs, AioContext *new_context) { + AioContext *ctx; + bdrv_drain(bs); /* ensure there are no in-flight requests */ + ctx = bdrv_get_aio_context(bs); + while (aio_poll(ctx, false)) { + /* wait for all bottom halves to execute */ + } + bdrv_detach_aio_context(bs); /* This function executes in the old AioContext so acquire the new one in diff --git a/block/file-posix.c b/block/file-posix.c index c4c06637ef..53febd3767 100644 --- a/block/file-posix.c +++ b/block/file-posix.c @@ -686,7 +686,7 @@ static int hdev_get_max_segments(const struct stat *st) goto out; } do { - ret = read(fd, buf, sizeof(buf)); + ret = read(fd, buf, sizeof(buf) - 1); } while (ret == -1 && errno == EINTR); if (ret < 0) { ret = -errno; @@ -703,6 +703,9 @@ static int hdev_get_max_segments(const struct stat *st) } out: + if (fd != -1) { + close(fd); + } g_free(sysfspath); return ret; #else diff --git a/block/mirror.c b/block/mirror.c index 4f3a5cb310..ca4baa510a 100644 --- a/block/mirror.c +++ b/block/mirror.c @@ -574,7 +574,8 @@ static void mirror_exit(BlockJob *job, void *opaque) * valid. Also give up permissions on mirror_top_bs->backing, which might * block the removal. */ block_job_remove_all_bdrv(job); - bdrv_child_set_perm(mirror_top_bs->backing, 0, BLK_PERM_ALL); + bdrv_child_try_set_perm(mirror_top_bs->backing, 0, BLK_PERM_ALL, + &error_abort); bdrv_replace_node(mirror_top_bs, backing_bs(mirror_top_bs), &error_abort); /* We just changed the BDS the job BB refers to (with either or both of the @@ -1245,7 +1246,8 @@ fail: block_job_unref(&s->common); } - bdrv_child_set_perm(mirror_top_bs->backing, 0, BLK_PERM_ALL); + bdrv_child_try_set_perm(mirror_top_bs->backing, 0, BLK_PERM_ALL, + &error_abort); bdrv_replace_node(mirror_top_bs, backing_bs(mirror_top_bs), &error_abort); } diff --git a/block/replication.c b/block/replication.c index 22f170fd33..bf3c395eb4 100644 --- a/block/replication.c +++ b/block/replication.c @@ -155,6 +155,18 @@ static void replication_close(BlockDriverState *bs) replication_remove(s->rs); } +static void replication_child_perm(BlockDriverState *bs, BdrvChild *c, + const BdrvChildRole *role, + uint64_t perm, uint64_t shared, + uint64_t *nperm, uint64_t *nshared) +{ + *nperm = *nshared = BLK_PERM_CONSISTENT_READ \ + | BLK_PERM_WRITE \ + | BLK_PERM_WRITE_UNCHANGED; + + return; +} + static int64_t replication_getlength(BlockDriverState *bs) { return bdrv_getlength(bs->file->bs); @@ -660,7 +672,7 @@ BlockDriver bdrv_replication = { .bdrv_open = replication_open, .bdrv_close = replication_close, - .bdrv_child_perm = bdrv_filter_default_perms, + .bdrv_child_perm = replication_child_perm, .bdrv_getlength = replication_getlength, .bdrv_co_readv = replication_co_readv, diff --git a/blockdev.c b/blockdev.c index f1f49bd3ca..c5b2c2c209 100644 --- a/blockdev.c +++ b/blockdev.c @@ -2047,7 +2047,9 @@ static void block_dirty_bitmap_clear_abort(BlkActionState *common) BlockDirtyBitmapState *state = DO_UPCAST(BlockDirtyBitmapState, common, common); - bdrv_undo_clear_dirty_bitmap(state->bitmap, state->backup); + if (state->backup) { + bdrv_undo_clear_dirty_bitmap(state->bitmap, state->backup); + } } static void block_dirty_bitmap_clear_commit(BlkActionState *common) diff --git a/include/block/block_int.h b/include/block/block_int.h index 6c699ac9c3..59400bd848 100644 --- a/include/block/block_int.h +++ b/include/block/block_int.h @@ -889,10 +889,6 @@ BdrvChild *bdrv_root_attach_child(BlockDriverState *child_bs, void *opaque, Error **errp); void bdrv_root_unref_child(BdrvChild *child); -int bdrv_child_check_perm(BdrvChild *c, uint64_t perm, uint64_t shared, - GSList *ignore_children, Error **errp); -void bdrv_child_set_perm(BdrvChild *c, uint64_t perm, uint64_t shared); -void bdrv_child_abort_perm_update(BdrvChild *c); int bdrv_child_try_set_perm(BdrvChild *c, uint64_t perm, uint64_t shared, Error **errp); diff --git a/util/thread-pool.c b/util/thread-pool.c index ce6cd30193..610646d131 100644 --- a/util/thread-pool.c +++ b/util/thread-pool.c @@ -188,6 +188,13 @@ restart: aio_context_release(pool->ctx); elem->common.cb(elem->common.opaque, elem->ret); aio_context_acquire(pool->ctx); + + /* We can safely cancel the completion_bh here regardless of someone + * else having scheduled it meanwhile because we reenter the + * completion function anyway (goto restart). + */ + qemu_bh_cancel(pool->completion_bh); + qemu_aio_unref(elem); goto restart; } else { |