Block layer fixes for 2.9.0-rc1

-----BEGIN PGP SIGNATURE-----
 Version: GnuPG v2.0.22 (GNU/Linux)
 
 iQIcBAABAgAGBQJYy9EsAAoJEH8JsnLIjy/W7bgP/jBQ+4laZXdEGDZCh+1RdmFL
 fqGzKx50MqKNC2JwfOPraIWdywcBzi/+SLMml6Ch8DG7K/1t5vdoI3t/KivXnIUy
 ZLTQV/DiGm2V25JRnWTeClmwwr/ANe+sUjEQBFE8iAbzK4RhzUa8il+Gb2pwCaQM
 n77bNz8FzZyDmSf1OgPuT0gb8YXdchpG4HJddG0rDLstn0YivwwIXzIsXPX7q50V
 ECVdXtkzn33/SN7m7mIdShIwg2bw0vxiS6iaKWxpc7wSqjQBpe4CJIHf61Y5cPXW
 34HlKBW6YIRebD4m5y6SaWDMVhJUypmzTEGmJuefYFiDy88wsFXG6j/jCDdvwUcg
 SkMVb+PkAnkE0Qq4nAs37g1mycWpwvnTJ2Ll6XjwUu9K0lkDJC85B8ktA7C6tgwM
 xhOjCRSmXznYhFqgZAL9efdyWsJOXFJYL7uO2zsFp1sXe+mNaBe5sPWsCnsz+cs2
 FEm2fVAnEZOh4a3jsBbWvCDivHjjkMDp81j+WWX1pEjTjAMLk57baIOab+tPGUu/
 u3BflJPiUPNSyfjIrL0eNKI2BKwl2DcU7YBa4WvrmCjGdH2xMTloceOQ7sh/uNwg
 y+j8YG7WcMiN+gPUmmd5NrydERV/PB0m2iPw0flzIRjcYHGdG50rITlb5sxqqSfL
 h41+694ek0R+uddAiRnb
 =kA44
 -----END PGP SIGNATURE-----

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>
This commit is contained in:
Peter Maydell 2017-03-17 13:26:10 +00:00
commit 31d8922836
7 changed files with 48 additions and 13 deletions

21
block.c
View file

@ -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

View file

@ -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

View file

@ -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);
}

View file

@ -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,

View file

@ -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)

View file

@ -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);

View file

@ -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 {