Commit 339205e7 authored by Peter Maydell's avatar Peter Maydell
Browse files

Merge remote-tracking branch 'remotes/maxreitz/tags/pull-block-2020-04-07' into staging



Block patches for 5.0-rc2:
- Fix double QLIST_REMOVE() and potential request object leak in
  xen-block
- Prevent a potential assertion failure in qcow2's code for compressed
  clusters by rejecting invalid (unaligned) requests with -EIO
- Prevent discards on qcow2 v2 images from making backing data reappear
- Make qemu-img convert report I/O error locations by byte offsets
  consistently
- Fix for potential I/O test errors (accidental globbing due to missing
  quotes)

# gpg: Signature made Tue 07 Apr 2020 13:30:01 BST
# gpg:                using RSA key 91BEB60A30DB3E8857D11829F407DB0061D5CF40
# gpg:                issuer "mreitz@redhat.com"
# gpg: Good signature from "Max Reitz <mreitz@redhat.com>" [full]
# Primary key fingerprint: 91BE B60A 30DB 3E88 57D1  1829 F407 DB00 61D5 CF40

* remotes/maxreitz/tags/pull-block-2020-04-07:
  xen-block: Fix double qlist remove and request leak
  iotests/common.pattern: Quote echos
  qcow2: Check request size in qcow2_co_pwritev_compressed_part()
  qemu-img: Report convert errors by bytes, not sectors
  qcow2: Forbid discard in qcow2 v2 images with backing files

