Commit f2bcdc8d authored by Peter Maydell's avatar Peter Maydell
Browse files

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



Block patches

# gpg: Signature made Fri 12 Sep 2014 16:09:43 BST using RSA key ID C88F2FD6
# gpg: Good signature from "Kevin Wolf <kwolf@redhat.com>"

* remotes/kevin/tags/for-upstream: (22 commits)
  qcow2: Add falloc and full preallocation option
  raw-posix: Add falloc and full preallocation option
  qapi: introduce PreallocMode and new PreallocModes full and falloc.
  block: don't convert file size to sector size
  block: round up file size to nearest sector
  iotests: Send the correct fd in socket_scm_helper
  blockdev: Refuse to drive_del something added with blockdev-add
  block: extend BLOCK_IO_ERROR with reason string
  dataplane: fix virtio_blk_data_plane_create() op blocker error path
  qemu-iotests: Run 025 for Archipelago block driver
  block/archipelago: Implement bdrv_truncate()
  block: Make the block accounting functions operate on BlockAcctStats
  block: rename BlockAcctType members to start with BLOCK_ instead of BDRV_
  block: Extract the block accounting code
  block: Extract the BlockAcctStats structure
  IDE: MMIO IDE device control should be little endian
  thread-pool: Drop unnecessary includes
  xen: Drop redundant bdrv_close() from pci_piix3_xen_ide_unplug()
  xen_disk: Plug memory leak on error path
  qemu-io: Clean up openfile() after commit 2e40134b
  ...

Signed-off-by: default avatarPeter Maydell <peter.maydell@linaro.org>
parents 16ab5046 0e4271b7
Loading
Loading
Loading
Loading
+28 −32
Original line number Diff line number Diff line
@@ -3363,9 +3363,8 @@ static int coroutine_fn bdrv_aligned_pwritev(BlockDriverState *bs,

    bdrv_set_dirty(bs, sector_num, nb_sectors);

    if (bs->wr_highest_sector < sector_num + nb_sectors - 1) {
        bs->wr_highest_sector = sector_num + nb_sectors - 1;
    }
    block_acct_highest_sector(&bs->stats, sector_num, nb_sectors);

    if (bs->growable && ret >= 0) {
        bs->total_sectors = MAX(bs->total_sectors, sector_num + nb_sectors);
    }
@@ -3639,6 +3638,19 @@ BlockErrorAction bdrv_get_error_action(BlockDriverState *bs, bool is_read, int e
    }
}

static void send_qmp_error_event(BlockDriverState *bs,
                                 BlockErrorAction action,
                                 bool is_read, int error)
{
    BlockErrorAction ac;

    ac = is_read ? IO_OPERATION_TYPE_READ : IO_OPERATION_TYPE_WRITE;
    qapi_event_send_block_io_error(bdrv_get_device_name(bs), ac, action,
                                   bdrv_iostatus_is_enabled(bs),
                                   error == ENOSPC, strerror(error),
                                   &error_abort);
}

/* This is done by device models because, while the block layer knows
 * about the error, it does not know whether an operation comes from
 * the device or the block layer (from a job, for example).
@@ -3664,16 +3676,10 @@ void bdrv_error_action(BlockDriverState *bs, BlockErrorAction action,
         * also ensures that the STOP/RESUME pair of events is emitted.
         */
        qemu_system_vmstop_request_prepare();
        qapi_event_send_block_io_error(bdrv_get_device_name(bs),
                                       is_read ? IO_OPERATION_TYPE_READ :
                                       IO_OPERATION_TYPE_WRITE,
                                       action, &error_abort);
        send_qmp_error_event(bs, action, is_read, error);
        qemu_system_vmstop_request(RUN_STATE_IO_ERROR);
    } else {
        qapi_event_send_block_io_error(bdrv_get_device_name(bs),
                                       is_read ? IO_OPERATION_TYPE_READ :
                                       IO_OPERATION_TYPE_WRITE,
                                       action, &error_abort);
        send_qmp_error_event(bs, action, is_read, error);
    }
}

@@ -5566,27 +5572,6 @@ void bdrv_iostatus_set_err(BlockDriverState *bs, int error)
    }
}

