Commit 2259637b authored by Peter Maydell's avatar Peter Maydell
Browse files

Merge remote-tracking branch 'remotes/kevin/tags/for-upstream' into staging



Block layer patches:

- block: AioContext management, part 1
- qmp: forbid qmp_cont in RUN_STATE_FINISH_MIGRATE
- nvme: fix copy direction in DMA reads going to CMB
- file-posix: Fix block status for unaligned raw images with O_DIRECT
- file-posix: Fix xfs_write_zeroes() after EOF
- Documentation and iotests improvements

# gpg: Signature made Mon 20 May 2019 16:12:38 BST
# gpg:                using RSA key 7F09B272C88F2FD6
# gpg: Good signature from "Kevin Wolf <kwolf@redhat.com>" [full]
# Primary key fingerprint: DC3D EB15 9A9A F95D 3D74  56FE 7F09 B272 C88F 2FD6

* remotes/kevin/tags/for-upstream: (24 commits)
  iotests: Make 245 faster and more reliable
  iotests.py: Fix VM.run_job
  iotests.py: Let assert_qmp() accept an array
  block: Improve "Block node is read-only" message
  qemu-img.texi: Describe human-readable info output
  qemu-img.texi: Be specific about JSON object types
  iotests: Test unaligned raw images with O_DIRECT
  block/file-posix: Unaligned O_DIRECT block-status
  test-block-iothread: Test AioContext propagation for block jobs
  blockjob: Remove AioContext notifiers
  blockjob: Propagate AioContext change to all job nodes
  block: Add blk_set_allow_aio_context_change()
  block: Implement .(can_)set_aio_ctx for BlockBackend
  test-block-iothread: Test AioContext propagation through the tree
  block: Propagate AioContext change to parents
  block: Move recursion to bdrv_set_aio_context()
  block: Make bdrv_attach/detach_aio_context() static
  block: Add bdrv_try_set_aio_context()
  nvme: fix copy direction in DMA reads going to CMB
  iotest: fix 169: do not run qmp_cont in RUN_STATE_FINISH_MIGRATE
  ...

Signed-off-by: default avatarPeter Maydell <peter.maydell@linaro.org>
parents 6d8e75d4 c423a6af
Loading
Loading
Loading
Loading
+158 −16
Original line number Diff line number Diff line
@@ -936,6 +936,20 @@ static int bdrv_child_cb_inactivate(BdrvChild *child)
    return 0;
}

static bool bdrv_child_cb_can_set_aio_ctx(BdrvChild *child, AioContext *ctx,
                                          GSList **ignore, Error **errp)
{
    BlockDriverState *bs = child->opaque;
    return bdrv_can_set_aio_context(bs, ctx, ignore, errp);
}

static void bdrv_child_cb_set_aio_ctx(BdrvChild *child, AioContext *ctx,
                                      GSList **ignore)
{
    BlockDriverState *bs = child->opaque;
    return bdrv_set_aio_context_ignore(bs, ctx, ignore);
}

