Commit 77e023ff authored by Kevin Wolf's avatar Kevin Wolf
Browse files

qcow2: Return 0/-errno in qcow2_alloc_compressed_cluster_offset()



qcow2_alloc_compressed_cluster_offset() used to return the cluster
offset for success and 0 for error. This doesn't only conflict with 0 as
a valid host offset, but also loses the error code.

Similar to the change made to qcow2_alloc_cluster_offset() for
uncompressed clusters in commit 148da7ea, make the function return
0/-errno and return the allocated cluster offset in a by-reference
parameter.

Signed-off-by: default avatarKevin Wolf <kwolf@redhat.com>
parent c6d619cc
Loading
Loading
Loading
Loading
+13 −15
Original line number Diff line number Diff line
@@ -736,19 +736,16 @@ static int get_cluster_table(BlockDriverState *bs, uint64_t offset,
/*
 * alloc_compressed_cluster_offset
 *
 * For a given offset of the disk image, return cluster offset in
 * qcow2 file.
 *
 * If the offset is not found, allocate a new compressed cluster.
 *
 * Return the cluster offset if successful,
 * Return 0, otherwise.
 * For a given offset on the virtual disk, allocate a new compressed cluster
 * and put the host offset of the cluster into *host_offset. If a cluster is
 * already allocated at the offset, return an error.
 *
 * Return 0 on success and -errno in error cases
 */

uint64_t qcow2_alloc_compressed_cluster_offset(BlockDriverState *bs,
int qcow2_alloc_compressed_cluster_offset(BlockDriverState *bs,
                                          uint64_t offset,
                                               int compressed_size)
                                          int compressed_size,
                                          uint64_t *host_offset)
{
    BDRVQcow2State *s = bs->opaque;
    int l2_index, ret;
@@ -758,7 +755,7 @@ uint64_t qcow2_alloc_compressed_cluster_offset(BlockDriverState *bs,

    ret = get_cluster_table(bs, offset, &l2_slice, &l2_index);
    if (ret < 0) {
        return 0;
        return ret;
    }

    /* Compression can't overwrite anything. Fail if the cluster was already
@@ -766,13 +763,13 @@ uint64_t qcow2_alloc_compressed_cluster_offset(BlockDriverState *bs,
    cluster_offset = be64_to_cpu(l2_slice[l2_index]);
    if (cluster_offset & L2E_OFFSET_MASK) {
        qcow2_cache_put(s->l2_table_cache, (void **) &l2_slice);
        return 0;
        return -EIO;
    }

    cluster_offset = qcow2_alloc_bytes(bs, compressed_size);
    if (cluster_offset < 0) {
        qcow2_cache_put(s->l2_table_cache, (void **) &l2_slice);
        return 0;
        return cluster_offset;
    }

    nb_csectors = ((cluster_offset + compressed_size - 1) >> 9) -
@@ -790,7 +787,8 @@ uint64_t qcow2_alloc_compressed_cluster_offset(BlockDriverState *bs,
    l2_slice[l2_index] = cpu_to_be64(cluster_offset);
    qcow2_cache_put(s->l2_table_cache, (void **) &l2_slice);

    return cluster_offset;
    *host_offset = cluster_offset & s->cluster_offset_mask;
    return 0;
}

static int perform_cow(BlockDriverState *bs, QCowL2Meta *m)
+8 −11
Original line number Diff line number Diff line
@@ -3896,17 +3896,16 @@ qcow2_co_pwritev_compressed(BlockDriverState *bs, uint64_t offset,
    int ret;
    size_t out_len;
    uint8_t *buf, *out_buf;
    int64_t cluster_offset;
    uint64_t cluster_offset;

    if (bytes == 0) {
        /* align end of file to a sector boundary to ease reading with
           sector based I/Os */
        cluster_offset = bdrv_getlength(bs->file->bs);
        if (cluster_offset < 0) {
            return cluster_offset;
        int64_t len = bdrv_getlength(bs->file->bs);
        if (len < 0) {
            return len;
        }
        return bdrv_co_truncate(bs->file, cluster_offset, PREALLOC_MODE_OFF,
                                NULL);
        return bdrv_co_truncate(bs->file, len, PREALLOC_MODE_OFF, NULL);
    }

    if (offset_into_cluster(s, offset)) {
@@ -3943,14 +3942,12 @@ qcow2_co_pwritev_compressed(BlockDriverState *bs, uint64_t offset,
    }

    qemu_co_mutex_lock(&s->lock);
    cluster_offset =
        qcow2_alloc_compressed_cluster_offset(bs, offset, out_len);
    if (!cluster_offset) {
    ret = qcow2_alloc_compressed_cluster_offset(bs, offset, out_len,
                                                &cluster_offset);
    if (ret < 0) {
        qemu_co_mutex_unlock(&s->lock);
        ret = -EIO;
        goto fail;
    }
    cluster_offset &= s->cluster_offset_mask;

    ret = qcow2_pre_write_overlap_check(bs, 0, cluster_offset, out_len);
    qemu_co_mutex_unlock(&s->lock);
+4 −3
Original line number Diff line number Diff line
@@ -647,9 +647,10 @@ int qcow2_get_cluster_offset(BlockDriverState *bs, uint64_t offset,
int qcow2_alloc_cluster_offset(BlockDriverState *bs, uint64_t offset,
                               unsigned int *bytes, uint64_t *host_offset,
                               QCowL2Meta **m);
uint64_t qcow2_alloc_compressed_cluster_offset(BlockDriverState *bs,
int qcow2_alloc_compressed_cluster_offset(BlockDriverState *bs,
                                          uint64_t offset,
                                         int compressed_size);
                                          int compressed_size,
                                          uint64_t *host_offset);

int qcow2_alloc_cluster_link_l2(BlockDriverState *bs, QCowL2Meta *m);
void qcow2_alloc_cluster_abort(BlockDriverState *bs, QCowL2Meta *m);
+1 −1
Original line number Diff line number Diff line
@@ -38,7 +38,7 @@ wrote 2097152/2097152 bytes at offset 37748736
No errors were found on the image.
image size 39845888
== Trying to write compressed cluster ==
write failed: Input/output error
write failed: File too large
image size 562949957615616
== Writing normal cluster ==
wrote 2097152/2097152 bytes at offset 0