void
bdrv_acct_start(BlockDriverState *bs, BlockAcctCookie *cookie, int64_t bytes,
        enum BlockAcctType type)
{
    assert(type < BDRV_MAX_IOTYPE);

    cookie->bytes = bytes;
    cookie->start_time_ns = get_clock();
    cookie->type = type;
}

void
bdrv_acct_done(BlockDriverState *bs, BlockAcctCookie *cookie)
{
    assert(cookie->type < BDRV_MAX_IOTYPE);

    bs->nr_bytes[cookie->type] += cookie->bytes;
    bs->nr_ops[cookie->type]++;
    bs->total_time_ns[cookie->type] += get_clock() - cookie->start_time_ns;
}

void bdrv_img_create(const char *filename, const char *fmt,
                     const char *base_filename, const char *base_fmt,
                     char *options, uint64_t img_size, int flags,
@@ -6103,3 +6088,14 @@ void bdrv_refresh_filename(BlockDriverState *bs)
        QDECREF(json);
    }
}

/* This accessor function purpose is to allow the device models to access the
 * BlockAcctStats structure embedded inside a BlockDriverState without being
 * aware of the BlockDriverState structure layout.
 * It will go away when the BlockAcctStats structure will be moved inside
 * the device models.
 */
BlockAcctStats *bdrv_get_stats(BlockDriverState *bs)
{
    return &bs->stats;
}
+1 −0
Original line number Diff line number Diff line
@@ -18,6 +18,7 @@ block-obj-$(CONFIG_RBD) += rbd.o
block-obj-$(CONFIG_GLUSTERFS) += gluster.o
block-obj-$(CONFIG_ARCHIPELAGO) += archipelago.o
block-obj-$(CONFIG_LIBSSH2) += ssh.o
block-obj-y += accounting.o

common-obj-y += stream.o
common-obj-y += commit.o

block/accounting.c

0 → 100644
+54 −0
Original line number Diff line number Diff line
/*
 * QEMU System Emulator block accounting
 *
 * Copyright (c) 2011 Christoph Hellwig
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 */

#include "block/accounting.h"
#include "block/block_int.h"

void block_acct_start(BlockAcctStats *stats, BlockAcctCookie *cookie,
                      int64_t bytes, enum BlockAcctType type)
{
    assert(type < BLOCK_MAX_IOTYPE);

    cookie->bytes = bytes;
    cookie->start_time_ns = get_clock();
    cookie->type = type;
}

void block_acct_done(BlockAcctStats *stats, BlockAcctCookie *cookie)
{
    assert(cookie->type < BLOCK_MAX_IOTYPE);

    stats->nr_bytes[cookie->type] += cookie->bytes;
    stats->nr_ops[cookie->type]++;
    stats->total_time_ns[cookie->type] += get_clock() - cookie->start_time_ns;
}


void block_acct_highest_sector(BlockAcctStats *stats, int64_t sector_num,
                               unsigned int nb_sectors)
{
    if (stats->wr_highest_sector < sector_num + nb_sectors - 1) {
        stats->wr_highest_sector = sector_num + nb_sectors - 1;
    }
}
+63 −3
Original line number Diff line number Diff line
@@ -63,8 +63,6 @@
#include <xseg/xseg.h>
#include <xseg/protocol.h>

#define ARCHIP_FD_READ      0
#define ARCHIP_FD_WRITE     1
#define MAX_REQUEST_SIZE    524288

#define ARCHIPELAGO_OPT_VOLUME      "volume"
@@ -84,6 +82,7 @@ typedef enum {
    ARCHIP_OP_WRITE,
    ARCHIP_OP_FLUSH,
    ARCHIP_OP_VOLINFO,
    ARCHIP_OP_TRUNCATE,
} ARCHIPCmd;

typedef struct ArchipelagoAIOCB {
@@ -248,6 +247,7 @@ static void xseg_request_handler(void *state)
                }
                break;
            case ARCHIP_OP_VOLINFO:
            case ARCHIP_OP_TRUNCATE:
                s->is_signaled = true;
                qemu_cond_signal(&s->archip_cond);
                break;