/*
 * Returns the options and flags that a temporary snapshot should get, based on
 * the originally requested flags (the originally requested image will have
@@ -1003,6 +1017,8 @@ const BdrvChildRole child_file = {
    .attach          = bdrv_child_cb_attach,
    .detach          = bdrv_child_cb_detach,
    .inactivate      = bdrv_child_cb_inactivate,
    .can_set_aio_ctx = bdrv_child_cb_can_set_aio_ctx,
    .set_aio_ctx     = bdrv_child_cb_set_aio_ctx,
};

/*
@@ -1029,6 +1045,8 @@ const BdrvChildRole child_format = {
    .attach          = bdrv_child_cb_attach,
    .detach          = bdrv_child_cb_detach,
    .inactivate      = bdrv_child_cb_inactivate,
    .can_set_aio_ctx = bdrv_child_cb_can_set_aio_ctx,
    .set_aio_ctx     = bdrv_child_cb_set_aio_ctx,
};

static void bdrv_backing_attach(BdrvChild *c)
@@ -1152,6 +1170,8 @@ const BdrvChildRole child_backing = {
    .drained_end     = bdrv_child_cb_drained_end,
    .inactivate      = bdrv_child_cb_inactivate,
    .update_filename = bdrv_backing_update_filename,
    .can_set_aio_ctx = bdrv_child_cb_can_set_aio_ctx,
    .set_aio_ctx     = bdrv_child_cb_set_aio_ctx,
};

static int bdrv_open_flags(BlockDriverState *bs, int flags)
@@ -1689,6 +1709,8 @@ static int bdrv_child_check_perm(BdrvChild *c, BlockReopenQueue *q,
                                 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);
static void bdrv_get_cumulative_perm(BlockDriverState *bs, uint64_t *perm,
                                     uint64_t *shared_perm);

typedef struct BlockReopenQueueEntry {
     bool prepared;
@@ -1775,7 +1797,20 @@ static int bdrv_check_perm(BlockDriverState *bs, BlockReopenQueue *q,
    if ((cumulative_perms & (BLK_PERM_WRITE | BLK_PERM_WRITE_UNCHANGED)) &&
        !bdrv_is_writable_after_reopen(bs, q))
    {
        if (!bdrv_is_writable_after_reopen(bs, NULL)) {
            error_setg(errp, "Block node is read-only");
        } else {
            uint64_t current_perms, current_shared;
            bdrv_get_cumulative_perm(bs, &current_perms, &current_shared);
            if (current_perms & (BLK_PERM_WRITE | BLK_PERM_WRITE_UNCHANGED)) {
                error_setg(errp, "Cannot make block node read-only, there is "
                           "a writer on it");
            } else {
                error_setg(errp, "Cannot make block node read-only and create "
                           "a writer on it");
            }
        }

        return -EPERM;
    }

@@ -5666,10 +5701,9 @@ static void bdrv_do_remove_aio_context_notifier(BdrvAioNotifier *ban)
    g_free(ban);
}

void bdrv_detach_aio_context(BlockDriverState *bs)
static void bdrv_detach_aio_context(BlockDriverState *bs)
{
    BdrvAioNotifier *baf, *baf_tmp;
    BdrvChild *child;

    assert(!bs->walking_aio_notifiers);
    bs->walking_aio_notifiers = true;
@@ -5688,9 +5722,6 @@ void bdrv_detach_aio_context(BlockDriverState *bs)
    if (bs->drv && bs->drv->bdrv_detach_aio_context) {
        bs->drv->bdrv_detach_aio_context(bs);
    }
    QLIST_FOREACH(child, &bs->children, next) {
        bdrv_detach_aio_context(child->bs);
    }

    if (bs->quiesce_counter) {
        aio_enable_external(bs->aio_context);
@@ -5698,11 +5729,10 @@ void bdrv_detach_aio_context(BlockDriverState *bs)
    bs->aio_context = NULL;
}

void bdrv_attach_aio_context(BlockDriverState *bs,
static void bdrv_attach_aio_context(BlockDriverState *bs,
                                    AioContext *new_context)
{
    BdrvAioNotifier *ban, *ban_tmp;
    BdrvChild *child;

    if (bs->quiesce_counter) {
        aio_disable_external(new_context);
@@ -5710,9 +5740,6 @@ void bdrv_attach_aio_context(BlockDriverState *bs,

    bs->aio_context = new_context;

    QLIST_FOREACH(child, &bs->children, next) {
        bdrv_attach_aio_context(child->bs, new_context);
    }
    if (bs->drv && bs->drv->bdrv_attach_aio_context) {
        bs->drv->bdrv_attach_aio_context(bs, new_context);
    }
@@ -5729,16 +5756,36 @@ void bdrv_attach_aio_context(BlockDriverState *bs,
    bs->walking_aio_notifiers = false;
}

/* The caller must own the AioContext lock for the old AioContext of bs, but it
 * must not own the AioContext lock for new_context (unless new_context is
 * the same as the current context of bs). */
void bdrv_set_aio_context(BlockDriverState *bs, AioContext *new_context)
/* @ignore will accumulate all visited BdrvChild object. The caller is
 * responsible for freeing the list afterwards. */
