Commit 79f2b6fc authored by Anthony Liguori's avatar Anthony Liguori
Browse files

Merge remote branch 'kwolf/for-anthony' into staging

parents c5d69e6b 16fde5f2
Loading
Loading
Loading
Loading
+8 −5
Original line number Diff line number Diff line
@@ -515,13 +515,16 @@ static int get_cluster_table(BlockDriverState *bs, uint64_t offset,
            return ret;
        }
    } else {
        /* FIXME Order */
        if (l2_offset)
            qcow2_free_clusters(bs, l2_offset, s->l2_size * sizeof(uint64_t));
        /* First allocate a new L2 table (and do COW if needed) */
        ret = l2_allocate(bs, l1_index, &l2_table);
        if (ret < 0) {
            return ret;
        }

        /* Then decrease the refcount of the old table */
        if (l2_offset) {
            qcow2_free_clusters(bs, l2_offset, s->l2_size * sizeof(uint64_t));
        }
        l2_offset = s->l1_table[l1_index] & ~QCOW_OFLAG_COPIED;
    }

@@ -878,11 +881,11 @@ int qcow2_decompress_cluster(BlockDriverState *bs, uint64_t cluster_offset)
        BLKDBG_EVENT(bs->file, BLKDBG_READ_COMPRESSED);
        ret = bdrv_read(bs->file, coffset >> 9, s->cluster_data, nb_csectors);
        if (ret < 0) {
            return -1;
            return ret;
        }
        if (decompress_buffer(s->cluster_cache, s->cluster_size,
                              s->cluster_data + sector_offset, csize) < 0) {
            return -1;
            return -EIO;
        }
        s->cluster_cache_offset = coffset;
    }
+19 −7
Original line number Diff line number Diff line
@@ -28,6 +28,7 @@
#include "aes.h"
#include "block/qcow2.h"
#include "qemu-error.h"
#include "qerror.h"