@@ -708,7 +708,8 @@ static int qemu_archipelago_create(const char *filename,

    parse_filename_opts(filename, errp, &volname, &segment_name, &mport,
                        &vport);
    total_size = qemu_opt_get_size_del(options, BLOCK_OPT_SIZE, 0);
    total_size = ROUND_UP(qemu_opt_get_size_del(options, BLOCK_OPT_SIZE, 0),
                          BDRV_SECTOR_SIZE);

    if (segment_name == NULL) {
        segment_name = g_strdup("archipelago");
@@ -995,6 +996,64 @@ static int64_t qemu_archipelago_getlength(BlockDriverState *bs)
    return ret;
}

static int qemu_archipelago_truncate(BlockDriverState *bs, int64_t offset)
{
    int ret, targetlen;
    struct xseg_request *req;
    BDRVArchipelagoState *s = bs->opaque;
    AIORequestData *reqdata = g_new(AIORequestData, 1);

    const char *volname = s->volname;
    targetlen = strlen(volname);
    req = xseg_get_request(s->xseg, s->srcport, s->mportno, X_ALLOC);
    if (!req) {
        archipelagolog("Cannot get XSEG request\n");
        return err_exit2;
    }

    ret = xseg_prep_request(s->xseg, req, targetlen, 0);
    if (ret < 0) {
        archipelagolog("Cannot prepare XSEG request\n");
        goto err_exit;
    }
    char *target = xseg_get_target(s->xseg, req);
    if (!target) {
        archipelagolog("Cannot get XSEG target\n");
        goto err_exit;
    }
    memcpy(target, volname, targetlen);
    req->offset = offset;
    req->op = X_TRUNCATE;

    reqdata->op = ARCHIP_OP_TRUNCATE;
    reqdata->volname = volname;

    xseg_set_req_data(s->xseg, req, reqdata);

    xport p = xseg_submit(s->xseg, req, s->srcport, X_ALLOC);
    if (p == NoPort) {
        archipelagolog("Cannot submit XSEG request\n");
        goto err_exit;
    }

    xseg_signal(s->xseg, p);
    qemu_mutex_lock(&s->archip_mutex);
    while (!s->is_signaled) {
        qemu_cond_wait(&s->archip_cond, &s->archip_mutex);
    }
    s->is_signaled = false;
    qemu_mutex_unlock(&s->archip_mutex);
    xseg_put_request(s->xseg, req, s->srcport);
    g_free(reqdata);
    return 0;

err_exit:
    xseg_put_request(s->xseg, req, s->srcport);
err_exit2:
    g_free(reqdata);
    return -EIO;
}

static QemuOptsList qemu_archipelago_create_opts = {
    .name = "archipelago-create-opts",
    .head = QTAILQ_HEAD_INITIALIZER(qemu_archipelago_create_opts.head),
@@ -1024,6 +1083,7 @@ static BlockDriver bdrv_archipelago = {
    .bdrv_close          = qemu_archipelago_close,
    .bdrv_create         = qemu_archipelago_create,
    .bdrv_getlength      = qemu_archipelago_getlength,
    .bdrv_truncate       = qemu_archipelago_truncate,
    .bdrv_aio_readv      = qemu_archipelago_aio_readv,
    .bdrv_aio_writev     = qemu_archipelago_aio_writev,
    .bdrv_aio_flush      = qemu_archipelago_aio_flush,
+2 −1
Original line number Diff line number Diff line
@@ -335,7 +335,8 @@ static int cow_create(const char *filename, QemuOpts *opts, Error **errp)
    BlockDriverState *cow_bs = NULL;

    /* Read out options */
    image_sectors = qemu_opt_get_size_del(opts, BLOCK_OPT_SIZE, 0) / 512;
    image_sectors = DIV_ROUND_UP(qemu_opt_get_size_del(opts, BLOCK_OPT_SIZE, 0),
                                 BDRV_SECTOR_SIZE);
    image_filename = qemu_opt_get_del(opts, BLOCK_OPT_BACKING_FILE);

    ret = bdrv_create_file(filename, opts, &local_err);
Loading