void bdrv_set_aio_context_ignore(BlockDriverState *bs,
                                 AioContext *new_context, GSList **ignore)
{
    BdrvChild *child;

    if (bdrv_get_aio_context(bs) == new_context) {
        return;
    }

    bdrv_drained_begin(bs);

    QLIST_FOREACH(child, &bs->children, next) {
        if (g_slist_find(*ignore, child)) {
            continue;
        }
        *ignore = g_slist_prepend(*ignore, child);
        bdrv_set_aio_context_ignore(child->bs, new_context, ignore);
    }
    QLIST_FOREACH(child, &bs->parents, next_parent) {
        if (g_slist_find(*ignore, child)) {
            continue;
        }
        if (child->role->set_aio_ctx) {
            *ignore = g_slist_prepend(*ignore, child);
            child->role->set_aio_ctx(child, new_context, ignore);
        }
    }

    bdrv_detach_aio_context(bs);

    /* This function executes in the old AioContext so acquire the new one in
@@ -5750,6 +5797,101 @@ void bdrv_set_aio_context(BlockDriverState *bs, AioContext *new_context)
    aio_context_release(new_context);
}

/* The caller must own the AioContext lock for the old AioContext of bs, but it
 * must not own the AioContext lock for new_context (unless new_context is
 * the same as the current context of bs). */
void bdrv_set_aio_context(BlockDriverState *bs, AioContext *new_context)
{
    GSList *ignore_list = NULL;
    bdrv_set_aio_context_ignore(bs, new_context, &ignore_list);
    g_slist_free(ignore_list);
}

static bool bdrv_parent_can_set_aio_context(BdrvChild *c, AioContext *ctx,
                                            GSList **ignore, Error **errp)
{
    if (g_slist_find(*ignore, c)) {
        return true;
    }
    *ignore = g_slist_prepend(*ignore, c);

    /* A BdrvChildRole that doesn't handle AioContext changes cannot
     * tolerate any AioContext changes */
    if (!c->role->can_set_aio_ctx) {
        char *user = bdrv_child_user_desc(c);
        error_setg(errp, "Changing iothreads is not supported by %s", user);
        g_free(user);
        return false;
    }
    if (!c->role->can_set_aio_ctx(c, ctx, ignore, errp)) {
        assert(!errp || *errp);
        return false;
    }
    return true;
}

bool bdrv_child_can_set_aio_context(BdrvChild *c, AioContext *ctx,
                                    GSList **ignore, Error **errp)
{
    if (g_slist_find(*ignore, c)) {
        return true;
    }
    *ignore = g_slist_prepend(*ignore, c);
    return bdrv_can_set_aio_context(c->bs, ctx, ignore, errp);
}

/* @ignore will accumulate all visited BdrvChild object. The caller is
 * responsible for freeing the list afterwards. */
bool bdrv_can_set_aio_context(BlockDriverState *bs, AioContext *ctx,
                              GSList **ignore, Error **errp)
{
    BdrvChild *c;

    if (bdrv_get_aio_context(bs) == ctx) {
        return true;
    }

    QLIST_FOREACH(c, &bs->parents, next_parent) {
        if (!bdrv_parent_can_set_aio_context(c, ctx, ignore, errp)) {
            return false;
        }
    }
    QLIST_FOREACH(c, &bs->children, next) {
        if (!bdrv_child_can_set_aio_context(c, ctx, ignore, errp)) {
            return false;
        }
    }

    return true;
}

int bdrv_child_try_set_aio_context(BlockDriverState *bs, AioContext *ctx,
                                   BdrvChild *ignore_child, Error **errp)
{
    GSList *ignore;
    bool ret;

    ignore = ignore_child ? g_slist_prepend(NULL, ignore_child) : NULL;
    ret = bdrv_can_set_aio_context(bs, ctx, &ignore, errp);
    g_slist_free(ignore);

    if (!ret) {
        return -EPERM;
    }

    ignore = ignore_child ? g_slist_prepend(NULL, ignore_child) : NULL;
    bdrv_set_aio_context_ignore(bs, ctx, &ignore);
    g_slist_free(ignore);

    return 0;
}

int bdrv_try_set_aio_context(BlockDriverState *bs, AioContext *ctx,
                             Error **errp)
{
    return bdrv_child_try_set_aio_context(bs, ctx, NULL, errp);
}

void bdrv_add_aio_context_notifier(BlockDriverState *bs,
        void (*attached_aio_context)(AioContext *new_context, void *opaque),
        void (*detach_aio_context)(void *opaque), void *opaque)
+0 −8
Original line number Diff line number Diff line
@@ -300,13 +300,6 @@ static void backup_clean(Job *job)
    s->target = NULL;
}