Signed-off-by: default avatarPeter Maydell <peter.maydell@linaro.org>
parents 3f0fb073 36d883ba
Loading
Loading
Loading
Loading
+11 −0
Original line number Diff line number Diff line
@@ -3784,6 +3784,12 @@ static coroutine_fn int qcow2_co_pdiscard(BlockDriverState *bs,
    int ret;
    BDRVQcow2State *s = bs->opaque;

    /* If the image does not support QCOW_OFLAG_ZERO then discarding
     * clusters could expose stale data from the backing file. */
    if (s->qcow_version < 3 && bs->backing) {
        return -ENOTSUP;
    }

    if (!QEMU_IS_ALIGNED(offset | bytes, s->cluster_size)) {
        assert(bytes < s->cluster_size);
        /* Ignore partial clusters, except for the special case of the
@@ -4349,6 +4355,11 @@ qcow2_co_pwritev_compressed_part(BlockDriverState *bs,
        return -EINVAL;
    }

    if (offset_into_cluster(s, bytes) &&
        (offset + bytes) != (bs->total_sectors << BDRV_SECTOR_BITS)) {
        return -EINVAL;
    }

    while (bytes && aio_task_pool_status(aio) == 0) {
        uint64_t chunk_size = MIN(bytes, s->cluster_size);

+16 −32
Original line number Diff line number Diff line
@@ -64,6 +64,8 @@ struct XenBlockDataPlane {
    AioContext *ctx;
};

static int xen_block_send_response(XenBlockRequest *request);

static void reset_request(XenBlockRequest *request)
{
    memset(&request->req, 0, sizeof(request->req));
@@ -115,23 +117,26 @@ out:
    return request;
}

static void xen_block_finish_request(XenBlockRequest *request)
static void xen_block_complete_request(XenBlockRequest *request)
{
    XenBlockDataPlane *dataplane = request->dataplane;

    QLIST_REMOVE(request, list);
    dataplane->requests_inflight--;
}
    if (xen_block_send_response(request)) {
        Error *local_err = NULL;

static void xen_block_release_request(XenBlockRequest *request)
{
    XenBlockDataPlane *dataplane = request->dataplane;
        xen_device_notify_event_channel(dataplane->xendev,
                                        dataplane->event_channel,
                                        &local_err);
        if (local_err) {
            error_report_err(local_err);
        }
    }

    QLIST_REMOVE(request, list);
    dataplane->requests_inflight--;
    reset_request(request);
    request->dataplane = dataplane;
    QLIST_INSERT_HEAD(&dataplane->freelist, request, list);
    dataplane->requests_inflight--;
}

/*
@@ -246,7 +251,6 @@ static int xen_block_copy_request(XenBlockRequest *request)
}

static int xen_block_do_aio(XenBlockRequest *request);
static int xen_block_send_response(XenBlockRequest *request);

static void xen_block_complete_aio(void *opaque, int ret)
{
@@ -286,7 +290,6 @@ static void xen_block_complete_aio(void *opaque, int ret)
    }

    request->status = request->aio_errors ? BLKIF_RSP_ERROR : BLKIF_RSP_OKAY;
    xen_block_finish_request(request);

    switch (request->req.operation) {
    case BLKIF_OP_WRITE:
@@ -306,17 +309,8 @@ static void xen_block_complete_aio(void *opaque, int ret)
    default:
        break;
    }
    if (xen_block_send_response(request)) {
        Error *local_err = NULL;

        xen_device_notify_event_channel(dataplane->xendev,
                                        dataplane->event_channel,
                                        &local_err);
        if (local_err) {
            error_report_err(local_err);
        }
    }
    xen_block_release_request(request);
    xen_block_complete_request(request);

    if (dataplane->more_work) {
        qemu_bh_schedule(dataplane->bh);
@@ -420,8 +414,8 @@ static int xen_block_do_aio(XenBlockRequest *request)
    return 0;

err:
    xen_block_finish_request(request);
    request->status = BLKIF_RSP_ERROR;
    xen_block_complete_request(request);
    return -1;
}

@@ -575,17 +569,7 @@ static bool xen_block_handle_requests(XenBlockDataPlane *dataplane)
                break;
            };

            if (xen_block_send_response(request)) {
                Error *local_err = NULL;

                xen_device_notify_event_channel(dataplane->xendev,
                                                dataplane->event_channel,
                                                &local_err);
                if (local_err) {
                    error_report_err(local_err);
                }
            }
            xen_block_release_request(request);
            xen_block_complete_request(request);
            continue;
        }

+4 −4
Original line number Diff line number Diff line
@@ -1924,8 +1924,8 @@ retry:
        if (status == BLK_DATA && !copy_range) {
            ret = convert_co_read(s, sector_num, n, buf);
            if (ret < 0) {
                error_report("error while reading sector %" PRId64
                             ": %s", sector_num, strerror(-ret));
                error_report("error while reading at byte %lld: %s",
                             sector_num * BDRV_SECTOR_SIZE, strerror(-ret));
                s->ret = ret;
            }
        } else if (!s->min_sparse && status == BLK_ZERO) {
@@ -1953,8 +1953,8 @@ retry:
                ret = convert_co_write(s, sector_num, n, buf, status);
            }
            if (ret < 0) {
                error_report("error while writing sector %" PRId64
                             ": %s", sector_num, strerror(-ret));
                error_report("error while writing at byte %lld: %s",
                             sector_num * BDRV_SECTOR_SIZE, strerror(-ret));
                s->ret = ret;
            }
        }
+6 −4
Original line number Diff line number Diff line
@@ -193,8 +193,8 @@ echo "== Verify image content =="
verify_io()
{
    if ($QEMU_IMG info -U -f "$IMGFMT" "$TEST_IMG" | grep "compat: 0.10" > /dev/null); then
        # For v2 images, discarded clusters are read from the backing file
        # Keep the variable empty so that the backing file value can be used as
        # In v2 images clusters are not discarded when there is a backing file.
        # Keep the variable empty so that the previous value can be used as
        # the default below
        discarded=
    else
@@ -230,14 +230,16 @@ verify_io()
    echo read -P 70 0x78000 0x6000
    echo read -P 7  0x7e000 0x2000

    echo read -P ${discarded:-8} 0x80000 0x6000
    echo read -P ${discarded:-89} 0x80000 0x1000
    echo read -P ${discarded:-8} 0x81000 0x5000
    echo read -P 80 0x86000 0x2000
    echo read -P ${discarded:-8} 0x88000 0x2000
    echo read -P 81 0x8a000 0xe000
    echo read -P 90 0x98000 0x6000
    echo read -P 9  0x9e000 0x2000

    echo read -P ${discarded:-10} 0xa0000 0x6000
    echo read -P ${discarded:-109} 0xa0000 0x1000
    echo read -P ${discarded:-10} 0xa1000 0x5000
    echo read -P 100 0xa6000 0x2000
    echo read -P ${discarded:-10} 0xa8000 0x2000
    echo read -P 101 0xaa000 0xe000
+8 −4
Original line number Diff line number Diff line
@@ -187,8 +187,10 @@ read 24576/24576 bytes at offset 491520
24 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
read 8192/8192 bytes at offset 516096
8 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
read 24576/24576 bytes at offset 524288
24 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
read 4096/4096 bytes at offset 524288
4 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
read 20480/20480 bytes at offset 528384
20 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
read 8192/8192 bytes at offset 548864
8 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
read 8192/8192 bytes at offset 557056
@@ -199,8 +201,10 @@ read 24576/24576 bytes at offset 622592
24 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
read 8192/8192 bytes at offset 647168
8 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
read 24576/24576 bytes at offset 655360
24 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
read 4096/4096 bytes at offset 655360
4 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
read 20480/20480 bytes at offset 659456
20 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
read 8192/8192 bytes at offset 679936
8 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
read 8192/8192 bytes at offset 688128
Loading