/*
  Differences with QCOW:
@@ -59,7 +60,7 @@ static int qcow2_probe(const uint8_t *buf, int buf_size, const char *filename)

    if (buf_size >= sizeof(QCowHeader) &&
        be32_to_cpu(cow_header->magic) == QCOW_MAGIC &&
        be32_to_cpu(cow_header->version) == QCOW_VERSION)
        be32_to_cpu(cow_header->version) >= QCOW_VERSION)
        return 100;
    else
        return 0;
@@ -163,10 +164,18 @@ static int qcow2_open(BlockDriverState *bs, int flags)
    be64_to_cpus(&header.snapshots_offset);
    be32_to_cpus(&header.nb_snapshots);

    if (header.magic != QCOW_MAGIC || header.version != QCOW_VERSION) {
    if (header.magic != QCOW_MAGIC) {
        ret = -EINVAL;
        goto fail;
    }
    if (header.version != QCOW_VERSION) {
        char version[64];
        snprintf(version, sizeof(version), "QCOW version %d", header.version);
        qerror_report(QERR_UNKNOWN_BLOCK_FORMAT_FEATURE,
            bs->device_name, "qcow2", version);
        ret = -ENOTSUP;
        goto fail;
    }
    if (header.cluster_bits < MIN_CLUSTER_BITS ||
        header.cluster_bits > MAX_CLUSTER_BITS) {
        ret = -EINVAL;
@@ -355,7 +364,7 @@ int qcow2_backing_read1(BlockDriverState *bs, QEMUIOVector *qiov,
    else
        n1 = bs->total_sectors - sector_num;

    qemu_iovec_memset(qiov, 0, 512 * (nb_sectors - n1));
    qemu_iovec_memset_skip(qiov, 0, 512 * (nb_sectors - n1), 512 * n1);

    return n1;
}
@@ -478,10 +487,11 @@ static void qcow2_aio_read_cb(void *opaque, int ret)
            if (n1 > 0) {
                BLKDBG_EVENT(bs->file, BLKDBG_READ_BACKING_AIO);
                acb->hd_aiocb = bdrv_aio_readv(bs->backing_hd, acb->sector_num,
                                    &acb->hd_qiov, acb->cur_nr_sectors,
				    qcow2_aio_read_cb, acb);
                if (acb->hd_aiocb == NULL)
                                    &acb->hd_qiov, n1, qcow2_aio_read_cb, acb);
                if (acb->hd_aiocb == NULL) {
                    ret = -EIO;
                    goto done;
                }
            } else {
                ret = qcow2_schedule_bh(qcow2_aio_read_bh, acb);
                if (ret < 0)
@@ -496,8 +506,10 @@ static void qcow2_aio_read_cb(void *opaque, int ret)
        }
    } else if (acb->cluster_offset & QCOW_OFLAG_COMPRESSED) {
        /* add AIO support for compressed blocks ? */
        if (qcow2_decompress_cluster(bs, acb->cluster_offset) < 0)
        ret = qcow2_decompress_cluster(bs, acb->cluster_offset);
        if (ret < 0) {
            goto done;
        }

        qemu_iovec_from_buffer(&acb->hd_qiov,
            s->cluster_cache + index_in_cluster * 512,
+8 −1
Original line number Diff line number Diff line
@@ -14,6 +14,7 @@

#include "trace.h"
#include "qed.h"
#include "qerror.h"

static void qed_aio_cancel(BlockDriverAIOCB *blockacb)
{
@@ -311,7 +312,13 @@ static int bdrv_qed_open(BlockDriverState *bs, int flags)
        return -EINVAL;
    }
    if (s->header.features & ~QED_FEATURE_MASK) {
        return -ENOTSUP; /* image uses unsupported feature bits */
        /* image uses unsupported feature bits */
        char buf[64];
        snprintf(buf, sizeof(buf), "%" PRIx64,
            s->header.features & ~QED_FEATURE_MASK);
        qerror_report(QERR_UNKNOWN_BLOCK_FORMAT_FEATURE,
            bs->device_name, "QED", buf);
        return -ENOTSUP;
    }
    if (!qed_is_cluster_size_valid(s->header.cluster_size)) {
        return -EINVAL;
+10 −2
Original line number Diff line number Diff line
@@ -182,6 +182,7 @@ static void drive_uninit(DriveInfo *dinfo)
{
    qemu_opts_del(dinfo->opts);
    bdrv_delete(dinfo->bdrv);
    qemu_free(dinfo->id);
    QTAILQ_REMOVE(&drives, dinfo, next);
    qemu_free(dinfo);
}
@@ -525,7 +526,7 @@ DriveInfo *drive_init(QemuOpts *opts, int default_to_scsi)
    } else if (ro == 1) {
        if (type != IF_SCSI && type != IF_VIRTIO && type != IF_FLOPPY && type != IF_NONE) {
            error_report("readonly not supported by this bus type");
            return NULL;
            goto err;
        }
    }

@@ -535,12 +536,19 @@ DriveInfo *drive_init(QemuOpts *opts, int default_to_scsi)
    if (ret < 0) {
        error_report("could not open disk image %s: %s",
                     file, strerror(-ret));
        return NULL;
        goto err;
    }

    if (bdrv_key_required(dinfo->bdrv))
        autostart = 0;
    return dinfo;

err:
    bdrv_delete(dinfo->bdrv);
    qemu_free(dinfo->id);
    QTAILQ_REMOVE(&drives, dinfo, next);
    qemu_free(dinfo);
    return NULL;
}

void do_commit(Monitor *mon, const QDict *qdict)
+31 −0
Original line number Diff line number Diff line
@@ -267,6 +267,37 @@ void qemu_iovec_memset(QEMUIOVector *qiov, int c, size_t count)
    }
}

void qemu_iovec_memset_skip(QEMUIOVector *qiov, int c, size_t count,
                            size_t skip)
{
    int i;
    size_t done;
    void *iov_base;
    uint64_t iov_len;

    done = 0;
    for (i = 0; (i < qiov->niov) && (done != count); i++) {
        if (skip >= qiov->iov[i].iov_len) {
            /* Skip the whole iov */
            skip -= qiov->iov[i].iov_len;
            continue;
        } else {
            /* Skip only part (or nothing) of the iov */
            iov_base = (uint8_t*) qiov->iov[i].iov_base + skip;
            iov_len = qiov->iov[i].iov_len - skip;
            skip = 0;
        }

        if (done + iov_len > count) {
            memset(iov_base, c, count - done);
            break;
        } else {
            memset(iov_base, c, iov_len);
        }
        done += iov_len;
    }
}

#ifndef _WIN32
/* Sets a specific flag */
int fcntl_setfl(int fd, int flag)
Loading