static void backup_attached_aio_context(BlockJob *job, AioContext *aio_context)
{
    BackupBlockJob *s = container_of(job, BackupBlockJob, common);

    blk_set_aio_context(s->target, aio_context);
}

void backup_do_checkpoint(BlockJob *job, Error **errp)
{
    BackupBlockJob *backup_job = container_of(job, BackupBlockJob, common);
@@ -558,7 +551,6 @@ static const BlockJobDriver backup_job_driver = {
        .abort                  = backup_abort,
        .clean                  = backup_clean,
    },
    .attached_aio_context   = backup_attached_aio_context,
    .drain                  = backup_drain,
};

+53 −2
Original line number Diff line number Diff line
@@ -71,6 +71,7 @@ struct BlockBackend {
    uint64_t shared_perm;
    bool disable_perm;

    bool allow_aio_context_change;
    bool allow_write_beyond_eof;

    NotifierList remove_bs_notifiers, insert_bs_notifiers;
@@ -124,6 +125,11 @@ static void blk_root_drained_end(BdrvChild *child);
static void blk_root_change_media(BdrvChild *child, bool load);
static void blk_root_resize(BdrvChild *child);

static bool blk_root_can_set_aio_ctx(BdrvChild *child, AioContext *ctx,
                                     GSList **ignore, Error **errp);
static void blk_root_set_aio_ctx(BdrvChild *child, AioContext *ctx,
                                 GSList **ignore);

static char *blk_root_get_parent_desc(BdrvChild *child)
{
    BlockBackend *blk = child->opaque;
@@ -300,6 +306,9 @@ static const BdrvChildRole child_root = {

    .attach             = blk_root_attach,
    .detach             = blk_root_detach,

    .can_set_aio_ctx    = blk_root_can_set_aio_ctx,
    .set_aio_ctx        = blk_root_set_aio_ctx,
};

/*
@@ -1084,6 +1093,11 @@ void blk_set_allow_write_beyond_eof(BlockBackend *blk, bool allow)
    blk->allow_write_beyond_eof = allow;
}

void blk_set_allow_aio_context_change(BlockBackend *blk, bool allow)
{
    blk->allow_aio_context_change = allow;
}

static int blk_check_byte_request(BlockBackend *blk, int64_t offset,
                                  size_t size)
{
@@ -1852,7 +1866,8 @@ static AioContext *blk_aiocb_get_aio_context(BlockAIOCB *acb)
    return blk_get_aio_context(blk_acb->blk);
}

void blk_set_aio_context(BlockBackend *blk, AioContext *new_context)
static void blk_do_set_aio_context(BlockBackend *blk, AioContext *new_context,
                                   bool update_root_node)
{
    BlockDriverState *bs = blk_bs(blk);
    ThrottleGroupMember *tgm = &blk->public.throttle_group_member;
@@ -1864,10 +1879,46 @@ void blk_set_aio_context(BlockBackend *blk, AioContext *new_context)
            throttle_group_attach_aio_context(tgm, new_context);
            bdrv_drained_end(bs);
        }
        bdrv_set_aio_context(bs, new_context);
        if (update_root_node) {
            GSList *ignore = g_slist_prepend(NULL, blk->root);
            bdrv_set_aio_context_ignore(bs, new_context, &ignore);
            g_slist_free(ignore);
        }
    }
}

void blk_set_aio_context(BlockBackend *blk, AioContext *new_context)
{
    blk_do_set_aio_context(blk, new_context, true);
}

static bool blk_root_can_set_aio_ctx(BdrvChild *child, AioContext *ctx,
                                     GSList **ignore, Error **errp)
{
    BlockBackend *blk = child->opaque;

    if (blk->allow_aio_context_change) {
        return true;
    }

    /* Only manually created BlockBackends that are not attached to anything
     * can change their AioContext without updating their user. */
    if (!blk->name || blk->dev) {
        /* TODO Add BB name/QOM path */
        error_setg(errp, "Cannot change iothread of active block backend");
        return false;
    }

    return true;
}

static void blk_root_set_aio_ctx(BdrvChild *child, AioContext *ctx,
                                 GSList **ignore)
{
    BlockBackend *blk = child->opaque;
    blk_do_set_aio_context(blk, ctx, false);
}

void blk_add_aio_context_notifier(BlockBackend *blk,
        void (*attached_aio_context)(AioContext *new_context, void *opaque),
        void (*detach_aio_context)(void *opaque), void *opaque)
+29 −0
Original line number Diff line number Diff line
@@ -1444,9 +1444,22 @@ out:
#ifdef CONFIG_XFS
static int xfs_write_zeroes(BDRVRawState *s, int64_t offset, uint64_t bytes)
{
    int64_t len;
    struct xfs_flock64 fl;
    int err;

    len = lseek(s->fd, 0, SEEK_END);
    if (len < 0) {
        return -errno;
    }

    if (offset + bytes > len) {
        /* XFS_IOC_ZERO_RANGE does not increase the file length */
        if (ftruncate(s->fd, offset + bytes) < 0) {
            return -errno;
        }
    }

    memset(&fl, 0, sizeof(fl));
    fl.l_whence = SEEK_SET;
    fl.l_start = offset;
@@ -2475,6 +2488,8 @@ static int coroutine_fn raw_co_block_status(BlockDriverState *bs,
    off_t data = 0, hole = 0;
    int ret;

    assert(QEMU_IS_ALIGNED(offset | bytes, bs->bl.request_alignment));

    ret = fd_open(bs);
    if (ret < 0) {
        return ret;
@@ -2500,6 +2515,20 @@ static int coroutine_fn raw_co_block_status(BlockDriverState *bs,
        /* On a data extent, compute bytes to the end of the extent,
         * possibly including a partial sector at EOF. */
        *pnum = MIN(bytes, hole - offset);

        /*
         * We are not allowed to return partial sectors, though, so
         * round up if necessary.
         */
        if (!QEMU_IS_ALIGNED(*pnum, bs->bl.request_alignment)) {
            int64_t file_length = raw_getlength(bs);
            if (file_length > 0) {
                /* Ignore errors, this is just a safeguard */
                assert(hole == file_length);
            }
            *pnum = ROUND_UP(*pnum, bs->bl.request_alignment);
        }

        ret = BDRV_BLOCK_DATA;
    } else {
        /* On a hole, compute bytes to the beginning of the next extent.  */
+3 −3
Original line number Diff line number Diff line
@@ -769,7 +769,7 @@ static bool coroutine_fn wait_serialising_requests(BdrvTrackedRequest *self)
static int bdrv_check_byte_request(BlockDriverState *bs, int64_t offset,
                                   size_t size)
{
    if (size > BDRV_REQUEST_MAX_SECTORS << BDRV_SECTOR_BITS) {
    if (size > BDRV_REQUEST_MAX_BYTES) {
        return -EIO;
    }

@@ -1017,7 +1017,7 @@ static int coroutine_fn bdrv_driver_preadv(BlockDriverState *bs,

    assert((offset & (BDRV_SECTOR_SIZE - 1)) == 0);
    assert((bytes & (BDRV_SECTOR_SIZE - 1)) == 0);
    assert((bytes >> BDRV_SECTOR_BITS) <= BDRV_REQUEST_MAX_SECTORS);
    assert(bytes <= BDRV_REQUEST_MAX_BYTES);
    assert(drv->bdrv_co_readv);

    return drv->bdrv_co_readv(bs, sector_num, nb_sectors, qiov);
@@ -1070,7 +1070,7 @@ static int coroutine_fn bdrv_driver_pwritev(BlockDriverState *bs,

    assert((offset & (BDRV_SECTOR_SIZE - 1)) == 0);
    assert((bytes & (BDRV_SECTOR_SIZE - 1)) == 0);
    assert((bytes >> BDRV_SECTOR_BITS) <= BDRV_REQUEST_MAX_SECTORS);
    assert(bytes <= BDRV_REQUEST_MAX_BYTES);

    assert(drv->bdrv_co_writev);
    ret = drv->bdrv_co_writev(bs, sector_num, nb_sectors, qiov,
Loading