Commit 8644476e authored by Max Reitz's avatar Max Reitz Committed by Stefan Hajnoczi
Browse files

block: Skip COR for inactive nodes



We must not write data to inactive nodes, and a COR is certainly
something we can simply not do without upsetting anyone.  So skip COR
operations on inactive nodes.

Signed-off-by: default avatarMax Reitz <mreitz@redhat.com>
Reviewed-by: default avatarEric Blake <eblake@redhat.com>
Message-id: 20191001174827.11081-2-mreitz@redhat.com
Message-Id: <20191001174827.11081-2-mreitz@redhat.com>
Signed-off-by: default avatarStefan Hajnoczi <stefanha@redhat.com>
parent 9b92fbcf
Loading
Loading
Loading
Loading
+27 −14
Original line number Diff line number Diff line
@@ -1246,11 +1246,18 @@ static int coroutine_fn bdrv_co_do_copy_on_readv(BdrvChild *child,
    int max_transfer = MIN_NON_ZERO(bs->bl.max_transfer,
                                    BDRV_REQUEST_MAX_BYTES);
    unsigned int progress = 0;
    bool skip_write;

    if (!drv) {
        return -ENOMEDIUM;
    }

    /*
     * Do not write anything when the BDS is inactive.  That is not
     * allowed, and it would not help.
     */
    skip_write = (bs->open_flags & BDRV_O_INACTIVE);

    /* FIXME We cannot require callers to have write permissions when all they
     * are doing is a read request. If we did things right, write permissions
     * would be obtained anyway, but internally by the copy-on-read code. As
@@ -1274,10 +1281,15 @@ static int coroutine_fn bdrv_co_do_copy_on_readv(BdrvChild *child,
    while (cluster_bytes) {
        int64_t pnum;

        if (skip_write) {
            ret = 1; /* "already allocated", so nothing will be copied */
            pnum = MIN(cluster_bytes, max_transfer);
        } else {
            ret = bdrv_is_allocated(bs, cluster_offset,
                                    MIN(cluster_bytes, max_transfer), &pnum);
            if (ret < 0) {
            /* Safe to treat errors in querying allocation as if
                /*
                 * Safe to treat errors in querying allocation as if
                 * unallocated; we'll probably fail again soon on the
                 * read, but at least that will set a decent errno.
                 */
@@ -1291,6 +1303,7 @@ static int coroutine_fn bdrv_co_do_copy_on_readv(BdrvChild *child,
            }

            assert(skip_bytes < pnum);
        }

        if (ret <= 0) {
            QEMUIOVector local_qiov;