Commit 8ae60ee8 authored by Peter Maydell's avatar Peter Maydell
Browse files

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



Block patches for 2.0.0

# gpg: Signature made Fri 04 Apr 2014 20:25:08 BST using RSA key ID C88F2FD6
# gpg: Good signature from "Kevin Wolf <kwolf@redhat.com>"

* remotes/kevin/tags/for-upstream:
  dataplane: replace iothread object_add() with embedded instance
  iothread: make IOThread struct definition public
  dma-helpers: Initialize DMAAIOCB in_cancel flag
  block: Check bdrv_getlength() return value in bdrv_append_temp_snapshot()
  block: Fix snapshot=on for protocol parsed from filename
  qemu-iotests: Remove CR line endings in reference output
  block: Don't parse 'filename' option
  qcow2: Put cache reference in error case
  qcow2: Flush metadata during read-only reopen
  iscsi: Don't set error if already set in iscsi_do_inquiry

Signed-off-by: default avatarPeter Maydell <peter.maydell@linaro.org>
parents bae2c270 54bee5c2
Loading
Loading
Loading
Loading
+87 −74
Original line number Diff line number Diff line
@@ -767,6 +767,11 @@ static int bdrv_open_flags(BlockDriverState *bs, int flags)
{
    int open_flags = flags | BDRV_O_CACHE_WB;

    /* The backing file of a temporary snapshot is read-only */
    if (flags & BDRV_O_SNAPSHOT) {
        open_flags &= ~BDRV_O_RDWR;
    }

    /*
     * Clear flags that are internal to the block layer before opening the
     * image.
@@ -968,7 +973,7 @@ static int bdrv_file_open(BlockDriverState *bs, const char *filename,
{
    BlockDriver *drv;
    const char *drvname;
    bool allow_protocol_prefix = false;
    bool parse_filename = false;
    Error *local_err = NULL;
    int ret;

@@ -977,7 +982,7 @@ static int bdrv_file_open(BlockDriverState *bs, const char *filename,
        filename = qdict_get_try_str(*options, "filename");
    } else if (filename && !qdict_haskey(*options, "filename")) {
        qdict_put(*options, "filename", qstring_from_str(filename));
        allow_protocol_prefix = true;
        parse_filename = true;
    } else {
        error_setg(errp, "Can't specify 'file' and 'filename' options at the "
                   "same time");
@@ -994,7 +999,7 @@ static int bdrv_file_open(BlockDriverState *bs, const char *filename,
        }
        qdict_del(*options, "driver");
    } else if (filename) {
        drv = bdrv_find_protocol(filename, allow_protocol_prefix);
        drv = bdrv_find_protocol(filename, parse_filename);
        if (!drv) {
            error_setg(errp, "Unknown protocol");
        }
@@ -1010,7 +1015,7 @@ static int bdrv_file_open(BlockDriverState *bs, const char *filename,
    }

    /* Parse the filename and open it */
    if (drv->bdrv_parse_filename && filename) {
    if (drv->bdrv_parse_filename && parse_filename) {
        drv->bdrv_parse_filename(filename, *options, &local_err);
        if (local_err) {
            error_propagate(errp, local_err);
@@ -1162,6 +1167,73 @@ done:
    return ret;
}

void bdrv_append_temp_snapshot(BlockDriverState *bs, Error **errp)
{
    /* TODO: extra byte is a hack to ensure MAX_PATH space on Windows. */
    char tmp_filename[PATH_MAX + 1];

    int64_t total_size;
    BlockDriver *bdrv_qcow2;
    QEMUOptionParameter *create_options;
    QDict *snapshot_options;
    BlockDriverState *bs_snapshot;
    Error *local_err;
    int ret;

    /* if snapshot, we create a temporary backing file and open it
       instead of opening 'filename' directly */

    /* Get the required size from the image */
    total_size = bdrv_getlength(bs);
    if (total_size < 0) {
        error_setg_errno(errp, -total_size, "Could not get image size");
        return;
    }
    total_size &= BDRV_SECTOR_MASK;

    /* Create the temporary image */
    ret = get_tmp_filename(tmp_filename, sizeof(tmp_filename));
    if (ret < 0) {
        error_setg_errno(errp, -ret, "Could not get temporary filename");
        return;
    }

    bdrv_qcow2 = bdrv_find_format("qcow2");
    create_options = parse_option_parameters("", bdrv_qcow2->create_options,
                                             NULL);

    set_option_parameter_int(create_options, BLOCK_OPT_SIZE, total_size);

    ret = bdrv_create(bdrv_qcow2, tmp_filename, create_options, &local_err);
    free_option_parameters(create_options);
    if (ret < 0) {
        error_setg_errno(errp, -ret, "Could not create temporary overlay "
                         "'%s': %s", tmp_filename,
                         error_get_pretty(local_err));
        error_free(local_err);
        return;
    }

    /* Prepare a new options QDict for the temporary file */
    snapshot_options = qdict_new();
    qdict_put(snapshot_options, "file.driver",
              qstring_from_str("file"));
    qdict_put(snapshot_options, "file.filename",
              qstring_from_str(tmp_filename));

    bs_snapshot = bdrv_new("");
    bs_snapshot->is_temporary = 1;

    ret = bdrv_open(&bs_snapshot, NULL, NULL, snapshot_options,
                    bs->open_flags & ~BDRV_O_SNAPSHOT, bdrv_qcow2, &local_err);
    if (ret < 0) {
        error_propagate(errp, local_err);
        return;
    }

    bdrv_append(bs_snapshot, bs);
}

/*
 * Opens a disk image (raw, qcow2, vmdk, ...)
 *
@@ -1182,8 +1254,6 @@ int bdrv_open(BlockDriverState **pbs, const char *filename,
              BlockDriver *drv, Error **errp)
{
    int ret;
    /* TODO: extra byte is a hack to ensure MAX_PATH space on Windows. */
    char tmp_filename[PATH_MAX + 1];
    BlockDriverState *file = NULL, *bs;
    const char *drvname;
    Error *local_err = NULL;
@@ -1243,74 +1313,6 @@ int bdrv_open(BlockDriverState **pbs, const char *filename,
        }
    }

    /* For snapshot=on, create a temporary qcow2 overlay */
    if (flags & BDRV_O_SNAPSHOT) {
        BlockDriverState *bs1;
        int64_t total_size;
        BlockDriver *bdrv_qcow2;
        QEMUOptionParameter *create_options;
        QDict *snapshot_options;

        /* if snapshot, we create a temporary backing file and open it
           instead of opening 'filename' directly */

        /* Get the required size from the image */
        QINCREF(options);
        bs1 = NULL;
        ret = bdrv_open(&bs1, filename, NULL, options, BDRV_O_NO_BACKING,
                        drv, &local_err);
        if (ret < 0) {
            goto fail;
        }
        total_size = bdrv_getlength(bs1) & BDRV_SECTOR_MASK;

        bdrv_unref(bs1);

        /* Create the temporary image */
        ret = get_tmp_filename(tmp_filename, sizeof(tmp_filename));
        if (ret < 0) {
            error_setg_errno(errp, -ret, "Could not get temporary filename");
            goto fail;
        }

        bdrv_qcow2 = bdrv_find_format("qcow2");
        create_options = parse_option_parameters("", bdrv_qcow2->create_options,
                                                 NULL);

        set_option_parameter_int(create_options, BLOCK_OPT_SIZE, total_size);

        ret = bdrv_create(bdrv_qcow2, tmp_filename, create_options, &local_err);
        free_option_parameters(create_options);
        if (ret < 0) {
            error_setg_errno(errp, -ret, "Could not create temporary overlay "
                             "'%s': %s", tmp_filename,
                             error_get_pretty(local_err));
            error_free(local_err);
            local_err = NULL;
            goto fail;
        }

        /* Prepare a new options QDict for the temporary file, where user
         * options refer to the backing file */
        if (filename) {
            qdict_put(options, "file.filename", qstring_from_str(filename));
        }
        if (drv) {
            qdict_put(options, "driver", qstring_from_str(drv->format_name));
        }

        snapshot_options = qdict_new();
        qdict_put(snapshot_options, "backing", options);
        qdict_flatten(snapshot_options);

        bs->options = snapshot_options;
        options = qdict_clone_shallow(bs->options);

        filename = tmp_filename;
        drv = bdrv_qcow2;
        bs->is_temporary = 1;
    }

    /* Open image file without format layer */
    if (flags & BDRV_O_RDWR) {
        flags |= BDRV_O_ALLOW_RDWR;
@@ -1372,6 +1374,17 @@ int bdrv_open(BlockDriverState **pbs, const char *filename,
        }
    }

    /* For snapshot=on, create a temporary qcow2 overlay. bs points to the
     * temporary snapshot afterwards. */
    if (flags & BDRV_O_SNAPSHOT) {
        bdrv_append_temp_snapshot(bs, &local_err);
        if (local_err) {
            error_propagate(errp, local_err);
            goto close_and_fail;
        }
    }


done:
    /* Check if any unknown options were used */
    if (options && (qdict_size(options) != 0)) {
+4 −2
Original line number Diff line number Diff line
@@ -1101,8 +1101,10 @@ static struct scsi_task *iscsi_do_inquiry(struct iscsi_context *iscsi, int lun,
    return task;

fail:
    if (!error_is_set(errp)) {
        error_setg(errp, "iSCSI: Inquiry command failed : %s",
                   iscsi_get_error(iscsi));
    }
    if (task != NULL) {
        scsi_free_scsi_task(task);
    }
+1 −0
Original line number Diff line number Diff line
@@ -491,6 +491,7 @@ int qcow2_get_cluster_offset(BlockDriverState *bs, uint64_t offset,
        break;
    case QCOW2_CLUSTER_ZERO:
        if (s->qcow_version < 3) {
            qcow2_cache_put(bs, s->l2_table_cache, (void**) &l2_table);
            return -EIO;
        }
        c = count_contiguous_clusters(nb_clusters, s->cluster_size,
+21 −4
Original line number Diff line number Diff line
@@ -269,12 +269,15 @@ static int qcow2_mark_clean(BlockDriverState *bs)
    BDRVQcowState *s = bs->opaque;

    if (s->incompatible_features & QCOW2_INCOMPAT_DIRTY) {
        int ret = bdrv_flush(bs);
        int ret;

        s->incompatible_features &= ~QCOW2_INCOMPAT_DIRTY;

        ret = bdrv_flush(bs);
        if (ret < 0) {
            return ret;
        }

        s->incompatible_features &= ~QCOW2_INCOMPAT_DIRTY;
        return qcow2_update_header(bs);
    }
    return 0;
@@ -900,11 +903,25 @@ static int qcow2_set_key(BlockDriverState *bs, const char *key)
    return 0;
}

/* We have nothing to do for QCOW2 reopen, stubs just return
 * success */
/* We have no actual commit/abort logic for qcow2, but we need to write out any
 * unwritten data if we reopen read-only. */
static int qcow2_reopen_prepare(BDRVReopenState *state,
                                BlockReopenQueue *queue, Error **errp)
{
    int ret;

    if ((state->flags & BDRV_O_RDWR) == 0) {
        ret = bdrv_flush(state->bs);
        if (ret < 0) {
            return ret;
        }

        ret = qcow2_mark_clean(state->bs);
        if (ret < 0) {
            return ret;
        }
    }

    return 0;
}

+1 −0
Original line number Diff line number Diff line
@@ -213,6 +213,7 @@ BlockDriverAIOCB *dma_bdrv_io(
    dbs->sg_cur_index = 0;
    dbs->sg_cur_byte = 0;
    dbs->dir = dir;
    dbs->in_cancel = false;
    dbs->io_func = io_func;
    dbs->bh = NULL;
    qemu_iovec_init(&dbs->iov, sg->nsg);
Loading