diff options
author | Peter Maydell <peter.maydell@linaro.org> | 2016-05-12 16:33:40 +0100 |
---|---|---|
committer | Peter Maydell <peter.maydell@linaro.org> | 2016-05-12 16:33:40 +0100 |
commit | f68419eee9a966f5a915314c43cda6778f976a77 (patch) | |
tree | 5b63c0bf712a978a50c43be7000b6a9332258c20 | |
parent | e4f70d635863cfc3e3fa7d9a6e37b569ae94d82f (diff) | |
parent | efc2645f714aae1bcf22e8165cad51c57f34fdf3 (diff) |
Merge remote-tracking branch 'remotes/kevin/tags/for-upstream' into staging
Block layer patches
# gpg: Signature made Thu 12 May 2016 14:37:05 BST using RSA key ID C88F2FD6
# gpg: Good signature from "Kevin Wolf <kwolf@redhat.com>"
* remotes/kevin/tags/for-upstream: (69 commits)
qemu-iotests: iotests: fail hard if not run via "check"
block: enable testing of LUKS driver with block I/O tests
block: add support for encryption secrets in block I/O tests
block: add support for --image-opts in block I/O tests
qemu-io: Add 'write -z -u' to test MAY_UNMAP flag
qemu-io: Add 'write -f' to test FUA flag
qemu-io: Allow unaligned access by default
qemu-io: Use bool for command line flags
qemu-io: Make 'open' subcommand more like command line
qemu-io: Add missing option documentation
qmp: add monitor command to add/remove a child
quorum: implement bdrv_add_child() and bdrv_del_child()
Add new block driver interface to add/delete a BDS's child
qemu-img: check block status of backing file when converting.
iotests: fix the redirection order in 083
block: Inactivate all children
block: Drop superfluous invalidating bs->file from drivers
block: Invalidate all children
nbd: Simplify client FUA handling
block: Honor BDRV_REQ_FUA during write_zeroes
...
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
78 files changed, 3323 insertions, 2059 deletions
@@ -218,8 +218,6 @@ void bdrv_get_full_backing_filename(BlockDriverState *bs, char *dest, size_t sz, void bdrv_register(BlockDriver *bdrv) { - bdrv_setup_io_funcs(bdrv); - QLIST_INSERT_HEAD(&bdrv_drivers, bdrv, list); } @@ -1176,10 +1174,10 @@ BdrvChild *bdrv_root_attach_child(BlockDriverState *child_bs, return child; } -static BdrvChild *bdrv_attach_child(BlockDriverState *parent_bs, - BlockDriverState *child_bs, - const char *child_name, - const BdrvChildRole *child_role) +BdrvChild *bdrv_attach_child(BlockDriverState *parent_bs, + BlockDriverState *child_bs, + const char *child_name, + const BdrvChildRole *child_role) { BdrvChild *child = bdrv_root_attach_child(child_bs, child_name, child_role); QLIST_INSERT_HEAD(&parent_bs->children, child, next); @@ -2261,7 +2259,6 @@ static void swap_feature_fields(BlockDriverState *bs_top, assert(!bs_new->throttle_state); if (bs_top->throttle_state) { - assert(bs_top->io_limits_enabled); bdrv_io_limits_enable(bs_new, throttle_group_get_name(bs_top)); bdrv_io_limits_disable(bs_top); } @@ -3201,6 +3198,7 @@ void bdrv_init_with_whitelist(void) void bdrv_invalidate_cache(BlockDriverState *bs, Error **errp) { + BdrvChild *child; Error *local_err = NULL; int ret; @@ -3215,13 +3213,20 @@ void bdrv_invalidate_cache(BlockDriverState *bs, Error **errp) if (bs->drv->bdrv_invalidate_cache) { bs->drv->bdrv_invalidate_cache(bs, &local_err); - } else if (bs->file) { - bdrv_invalidate_cache(bs->file->bs, &local_err); + if (local_err) { + bs->open_flags |= BDRV_O_INACTIVE; + error_propagate(errp, local_err); + return; + } } - if (local_err) { - bs->open_flags |= BDRV_O_INACTIVE; - error_propagate(errp, local_err); - return; + + QLIST_FOREACH(child, &bs->children, next) { + bdrv_invalidate_cache(child->bs, &local_err); + if (local_err) { + bs->open_flags |= BDRV_O_INACTIVE; + error_propagate(errp, local_err); + return; + } } ret = refresh_total_sectors(bs, bs->total_sectors); @@ -3250,38 +3255,63 @@ void bdrv_invalidate_cache_all(Error **errp) } } -static int bdrv_inactivate(BlockDriverState *bs) +static int bdrv_inactivate_recurse(BlockDriverState *bs, + bool setting_flag) { + BdrvChild *child; int ret; - if (bs->drv->bdrv_inactivate) { + if (!setting_flag && bs->drv->bdrv_inactivate) { ret = bs->drv->bdrv_inactivate(bs); if (ret < 0) { return ret; } } - bs->open_flags |= BDRV_O_INACTIVE; + QLIST_FOREACH(child, &bs->children, next) { + ret = bdrv_inactivate_recurse(child->bs, setting_flag); + if (ret < 0) { + return ret; + } + } + + if (setting_flag) { + bs->open_flags |= BDRV_O_INACTIVE; + } return 0; } int bdrv_inactivate_all(void) { BlockDriverState *bs = NULL; - int ret; + int ret = 0; + int pass; while ((bs = bdrv_next(bs)) != NULL) { - AioContext *aio_context = bdrv_get_aio_context(bs); + aio_context_acquire(bdrv_get_aio_context(bs)); + } - aio_context_acquire(aio_context); - ret = bdrv_inactivate(bs); - aio_context_release(aio_context); - if (ret < 0) { - return ret; + /* We do two passes of inactivation. The first pass calls to drivers' + * .bdrv_inactivate callbacks recursively so all cache is flushed to disk; + * the second pass sets the BDRV_O_INACTIVE flag so that no further write + * is allowed. */ + for (pass = 0; pass < 2; pass++) { + bs = NULL; + while ((bs = bdrv_next(bs)) != NULL) { + ret = bdrv_inactivate_recurse(bs, pass); + if (ret < 0) { + goto out; + } } } - return 0; +out: + bs = NULL; + while ((bs = bdrv_next(bs)) != NULL) { + aio_context_release(bdrv_get_aio_context(bs)); + } + + return ret; } /**************************************************************/ @@ -3981,3 +4011,52 @@ void bdrv_refresh_filename(BlockDriverState *bs) QDECREF(json); } } + +/* + * Hot add/remove a BDS's child. So the user can take a child offline when + * it is broken and take a new child online + */ +void bdrv_add_child(BlockDriverState *parent_bs, BlockDriverState *child_bs, + Error **errp) +{ + + if (!parent_bs->drv || !parent_bs->drv->bdrv_add_child) { + error_setg(errp, "The node %s does not support adding a child", + bdrv_get_device_or_node_name(parent_bs)); + return; + } + + if (!QLIST_EMPTY(&child_bs->parents)) { + error_setg(errp, "The node %s already has a parent", + child_bs->node_name); + return; + } + + parent_bs->drv->bdrv_add_child(parent_bs, child_bs, errp); +} + +void bdrv_del_child(BlockDriverState *parent_bs, BdrvChild *child, Error **errp) +{ + BdrvChild *tmp; + + if (!parent_bs->drv || !parent_bs->drv->bdrv_del_child) { + error_setg(errp, "The node %s does not support removing a child", + bdrv_get_device_or_node_name(parent_bs)); + return; + } + + QLIST_FOREACH(tmp, &parent_bs->children, next) { + if (tmp == child) { + break; + } + } + + if (!tmp) { + error_setg(errp, "The node %s does not have a child named %s", + bdrv_get_device_or_node_name(parent_bs), + bdrv_get_device_or_node_name(child->bs)); + return; + } + + parent_bs->drv->bdrv_del_child(parent_bs, child, errp); +} diff --git a/block/block-backend.c b/block/block-backend.c index 16c9d5e0f2..a1e2c7fa20 100644 --- a/block/block-backend.c +++ b/block/block-backend.c @@ -1,7 +1,7 @@ /* * QEMU Block backends * - * Copyright (C) 2014 Red Hat, Inc. + * Copyright (C) 2014-2016 Red Hat, Inc. * * Authors: * Markus Armbruster <armbru@redhat.com>, @@ -692,7 +692,7 @@ static int coroutine_fn blk_co_preadv(BlockBackend *blk, int64_t offset, return ret; } - return bdrv_co_do_preadv(blk_bs(blk), offset, bytes, qiov, flags); + return bdrv_co_preadv(blk_bs(blk), offset, bytes, qiov, flags); } static int coroutine_fn blk_co_pwritev(BlockBackend *blk, int64_t offset, @@ -710,7 +710,7 @@ static int coroutine_fn blk_co_pwritev(BlockBackend *blk, int64_t offset, flags |= BDRV_REQ_FUA; } - return bdrv_co_do_pwritev(blk_bs(blk), offset, bytes, qiov, flags); + return bdrv_co_pwritev(blk_bs(blk), offset, bytes, qiov, flags); } typedef struct BlkRwCo { @@ -772,55 +772,28 @@ static int blk_prw(BlockBackend *blk, int64_t offset, uint8_t *buf, return rwco.ret; } -static int blk_rw(BlockBackend *blk, int64_t sector_num, uint8_t *buf, - int nb_sectors, CoroutineEntry co_entry, - BdrvRequestFlags flags) -{ - if (nb_sectors < 0 || nb_sectors > BDRV_REQUEST_MAX_SECTORS) { - return -EINVAL; - } - - return blk_prw(blk, sector_num << BDRV_SECTOR_BITS, buf, - nb_sectors << BDRV_SECTOR_BITS, co_entry, flags); -} - -int blk_read(BlockBackend *blk, int64_t sector_num, uint8_t *buf, - int nb_sectors) -{ - return blk_rw(blk, sector_num, buf, nb_sectors, blk_read_entry, 0); -} - -int blk_read_unthrottled(BlockBackend *blk, int64_t sector_num, uint8_t *buf, - int nb_sectors) +int blk_pread_unthrottled(BlockBackend *blk, int64_t offset, uint8_t *buf, + int count) { BlockDriverState *bs = blk_bs(blk); - bool enabled; int ret; - ret = blk_check_request(blk, sector_num, nb_sectors); + ret = blk_check_byte_request(blk, offset, count); if (ret < 0) { return ret; } - enabled = bs->io_limits_enabled; - bs->io_limits_enabled = false; - ret = blk_read(blk, sector_num, buf, nb_sectors); - bs->io_limits_enabled = enabled; + bdrv_no_throttling_begin(bs); + ret = blk_pread(blk, offset, buf, count); + bdrv_no_throttling_end(bs); return ret; } -int blk_write(BlockBackend *blk, int64_t sector_num, const uint8_t *buf, - int nb_sectors) -{ - return blk_rw(blk, sector_num, (uint8_t*) buf, nb_sectors, - blk_write_entry, 0); -} - -int blk_write_zeroes(BlockBackend *blk, int64_t sector_num, - int nb_sectors, BdrvRequestFlags flags) +int blk_write_zeroes(BlockBackend *blk, int64_t offset, + int count, BdrvRequestFlags flags) { - return blk_rw(blk, sector_num, NULL, nb_sectors, blk_write_entry, - flags | BDRV_REQ_ZERO_WRITE); + return blk_prw(blk, offset, NULL, count, blk_write_entry, + flags | BDRV_REQ_ZERO_WRITE); } static void error_callback_bh(void *opaque) @@ -932,18 +905,12 @@ static void blk_aio_write_entry(void *opaque) blk_aio_complete(acb); } -BlockAIOCB *blk_aio_write_zeroes(BlockBackend *blk, int64_t sector_num, - int nb_sectors, BdrvRequestFlags flags, +BlockAIOCB *blk_aio_write_zeroes(BlockBackend *blk, int64_t offset, + int count, BdrvRequestFlags flags, BlockCompletionFunc *cb, void *opaque) { - if (nb_sectors < 0 || nb_sectors > BDRV_REQUEST_MAX_SECTORS) { - return blk_abort_aio_request(blk, cb, opaque, -EINVAL); - } - - return blk_aio_prwv(blk, sector_num << BDRV_SECTOR_BITS, - nb_sectors << BDRV_SECTOR_BITS, NULL, - blk_aio_write_entry, flags | BDRV_REQ_ZERO_WRITE, - cb, opaque); + return blk_aio_prwv(blk, offset, count, NULL, blk_aio_write_entry, + flags | BDRV_REQ_ZERO_WRITE, cb, opaque); } int blk_pread(BlockBackend *blk, int64_t offset, void *buf, int count) @@ -955,9 +922,11 @@ int blk_pread(BlockBackend *blk, int64_t offset, void *buf, int count) return count; } -int blk_pwrite(BlockBackend *blk, int64_t offset, const void *buf, int count) +int blk_pwrite(BlockBackend *blk, int64_t offset, const void *buf, int count, + BdrvRequestFlags flags) { - int ret = blk_prw(blk, offset, (void*) buf, count, blk_write_entry, 0); + int ret = blk_prw(blk, offset, (void *) buf, count, blk_write_entry, + flags); if (ret < 0) { return ret; } @@ -991,30 +960,20 @@ int64_t blk_nb_sectors(BlockBackend *blk) return bdrv_nb_sectors(blk_bs(blk)); } -BlockAIOCB *blk_aio_readv(BlockBackend *blk, int64_t sector_num, - QEMUIOVector *iov, int nb_sectors, - BlockCompletionFunc *cb, void *opaque) +BlockAIOCB *blk_aio_preadv(BlockBackend *blk, int64_t offset, + QEMUIOVector *qiov, BdrvRequestFlags flags, + BlockCompletionFunc *cb, void *opaque) { - if (nb_sectors < 0 || nb_sectors > BDRV_REQUEST_MAX_SECTORS) { - return blk_abort_aio_request(blk, cb, opaque, -EINVAL); - } - - assert(nb_sectors << BDRV_SECTOR_BITS == iov->size); - return blk_aio_prwv(blk, sector_num << BDRV_SECTOR_BITS, iov->size, iov, - blk_aio_read_entry, 0, cb, opaque); + return blk_aio_prwv(blk, offset, qiov->size, qiov, + blk_aio_read_entry, flags, cb, opaque); } -BlockAIOCB *blk_aio_writev(BlockBackend *blk, int64_t sector_num, - QEMUIOVector *iov, int nb_sectors, - BlockCompletionFunc *cb, void *opaque) +BlockAIOCB *blk_aio_pwritev(BlockBackend *blk, int64_t offset, + QEMUIOVector *qiov, BdrvRequestFlags flags, + BlockCompletionFunc *cb, void *opaque) { - if (nb_sectors < 0 || nb_sectors > BDRV_REQUEST_MAX_SECTORS) { - return blk_abort_aio_request(blk, cb, opaque, -EINVAL); - } - - assert(nb_sectors << BDRV_SECTOR_BITS == iov->size); - return blk_aio_prwv(blk, sector_num << BDRV_SECTOR_BITS, iov->size, iov, - blk_aio_write_entry, 0, cb, opaque); + return blk_aio_prwv(blk, offset, qiov->size, qiov, + blk_aio_write_entry, flags, cb, opaque); } BlockAIOCB *blk_aio_flush(BlockBackend *blk, @@ -1444,15 +1403,10 @@ void *blk_aio_get(const AIOCBInfo *aiocb_info, BlockBackend *blk, return qemu_aio_get(aiocb_info, blk_bs(blk), cb, opaque); } -int coroutine_fn blk_co_write_zeroes(BlockBackend *blk, int64_t sector_num, - int nb_sectors, BdrvRequestFlags flags) +int coroutine_fn blk_co_write_zeroes(BlockBackend *blk, int64_t offset, + int count, BdrvRequestFlags flags) { - if (nb_sectors < 0 || nb_sectors > BDRV_REQUEST_MAX_SECTORS) { - return -EINVAL; - } - - return blk_co_pwritev(blk, sector_num << BDRV_SECTOR_BITS, - nb_sectors << BDRV_SECTOR_BITS, NULL, + return blk_co_pwritev(blk, offset, count, NULL, flags | BDRV_REQ_ZERO_WRITE); } diff --git a/block/bochs.c b/block/bochs.c index af8b7abdfd..f0e18c0b84 100644 --- a/block/bochs.c +++ b/block/bochs.c @@ -104,6 +104,7 @@ static int bochs_open(BlockDriverState *bs, QDict *options, int flags, int ret; bs->read_only = 1; // no write support yet + bs->request_alignment = BDRV_SECTOR_SIZE; /* No sub-sector I/O supported */ ret = bdrv_pread(bs->file->bs, 0, &bochs, sizeof(bochs)); if (ret < 0) { @@ -221,38 +222,52 @@ static int64_t seek_to_sector(BlockDriverState *bs, int64_t sector_num) return bitmap_offset + (512 * (s->bitmap_blocks + extent_offset)); } -static int bochs_read(BlockDriverState *bs, int64_t sector_num, - uint8_t *buf, int nb_sectors) +static int coroutine_fn +bochs_co_preadv(BlockDriverState *bs, uint64_t offset, uint64_t bytes, + QEMUIOVector *qiov, int flags) { + BDRVBochsState *s = bs->opaque; + uint64_t sector_num = offset >> BDRV_SECTOR_BITS; + int nb_sectors = bytes >> BDRV_SECTOR_BITS; + uint64_t bytes_done = 0; + QEMUIOVector local_qiov; int ret; + assert((offset & (BDRV_SECTOR_SIZE - 1)) == 0); + assert((bytes & (BDRV_SECTOR_SIZE - 1)) == 0); + + qemu_iovec_init(&local_qiov, qiov->niov); + qemu_co_mutex_lock(&s->lock); + while (nb_sectors > 0) { int64_t block_offset = seek_to_sector(bs, sector_num); if (block_offset < 0) { - return block_offset; - } else if (block_offset > 0) { - ret = bdrv_pread(bs->file->bs, block_offset, buf, 512); + ret = block_offset; + goto fail; + } + + qemu_iovec_reset(&local_qiov); + qemu_iovec_concat(&local_qiov, qiov, bytes_done, 512); + + if (block_offset > 0) { + ret = bdrv_co_preadv(bs->file->bs, block_offset, 512, + &local_qiov, 0); if (ret < 0) { - return ret; + goto fail; } } else { - memset(buf, 0, 512); + qemu_iovec_memset(&local_qiov, 0, 0, 512); } nb_sectors--; sector_num++; - buf += 512; + bytes_done += 512; } - return 0; -} -static coroutine_fn int bochs_co_read(BlockDriverState *bs, int64_t sector_num, - uint8_t *buf, int nb_sectors) -{ - int ret; - BDRVBochsState *s = bs->opaque; - qemu_co_mutex_lock(&s->lock); - ret = bochs_read(bs, sector_num, buf, nb_sectors); + ret = 0; +fail: qemu_co_mutex_unlock(&s->lock); + qemu_iovec_destroy(&local_qiov); + return ret; } @@ -267,7 +282,7 @@ static BlockDriver bdrv_bochs = { .instance_size = sizeof(BDRVBochsState), .bdrv_probe = bochs_probe, .bdrv_open = bochs_open, - .bdrv_read = bochs_co_read, + .bdrv_co_preadv = bochs_co_preadv, .bdrv_close = bochs_close, }; diff --git a/block/cloop.c b/block/cloop.c index a84f14019c..fc1ca3a05a 100644 --- a/block/cloop.c +++ b/block/cloop.c @@ -66,6 +66,7 @@ static int cloop_open(BlockDriverState *bs, QDict *options, int flags, int ret; bs->read_only = 1; + bs->request_alignment = BDRV_SECTOR_SIZE; /* No sub-sector I/O supported */ /* read header */ ret = bdrv_pread(bs->file->bs, 128, &s->block_size, 4); @@ -229,33 +230,38 @@ static inline int cloop_read_block(BlockDriverState *bs, int block_num) return 0; } -static int cloop_read(BlockDriverState *bs, int64_t sector_num, - uint8_t *buf, int nb_sectors) +static int coroutine_fn +cloop_co_preadv(BlockDriverState *bs, uint64_t offset, uint64_t bytes, + QEMUIOVector *qiov, int flags) { BDRVCloopState *s = bs->opaque; - int i; + uint64_t sector_num = offset >> BDRV_SECTOR_BITS; + int nb_sectors = bytes >> BDRV_SECTOR_BITS; + int ret, i; + + assert((offset & (BDRV_SECTOR_SIZE - 1)) == 0); + assert((bytes & (BDRV_SECTOR_SIZE - 1)) == 0); + + qemu_co_mutex_lock(&s->lock); for (i = 0; i < nb_sectors; i++) { + void *data; uint32_t sector_offset_in_block = ((sector_num + i) % s->sectors_per_block), block_num = (sector_num + i) / s->sectors_per_block; if (cloop_read_block(bs, block_num) != 0) { - return -1; + ret = -EIO; + goto fail; } - memcpy(buf + i * 512, - s->uncompressed_block + sector_offset_in_block * 512, 512); + + data = s->uncompressed_block + sector_offset_in_block * 512; + qemu_iovec_from_buf(qiov, i * 512, data, 512); } - return 0; -} -static coroutine_fn int cloop_co_read(BlockDriverState *bs, int64_t sector_num, - uint8_t *buf, int nb_sectors) -{ - int ret; - BDRVCloopState *s = bs->opaque; - qemu_co_mutex_lock(&s->lock); - ret = cloop_read(bs, sector_num, buf, nb_sectors); + ret = 0; +fail: qemu_co_mutex_unlock(&s->lock); + return ret; } @@ -273,7 +279,7 @@ static BlockDriver bdrv_cloop = { .instance_size = sizeof(BDRVCloopState), .bdrv_probe = cloop_probe, .bdrv_open = cloop_open, - .bdrv_read = cloop_co_read, + .bdrv_co_preadv = cloop_co_preadv, .bdrv_close = cloop_close, }; diff --git a/block/crypto.c b/block/crypto.c index 2424a4c9c9..758e14e032 100644 --- a/block/crypto.c +++ b/block/crypto.c @@ -91,7 +91,7 @@ static ssize_t block_crypto_write_func(QCryptoBlock *block, struct BlockCryptoCreateData *data = opaque; ssize_t ret; - ret = blk_pwrite(data->blk, offset, buf, buflen); + ret = blk_pwrite(data->blk, offset, buf, buflen, 0); if (ret < 0) { error_setg_errno(errp, -ret, "Could not write encryption header"); return ret; diff --git a/block/curl.c b/block/curl.c index 5a8f8b6239..da9f5e85de 100644 --- a/block/curl.c +++ b/block/curl.c @@ -36,10 +36,16 @@ // #define DEBUG_VERBOSE #ifdef DEBUG_CURL -#define DPRINTF(fmt, ...) do { printf(fmt, ## __VA_ARGS__); } while (0) +#define DEBUG_CURL_PRINT 1 #else -#define DPRINTF(fmt, ...) do { } while (0) +#define DEBUG_CURL_PRINT 0 #endif +#define DPRINTF(fmt, ...) \ + do { \ + if (DEBUG_CURL_PRINT) { \ + fprintf(stderr, fmt, ## __VA_ARGS__); \ + } \ + } while (0) #if LIBCURL_VERSION_NUM >= 0x071000 /* The multi interface timer callback was introduced in 7.16.0 */ diff --git a/block/dmg.c b/block/dmg.c index a496eb7c9b..1ea5f22d82 100644 --- a/block/dmg.c +++ b/block/dmg.c @@ -440,6 +440,8 @@ static int dmg_open(BlockDriverState *bs, QDict *options, int flags, int ret; bs->read_only = 1; + bs->request_alignment = BDRV_SECTOR_SIZE; /* No sub-sector I/O supported */ + s->n_chunks = 0; s->offsets = s->lengths = s->sectors = s->sectorcounts = NULL; /* used by dmg_read_mish_block to keep track of the current I/O position */ @@ -659,38 +661,42 @@ static inline int dmg_read_chunk(BlockDriverState *bs, uint64_t sector_num) return 0; } -static int dmg_read(BlockDriverState *bs, int64_t sector_num, - uint8_t *buf, int nb_sectors) +static int coroutine_fn +dmg_co_preadv(BlockDriverState *bs, uint64_t offset, uint64_t bytes, + QEMUIOVector *qiov, int flags) { BDRVDMGState *s = bs->opaque; - int i; + uint64_t sector_num = offset >> BDRV_SECTOR_BITS; + int nb_sectors = bytes >> BDRV_SECTOR_BITS; + int ret, i; + + assert((offset & (BDRV_SECTOR_SIZE - 1)) == 0); + assert((bytes & (BDRV_SECTOR_SIZE - 1)) == 0); + + qemu_co_mutex_lock(&s->lock); for (i = 0; i < nb_sectors; i++) { uint32_t sector_offset_in_chunk; + void *data; + if (dmg_read_chunk(bs, sector_num + i) != 0) { - return -1; + ret = -EIO; + goto fail; } /* Special case: current chunk is all zeroes. Do not perform a memcpy as * s->uncompressed_chunk may be too small to cover the large all-zeroes * section. dmg_read_chunk is called to find s->current_chunk */ if (s->types[s->current_chunk] == 2) { /* all zeroes block entry */ - memset(buf + i * 512, 0, 512); + qemu_iovec_memset(qiov, i * 512, 0, 512); continue; } sector_offset_in_chunk = sector_num + i - s->sectors[s->current_chunk]; - memcpy(buf + i * 512, - s->uncompressed_chunk + sector_offset_in_chunk * 512, 512); + data = s->uncompressed_chunk + sector_offset_in_chunk * 512; + qemu_iovec_from_buf(qiov, i * 512, data, 512); } - return 0; -} -static coroutine_fn int dmg_co_read(BlockDriverState *bs, int64_t sector_num, - uint8_t *buf, int nb_sectors) -{ - int ret; - BDRVDMGState *s = bs->opaque; - qemu_co_mutex_lock(&s->lock); - ret = dmg_read(bs, sector_num, buf, nb_sectors); + ret = 0; +fail: qemu_co_mutex_unlock(&s->lock); return ret; } @@ -715,7 +721,7 @@ static BlockDriver bdrv_dmg = { .instance_size = sizeof(BDRVDMGState), .bdrv_probe = dmg_probe, .bdrv_open = dmg_open, - .bdrv_read = dmg_co_read, + .bdrv_co_preadv = dmg_co_preadv, .bdrv_close = dmg_close, }; diff --git a/block/io.c b/block/io.c index a7dbf85b19..cd6d71a503 100644 --- a/block/io.c +++ b/block/io.c @@ -34,18 +34,6 @@ #define NOT_DONE 0x7fffffff /* used while emulated sync operation in progress */ -static BlockAIOCB *bdrv_aio_readv_em(BlockDriverState *bs, - int64_t sector_num, QEMUIOVector *qiov, int nb_sectors, - BlockCompletionFunc *cb, void *opaque); -static BlockAIOCB *bdrv_aio_writev_em(BlockDriverState *bs, - int64_t sector_num, QEMUIOVector *qiov, int nb_sectors, - BlockCompletionFunc *cb, void *opaque); -static int coroutine_fn bdrv_co_readv_em(BlockDriverState *bs, - int64_t sector_num, int nb_sectors, - QEMUIOVector *iov); -static int coroutine_fn bdrv_co_writev_em(BlockDriverState *bs, - int64_t sector_num, int nb_sectors, - QEMUIOVector *iov); static BlockAIOCB *bdrv_co_aio_rw_vector(BlockDriverState *bs, int64_t sector_num, QEMUIOVector *qiov, @@ -62,48 +50,35 @@ static int coroutine_fn bdrv_co_do_write_zeroes(BlockDriverState *bs, void bdrv_set_io_limits(BlockDriverState *bs, ThrottleConfig *cfg) { - int i; - throttle_group_config(bs, cfg); - - for (i = 0; i < 2; i++) { - qemu_co_enter_next(&bs->throttled_reqs[i]); - } } -/* this function drain all the throttled IOs */ -static bool bdrv_start_throttled_reqs(BlockDriverState *bs) +void bdrv_no_throttling_begin(BlockDriverState *bs) { - bool drained = false; - bool enabled = bs->io_limits_enabled; - int i; - - bs->io_limits_enabled = false; - - for (i = 0; i < 2; i++) { - while (qemu_co_enter_next(&bs->throttled_reqs[i])) { - drained = true; - } + if (bs->io_limits_disabled++ == 0) { + throttle_group_restart_bs(bs); } +} - bs->io_limits_enabled = enabled; - - return drained; +void bdrv_no_throttling_end(BlockDriverState *bs) +{ + assert(bs->io_limits_disabled); + --bs->io_limits_disabled; } void bdrv_io_limits_disable(BlockDriverState *bs) { - bs->io_limits_enabled = false; - bdrv_start_throttled_reqs(bs); + assert(bs->throttle_state); + bdrv_no_throttling_begin(bs); throttle_group_unregister_bs(bs); + bdrv_no_throttling_end(bs); } /* should be called before bdrv_set_io_limits if a limit is set */ void bdrv_io_limits_enable(BlockDriverState *bs, const char *group) { - assert(!bs->io_limits_enabled); + assert(!bs->throttle_state); throttle_group_register_bs(bs, group); - bs->io_limits_enabled = true; } void bdrv_io_limits_update_group(BlockDriverState *bs, const char *group) @@ -123,24 +98,6 @@ void bdrv_io_limits_update_group(BlockDriverState *bs, const char *group) bdrv_io_limits_enable(bs, group); } -void bdrv_setup_io_funcs(BlockDriver *bdrv) -{ - /* Block drivers without coroutine functions need emulation */ - if (!bdrv->bdrv_co_readv) { - bdrv->bdrv_co_readv = bdrv_co_readv_em; - bdrv->bdrv_co_writev = bdrv_co_writev_em; - - /* bdrv_co_readv_em()/brdv_co_writev_em() work in terms of aio, so if - * the block driver lacks aio we need to emulate that too. - */ - if (!bdrv->bdrv_aio_readv) { - /* add AIO emulation layer */ - bdrv->bdrv_aio_readv = bdrv_aio_readv_em; - bdrv->bdrv_aio_writev = bdrv_aio_writev_em; - } - } -} - void bdrv_refresh_limits(BlockDriverState *bs, Error **errp) { BlockDriver *drv = bs->drv; @@ -260,18 +217,29 @@ typedef struct { bool done; } BdrvCoDrainData; +static void bdrv_drain_poll(BlockDriverState *bs) +{ + bool busy = true; + + while (busy) { + /* Keep iterating */ + busy = bdrv_requests_pending(bs); + busy |= aio_poll(bdrv_get_aio_context(bs), busy); + } +} + static void bdrv_co_drain_bh_cb(void *opaque) { BdrvCoDrainData *data = opaque; Coroutine *co = data->co; qemu_bh_delete(data->bh); - bdrv_drain(data->bs); + bdrv_drain_poll(data->bs); data->done = true; qemu_coroutine_enter(co, NULL); } -void coroutine_fn bdrv_co_drain(BlockDriverState *bs) +static void coroutine_fn bdrv_co_yield_to_drain(BlockDriverState *bs) { BdrvCoDrainData data; @@ -305,21 +273,28 @@ void coroutine_fn bdrv_co_drain(BlockDriverState *bs) * not depend on events in other AioContexts. In that case, use * bdrv_drain_all() instead. */ -void bdrv_drain(BlockDriverState *bs) +void coroutine_fn bdrv_co_drain(BlockDriverState *bs) { - bool busy = true; + bdrv_no_throttling_begin(bs); + bdrv_io_unplugged_begin(bs); + bdrv_drain_recurse(bs); + bdrv_co_yield_to_drain(bs); + bdrv_io_unplugged_end(bs); + bdrv_no_throttling_end(bs); +} +void bdrv_drain(BlockDriverState *bs) +{ + bdrv_no_throttling_begin(bs); + bdrv_io_unplugged_begin(bs); bdrv_drain_recurse(bs); if (qemu_in_coroutine()) { - bdrv_co_drain(bs); - return; - } - while (busy) { - /* Keep iterating */ - bdrv_flush_io_queue(bs); - busy = bdrv_requests_pending(bs); - busy |= aio_poll(bdrv_get_aio_context(bs), busy); + bdrv_co_yield_to_drain(bs); + } else { + bdrv_drain_poll(bs); } + bdrv_io_unplugged_end(bs); + bdrv_no_throttling_end(bs); } /* @@ -342,6 +317,8 @@ void bdrv_drain_all(void) if (bs->job) { block_job_pause(bs->job); } + bdrv_no_throttling_begin(bs); + bdrv_io_unplugged_begin(bs); bdrv_drain_recurse(bs); aio_context_release(aio_context); @@ -366,7 +343,6 @@ void bdrv_drain_all(void) aio_context_acquire(aio_context); while ((bs = bdrv_next(bs))) { if (aio_context == bdrv_get_aio_context(bs)) { - bdrv_flush_io_queue(bs); if (bdrv_requests_pending(bs)) { busy = true; aio_poll(aio_context, busy); @@ -383,6 +359,8 @@ void bdrv_drain_all(void) AioContext *aio_context = bdrv_get_aio_context(bs); aio_context_acquire(aio_context); + bdrv_io_unplugged_end(bs); + bdrv_no_throttling_end(bs); if (bs->job) { block_job_resume(bs->job); } @@ -581,13 +559,13 @@ static void coroutine_fn bdrv_rw_co_entry(void *opaque) RwCo *rwco = opaque; if (!rwco->is_write) { - rwco->ret = bdrv_co_do_preadv(rwco->bs, rwco->offset, - rwco->qiov->size, rwco->qiov, - rwco->flags); + rwco->ret = bdrv_co_preadv(rwco->bs, rwco->offset, + rwco->qiov->size, rwco->qiov, + rwco->flags); } else { - rwco->ret = bdrv_co_do_pwritev(rwco->bs, rwco->offset, - rwco->qiov->size, rwco->qiov, - rwco->flags); + rwco->ret = bdrv_co_pwritev(rwco->bs, rwco->offset, + rwco->qiov->size, rwco->qiov, + rwco->flags); } } @@ -608,17 +586,6 @@ static int bdrv_prwv_co(BlockDriverState *bs, int64_t offset, .flags = flags, }; - /** - * In sync call context, when the vcpu is blocked, this throttling timer - * will not fire; so the I/O throttling function has to be disabled here - * if it has been enabled. - */ - if (bs->io_limits_enabled) { - fprintf(stderr, "Disabling I/O throttling on '%s' due " - "to synchronous I/O.\n", bdrv_get_device_name(bs)); - bdrv_io_limits_disable(bs); - } - if (qemu_in_coroutine()) { /* Fast-path if already in coroutine context */ bdrv_rw_co_entry(&rwco); @@ -685,7 +652,8 @@ int bdrv_write_zeroes(BlockDriverState *bs, int64_t sector_num, * Completely zero out a block device with the help of bdrv_write_zeroes. * The operation is sped up by checking the block status and only writing * zeroes to the device if they currently do not return zeroes. Optional - * flags are passed through to bdrv_write_zeroes (e.g. BDRV_REQ_MAY_UNMAP). + * flags are passed through to bdrv_write_zeroes (e.g. BDRV_REQ_MAY_UNMAP, + * BDRV_REQ_FUA). * * Returns < 0 on error, 0 on success. For error codes see bdrv_write(). */ @@ -800,6 +768,109 @@ int bdrv_pwrite_sync(BlockDriverState *bs, int64_t offset, return 0; } +typedef struct CoroutineIOCompletion { + Coroutine *coroutine; + int ret; +} CoroutineIOCompletion; + +static void bdrv_co_io_em_complete(void *opaque, int ret) +{ + CoroutineIOCompletion *co = opaque; + + co->ret = ret; + qemu_coroutine_enter(co->coroutine, NULL); +} + +static int coroutine_fn bdrv_driver_preadv(BlockDriverState *bs, + uint64_t offset, uint64_t bytes, + QEMUIOVector *qiov, int flags) +{ + BlockDriver *drv = bs->drv; + int64_t sector_num; + unsigned int nb_sectors; + + if (drv->bdrv_co_preadv) { + return drv->bdrv_co_preadv(bs, offset, bytes, qiov, flags); + } + + sector_num = offset >> BDRV_SECTOR_BITS; + nb_sectors = bytes >> BDRV_SECTOR_BITS; + + assert((offset & (BDRV_SECTOR_SIZE - 1)) == 0); + assert((bytes & (BDRV_SECTOR_SIZE - 1)) == 0); + assert((bytes >> BDRV_SECTOR_BITS) <= BDRV_REQUEST_MAX_SECTORS); + + if (drv->bdrv_co_readv) { + return drv->bdrv_co_readv(bs, sector_num, nb_sectors, qiov); + } else { + BlockAIOCB *acb; + CoroutineIOCompletion co = { + .coroutine = qemu_coroutine_self(), + }; + + acb = bs->drv->bdrv_aio_readv(bs, sector_num, qiov, nb_sectors, + bdrv_co_io_em_complete, &co); + if (acb == NULL) { + return -EIO; + } else { + qemu_coroutine_yield(); + return co.ret; + } + } +} + +static int coroutine_fn bdrv_driver_pwritev(BlockDriverState *bs, + uint64_t offset, uint64_t bytes, + QEMUIOVector *qiov, int flags) +{ + BlockDriver *drv = bs->drv; + int64_t sector_num; + unsigned int nb_sectors; + int ret; + + if (drv->bdrv_co_pwritev) { + ret = drv->bdrv_co_pwritev(bs, offset, bytes, qiov, flags); + goto emulate_flags; + } + + sector_num = offset >> BDRV_SECTOR_BITS; + nb_sectors = bytes >> BDRV_SECTOR_BITS; + + assert((offset & (BDRV_SECTOR_SIZE - 1)) == 0); + assert((bytes & (BDRV_SECTOR_SIZE - 1)) == 0); + assert((bytes >> BDRV_SECTOR_BITS) <= BDRV_REQUEST_MAX_SECTORS); + + if (drv->bdrv_co_writev_flags) { + ret = drv->bdrv_co_writev_flags(bs, sector_num, nb_sectors, qiov, + flags & bs->supported_write_flags); + flags &= ~bs->supported_write_flags; + } else if (drv->bdrv_co_writev) { + assert(!bs->supported_write_flags); + ret = drv->bdrv_co_writev(bs, sector_num, nb_sectors, qiov); + } else { + BlockAIOCB *acb; + CoroutineIOCompletion co = { + .coroutine = qemu_coroutine_self(), + }; + + acb = bs->drv->bdrv_aio_writev(bs, sector_num, qiov, nb_sectors, + bdrv_co_io_em_complete, &co); + if (acb == NULL) { + ret = -EIO; + } else { + qemu_coroutine_yield(); + ret = co.ret; + } + } + +emulate_flags: + if (ret == 0 && (flags & BDRV_REQ_FUA)) { + ret = bdrv_co_flush(bs); + } + + return ret; +} + static int coroutine_fn bdrv_co_do_copy_on_readv(BlockDriverState *bs, int64_t sector_num, int nb_sectors, QEMUIOVector *qiov) { @@ -836,8 +907,9 @@ static int coroutine_fn bdrv_co_do_copy_on_readv(BlockDriverState *bs, qemu_iovec_init_external(&bounce_qiov, &iov, 1); - ret = drv->bdrv_co_readv(bs, cluster_sector_num, cluster_nb_sectors, - &bounce_qiov); + ret = bdrv_driver_preadv(bs, cluster_sector_num * BDRV_SECTOR_SIZE, + cluster_nb_sectors * BDRV_SECTOR_SIZE, + &bounce_qiov, 0); if (ret < 0) { goto err; } @@ -850,8 +922,9 @@ static int coroutine_fn bdrv_co_do_copy_on_readv(BlockDriverState *bs, /* This does not change the data on the disk, it is not necessary * to flush even in cache=writethrough mode. */ - ret = drv->bdrv_co_writev(bs, cluster_sector_num, cluster_nb_sectors, - &bounce_qiov); + ret = bdrv_driver_pwritev(bs, cluster_sector_num * BDRV_SECTOR_SIZE, + cluster_nb_sectors * BDRV_SECTOR_SIZE, + &bounce_qiov, 0); } if (ret < 0) { @@ -880,7 +953,6 @@ static int coroutine_fn bdrv_aligned_preadv(BlockDriverState *bs, BdrvTrackedRequest *req, int64_t offset, unsigned int bytes, int64_t align, QEMUIOVector *qiov, int flags) { - BlockDriver *drv = bs->drv; int ret; int64_t sector_num = offset >> BDRV_SECTOR_BITS; @@ -921,7 +993,7 @@ static int coroutine_fn bdrv_aligned_preadv(BlockDriverState *bs, /* Forward the request to the BlockDriver */ if (!bs->zero_beyond_eof) { - ret = drv->bdrv_co_readv(bs, sector_num, nb_sectors, qiov); + ret = bdrv_driver_preadv(bs, offset, bytes, qiov, 0); } else { /* Read zeros after EOF */ int64_t total_sectors, max_nb_sectors; @@ -935,7 +1007,7 @@ static int coroutine_fn bdrv_aligned_preadv(BlockDriverState *bs, max_nb_sectors = ROUND_UP(MAX(0, total_sectors - sector_num), align >> BDRV_SECTOR_BITS); if (nb_sectors < max_nb_sectors) { - ret = drv->bdrv_co_readv(bs, sector_num, nb_sectors, qiov); + ret = bdrv_driver_preadv(bs, offset, bytes, qiov, 0); } else if (max_nb_sectors > 0) { QEMUIOVector local_qiov; @@ -943,8 +1015,9 @@ static int coroutine_fn bdrv_aligned_preadv(BlockDriverState *bs, qemu_iovec_concat(&local_qiov, qiov, 0, max_nb_sectors * BDRV_SECTOR_SIZE); - ret = drv->bdrv_co_readv(bs, sector_num, max_nb_sectors, - &local_qiov); + ret = bdrv_driver_preadv(bs, offset, + max_nb_sectors * BDRV_SECTOR_SIZE, + &local_qiov, 0); qemu_iovec_destroy(&local_qiov); } else { @@ -967,7 +1040,7 @@ out: /* * Handle a read request in coroutine context */ -int coroutine_fn bdrv_co_do_preadv(BlockDriverState *bs, +int coroutine_fn bdrv_co_preadv(BlockDriverState *bs, int64_t offset, unsigned int bytes, QEMUIOVector *qiov, BdrvRequestFlags flags) { @@ -997,7 +1070,7 @@ int coroutine_fn bdrv_co_do_preadv(BlockDriverState *bs, } /* throttling disk I/O */ - if (bs->io_limits_enabled) { + if (bs->throttle_state) { throttle_group_co_io_limits_intercept(bs, bytes, false); } @@ -1049,8 +1122,8 @@ static int coroutine_fn bdrv_co_do_readv(BlockDriverState *bs, return -EINVAL; } - return bdrv_co_do_preadv(bs, sector_num << BDRV_SECTOR_BITS, - nb_sectors << BDRV_SECTOR_BITS, qiov, flags); + return bdrv_co_preadv(bs, sector_num << BDRV_SECTOR_BITS, + nb_sectors << BDRV_SECTOR_BITS, qiov, flags); } int coroutine_fn bdrv_co_readv(BlockDriverState *bs, int64_t sector_num, @@ -1088,6 +1161,7 @@ static int coroutine_fn bdrv_co_do_write_zeroes(BlockDriverState *bs, QEMUIOVector qiov; struct iovec iov = {0}; int ret = 0; + bool need_flush = false; int max_write_zeroes = MIN_NON_ZERO(bs->bl.max_write_zeroes, BDRV_REQUEST_MAX_SECTORS); @@ -1120,13 +1194,29 @@ static int coroutine_fn bdrv_co_do_write_zeroes(BlockDriverState *bs, ret = -ENOTSUP; /* First try the efficient write zeroes operation */ if (drv->bdrv_co_write_zeroes) { - ret = drv->bdrv_co_write_zeroes(bs, sector_num, num, flags); + ret = drv->bdrv_co_write_zeroes(bs, sector_num, num, + flags & bs->supported_zero_flags); + if (ret != -ENOTSUP && (flags & BDRV_REQ_FUA) && + !(bs->supported_zero_flags & BDRV_REQ_FUA)) { + need_flush = true; + } + } else { + assert(!bs->supported_zero_flags); } if (ret == -ENOTSUP) { /* Fall back to bounce buffer if write zeroes is unsupported */ int max_xfer_len = MIN_NON_ZERO(bs->bl.max_transfer_length, MAX_WRITE_ZEROES_BOUNCE_BUFFER); + BdrvRequestFlags write_flags = flags & ~BDRV_REQ_ZERO_WRITE; + + if ((flags & BDRV_REQ_FUA) && + !(bs->supported_write_flags & BDRV_REQ_FUA)) { + /* No need for bdrv_driver_pwrite() to do a fallback + * flush on each chunk; use just one at the end */ + write_flags &= ~BDRV_REQ_FUA; + need_flush = true; + } num = MIN(num, max_xfer_len); iov.iov_len = num * BDRV_SECTOR_SIZE; if (iov.iov_base == NULL) { @@ -1139,7 +1229,9 @@ static int coroutine_fn bdrv_co_do_write_zeroes(BlockDriverState *bs, } qemu_iovec_init_external(&qiov, &iov, 1); - ret = drv->bdrv_co_writev(bs, sector_num, num, &qiov); + ret = bdrv_driver_pwritev(bs, sector_num * BDRV_SECTOR_SIZE, + num * BDRV_SECTOR_SIZE, &qiov, + write_flags); /* Keep bounce buffer around if it is big enough for all * all future requests. @@ -1155,6 +1247,9 @@ static int coroutine_fn bdrv_co_do_write_zeroes(BlockDriverState *bs, } fail: + if (ret == 0 && need_flush) { + ret = bdrv_co_flush(bs); + } qemu_vfree(iov.iov_base); return ret; } @@ -1199,23 +1294,12 @@ static int coroutine_fn bdrv_aligned_pwritev(BlockDriverState *bs, } else if (flags & BDRV_REQ_ZERO_WRITE) { bdrv_debug_event(bs, BLKDBG_PWRITEV_ZERO); ret = bdrv_co_do_write_zeroes(bs, sector_num, nb_sectors, flags); - } else if (drv->bdrv_co_writev_flags) { - bdrv_debug_event(bs, BLKDBG_PWRITEV); - ret = drv->bdrv_co_writev_flags(bs, sector_num, nb_sectors, qiov, - flags); } else { - assert(drv->supported_write_flags == 0); bdrv_debug_event(bs, BLKDBG_PWRITEV); - ret = drv->bdrv_co_writev(bs, sector_num, nb_sectors, qiov); + ret = bdrv_driver_pwritev(bs, offset, bytes, qiov, flags); } bdrv_debug_event(bs, BLKDBG_PWRITEV_DONE); - if (ret == 0 && (flags & BDRV_REQ_FUA) && - !(drv->supported_write_flags & BDRV_REQ_FUA)) - { - ret = bdrv_co_flush(bs); - } - bdrv_set_dirty(bs, sector_num, nb_sectors); if (bs->wr_highest_offset < offset + bytes) { @@ -1320,7 +1404,7 @@ fail: /* * Handle a write request in coroutine context */ -int coroutine_fn bdrv_co_do_pwritev(BlockDriverState *bs, +int coroutine_fn bdrv_co_pwritev(BlockDriverState *bs, int64_t offset, unsigned int bytes, QEMUIOVector *qiov, BdrvRequestFlags flags) { @@ -1347,7 +1431,7 @@ int coroutine_fn bdrv_co_do_pwritev(BlockDriverState *bs, } /* throttling disk I/O */ - if (bs->io_limits_enabled) { + if (bs->throttle_state) { throttle_group_co_io_limits_intercept(bs, bytes, true); } @@ -1455,8 +1539,8 @@ static int coroutine_fn bdrv_co_do_writev(BlockDriverState *bs, return -EINVAL; } - return bdrv_co_do_pwritev(bs, sector_num << BDRV_SECTOR_BITS, - nb_sectors << BDRV_SECTOR_BITS, qiov, flags); + return bdrv_co_pwritev(bs, sector_num << BDRV_SECTOR_BITS, + nb_sectors << BDRV_SECTOR_BITS, qiov, flags); } int coroutine_fn bdrv_co_writev(BlockDriverState *bs, int64_t sector_num, @@ -2064,80 +2148,6 @@ void bdrv_aio_cancel_async(BlockAIOCB *acb) /**************************************************************/ /* async block device emulation */ -typedef struct BlockAIOCBSync { - BlockAIOCB common; - QEMUBH *bh; - int ret; - /* vector translation state */ - QEMUIOVector *qiov; - uint8_t *bounce; - int is_write; -} BlockAIOCBSync; - -static const AIOCBInfo bdrv_em_aiocb_info = { - .aiocb_size = sizeof(BlockAIOCBSync), -}; - -static void bdrv_aio_bh_cb(void *opaque) -{ - BlockAIOCBSync *acb = opaque; - - if (!acb->is_write && acb->ret >= 0) { - qemu_iovec_from_buf(acb->qiov, 0, acb->bounce, acb->qiov->size); - } - qemu_vfree(acb->bounce); - acb->common.cb(acb->common.opaque, acb->ret); - qemu_bh_delete(acb->bh); - acb->bh = NULL; - qemu_aio_unref(acb); -} - -static BlockAIOCB *bdrv_aio_rw_vector(BlockDriverState *bs, - int64_t sector_num, - QEMUIOVector *qiov, - int nb_sectors, - BlockCompletionFunc *cb, - void *opaque, - int is_write) - -{ - BlockAIOCBSync *acb; - - acb = qemu_aio_get(&bdrv_em_aiocb_info, bs, cb, opaque); - acb->is_write = is_write; - acb->qiov = qiov; - acb->bounce = qemu_try_blockalign(bs, qiov->size); - acb->bh = aio_bh_new(bdrv_get_aio_context(bs), bdrv_aio_bh_cb, acb); - - if (acb->bounce == NULL) { - acb->ret = -ENOMEM; - } else if (is_write) { - qemu_iovec_to_buf(acb->qiov, 0, acb->bounce, qiov->size); - acb->ret = bs->drv->bdrv_write(bs, sector_num, acb->bounce, nb_sectors); - } else { - acb->ret = bs->drv->bdrv_read(bs, sector_num, acb->bounce, nb_sectors); - } - - qemu_bh_schedule(acb->bh); - - return &acb->common; -} - -static BlockAIOCB *bdrv_aio_readv_em(BlockDriverState *bs, - int64_t sector_num, QEMUIOVector *qiov, int nb_sectors, - BlockCompletionFunc *cb, void *opaque) -{ - return bdrv_aio_rw_vector(bs, sector_num, qiov, nb_sectors, cb, opaque, 0); -} - -static BlockAIOCB *bdrv_aio_writev_em(BlockDriverState *bs, - int64_t sector_num, QEMUIOVector *qiov, int nb_sectors, - BlockCompletionFunc *cb, void *opaque) -{ - return bdrv_aio_rw_vector(bs, sector_num, qiov, nb_sectors, cb, opaque, 1); -} - - typedef struct BlockAIOCBCoroutine { BlockAIOCB common; BlockRequest req; @@ -2314,59 +2324,6 @@ void qemu_aio_unref(void *p) /**************************************************************/ /* Coroutine block device emulation */ -typedef struct CoroutineIOCompletion { - Coroutine *coroutine; - int ret; -} CoroutineIOCompletion; - -static void bdrv_co_io_em_complete(void *opaque, int ret) -{ - CoroutineIOCompletion *co = opaque; - - co->ret = ret; - qemu_coroutine_enter(co->coroutine, NULL); -} - -static int coroutine_fn bdrv_co_io_em(BlockDriverState *bs, int64_t sector_num, - int nb_sectors, QEMUIOVector *iov, - bool is_write) -{ - CoroutineIOCompletion co = { - .coroutine = qemu_coroutine_self(), - }; - BlockAIOCB *acb; - - if (is_write) { - acb = bs->drv->bdrv_aio_writev(bs, sector_num, iov, nb_sectors, - bdrv_co_io_em_complete, &co); - } else { - acb = bs->drv->bdrv_aio_readv(bs, sector_num, iov, nb_sectors, - bdrv_co_io_em_complete, &co); - } - - trace_bdrv_co_io_em(bs, sector_num, nb_sectors, is_write, acb); - if (!acb) { - return -EIO; - } - qemu_coroutine_yield(); - - return co.ret; -} - -static int coroutine_fn bdrv_co_readv_em(BlockDriverState *bs, - int64_t sector_num, int nb_sectors, - QEMUIOVector *iov) -{ - return bdrv_co_io_em(bs, sector_num, nb_sectors, iov, false); -} - -static int coroutine_fn bdrv_co_writev_em(BlockDriverState *bs, - int64_t sector_num, int nb_sectors, - QEMUIOVector *iov) -{ - return bdrv_co_io_em(bs, sector_num, nb_sectors, iov, true); -} - static void coroutine_fn bdrv_flush_co_entry(void *opaque) { RwCo *rwco = opaque; @@ -2763,33 +2720,68 @@ void bdrv_add_before_write_notifier(BlockDriverState *bs, void bdrv_io_plug(BlockDriverState *bs) { - BlockDriver *drv = bs->drv; - if (drv && drv->bdrv_io_plug) { - drv->bdrv_io_plug(bs); - } else if (bs->file) { - bdrv_io_plug(bs->file->bs); + BdrvChild *child; + + QLIST_FOREACH(child, &bs->children, next) { + bdrv_io_plug(child->bs); + } + + if (bs->io_plugged++ == 0 && bs->io_plug_disabled == 0) { + BlockDriver *drv = bs->drv; + if (drv && drv->bdrv_io_plug) { + drv->bdrv_io_plug(bs); + } } } void bdrv_io_unplug(BlockDriverState *bs) { - BlockDriver *drv = bs->drv; - if (drv && drv->bdrv_io_unplug) { - drv->bdrv_io_unplug(bs); - } else if (bs->file) { - bdrv_io_unplug(bs->file->bs); + BdrvChild *child; + + assert(bs->io_plugged); + if (--bs->io_plugged == 0 && bs->io_plug_disabled == 0) { + BlockDriver *drv = bs->drv; + if (drv && drv->bdrv_io_unplug) { + drv->bdrv_io_unplug(bs); + } + } + + QLIST_FOREACH(child, &bs->children, next) { + bdrv_io_unplug(child->bs); } } -void bdrv_flush_io_queue(BlockDriverState *bs) +void bdrv_io_unplugged_begin(BlockDriverState *bs) { - BlockDriver *drv = bs->drv; - if (drv && drv->bdrv_flush_io_queue) { - drv->bdrv_flush_io_queue(bs); - } else if (bs->file) { - bdrv_flush_io_queue(bs->file->bs); + BdrvChild *child; + + if (bs->io_plug_disabled++ == 0 && bs->io_plugged > 0) { + BlockDriver *drv = bs->drv; + if (drv && drv->bdrv_io_unplug) { + drv->bdrv_io_unplug(bs); + } + } + + QLIST_FOREACH(child, &bs->children, next) { + bdrv_io_unplugged_begin(child->bs); + } +} + +void bdrv_io_unplugged_end(BlockDriverState *bs) +{ + BdrvChild *child; + + assert(bs->io_plug_disabled); + QLIST_FOREACH(child, &bs->children, next) { + bdrv_io_unplugged_end(child->bs); + } + + if (--bs->io_plug_disabled == 0 && bs->io_plugged > 0) { + BlockDriver *drv = bs->drv; + if (drv && drv->bdrv_io_plug) { + drv->bdrv_io_plug(bs); + } } - bdrv_start_throttled_reqs(bs); } void bdrv_drained_begin(BlockDriverState *bs) diff --git a/block/iscsi.c b/block/iscsi.c index 302baf84c1..10f3906bcc 100644 --- a/block/iscsi.c +++ b/block/iscsi.c @@ -456,8 +456,11 @@ iscsi_co_writev_flags(BlockDriverState *bs, int64_t sector_num, int nb_sectors, struct IscsiTask iTask; uint64_t lba; uint32_t num_sectors; - bool fua; + bool fua = flags & BDRV_REQ_FUA; + if (fua) { + assert(iscsilun->dpofua); + } if (!is_request_lun_aligned(sector_num, nb_sectors, iscsilun)) { return -EINVAL; } @@ -472,7 +475,6 @@ iscsi_co_writev_flags(BlockDriverState *bs, int64_t sector_num, int nb_sectors, num_sectors = sector_qemu2lun(nb_sectors, iscsilun); iscsi_co_init_iscsitask(iscsilun, &iTask); retry: - fua = iscsilun->dpofua && (flags & BDRV_REQ_FUA); if (iscsilun->use_16_for_rw) { iTask.task = iscsi_write16_task(iscsilun->iscsi, iscsilun->lun, lba, NULL, num_sectors * iscsilun->block_size, @@ -513,13 +515,6 @@ retry: return 0; } -static int coroutine_fn -iscsi_co_writev(BlockDriverState *bs, int64_t sector_num, int nb_sectors, - QEMUIOVector *iov) -{ - return iscsi_co_writev_flags(bs, sector_num, nb_sectors, iov, 0); -} - static bool iscsi_allocationmap_is_allocated(IscsiLun *iscsilun, int64_t sector_num, int nb_sectors) @@ -1555,6 +1550,10 @@ static int iscsi_open(BlockDriverState *bs, QDict *options, int flags, task = NULL; iscsi_modesense_sync(iscsilun); + if (iscsilun->dpofua) { + bs->supported_write_flags = BDRV_REQ_FUA; + } + bs->supported_zero_flags = BDRV_REQ_MAY_UNMAP; /* Check the write protect flag of the LUN if we want to write */ if (iscsilun->type == TYPE_DISK && (flags & BDRV_O_RDWR) && @@ -1847,9 +1846,7 @@ static BlockDriver bdrv_iscsi = { .bdrv_co_discard = iscsi_co_discard, .bdrv_co_write_zeroes = iscsi_co_write_zeroes, .bdrv_co_readv = iscsi_co_readv, - .bdrv_co_writev = iscsi_co_writev, .bdrv_co_writev_flags = iscsi_co_writev_flags, - .supported_write_flags = BDRV_REQ_FUA, .bdrv_co_flush_to_disk = iscsi_co_flush, #ifdef __linux__ diff --git a/block/linux-aio.c b/block/linux-aio.c index 805757e02e..90ec98ee23 100644 --- a/block/linux-aio.c +++ b/block/linux-aio.c @@ -30,7 +30,7 @@ struct qemu_laiocb { BlockAIOCB common; - struct qemu_laio_state *ctx; + LinuxAioState *ctx; struct iocb iocb; ssize_t ret; size_t nbytes; @@ -46,7 +46,7 @@ typedef struct { QSIMPLEQ_HEAD(, qemu_laiocb) pending; } LaioQueue; -struct qemu_laio_state { +struct LinuxAioState { io_context_t ctx; EventNotifier e; @@ -60,7 +60,7 @@ struct qemu_laio_state { int event_max; }; -static void ioq_submit(struct qemu_laio_state *s); +static void ioq_submit(LinuxAioState *s); static inline ssize_t io_event_ret(struct io_event *ev) { @@ -70,8 +70,7 @@ static inline ssize_t io_event_ret(struct io_event *ev) /* * Completes an AIO request (calls the callback and frees the ACB). */ -static void qemu_laio_process_completion(struct qemu_laio_state *s, - struct qemu_laiocb *laiocb) +static void qemu_laio_process_completion(struct qemu_laiocb *laiocb) { int ret; @@ -99,7 +98,7 @@ static void qemu_laio_process_completion(struct qemu_laio_state *s, * * The function is somewhat tricky because it supports nested event loops, for * example when a request callback invokes aio_poll(). In order to do this, - * the completion events array and index are kept in qemu_laio_state. The BH + * the completion events array and index are kept in LinuxAioState. The BH * reschedules itself as long as there are completions pending so it will * either be called again in a nested event loop or will be called after all * events have been completed. When there are no events left to complete, the @@ -107,7 +106,7 @@ static void qemu_laio_process_completion(struct qemu_laio_state *s, */ static void qemu_laio_completion_bh(void *opaque) { - struct qemu_laio_state *s = opaque; + LinuxAioState *s = opaque; /* Fetch more completion events when empty */ if (s->event_idx == s->event_max) { @@ -136,7 +135,7 @@ static void qemu_laio_completion_bh(void *opaque) laiocb->ret = io_event_ret(&s->events[s->event_idx]); s->event_idx++; - qemu_laio_process_completion(s, laiocb); + qemu_laio_process_completion(laiocb); } if (!s->io_q.plugged && !QSIMPLEQ_EMPTY(&s->io_q.pending)) { @@ -146,7 +145,7 @@ static void qemu_laio_completion_bh(void *opaque) static void qemu_laio_completion_cb(EventNotifier *e) { - struct qemu_laio_state *s = container_of(e, struct qemu_laio_state, e); + LinuxAioState *s = container_of(e, LinuxAioState, e); if (event_notifier_test_and_clear(&s->e)) { qemu_bh_schedule(s->completion_bh); @@ -185,7 +184,7 @@ static void ioq_init(LaioQueue *io_q) io_q->blocked = false; } -static void ioq_submit(struct qemu_laio_state *s) +static void ioq_submit(LinuxAioState *s) { int ret, len; struct qemu_laiocb *aiocb; @@ -216,33 +215,25 @@ static void ioq_submit(struct qemu_laio_state *s) s->io_q.blocked = (s->io_q.n > 0); } -void laio_io_plug(BlockDriverState *bs, void *aio_ctx) +void laio_io_plug(BlockDriverState *bs, LinuxAioState *s) { - struct qemu_laio_state *s = aio_ctx; - - s->io_q.plugged++; + assert(!s->io_q.plugged); + s->io_q.plugged = 1; } -void laio_io_unplug(BlockDriverState *bs, void *aio_ctx, bool unplug) +void laio_io_unplug(BlockDriverState *bs, LinuxAioState *s) { - struct qemu_laio_state *s = aio_ctx; - - assert(s->io_q.plugged > 0 || !unplug); - - if (unplug && --s->io_q.plugged > 0) { - return; - } - + assert(s->io_q.plugged); + s->io_q.plugged = 0; if (!s->io_q.blocked && !QSIMPLEQ_EMPTY(&s->io_q.pending)) { ioq_submit(s); } } -BlockAIOCB *laio_submit(BlockDriverState *bs, void *aio_ctx, int fd, +BlockAIOCB *laio_submit(BlockDriverState *bs, LinuxAioState *s, int fd, int64_t sector_num, QEMUIOVector *qiov, int nb_sectors, BlockCompletionFunc *cb, void *opaque, int type) { - struct qemu_laio_state *s = aio_ctx; struct qemu_laiocb *laiocb; struct iocb *iocbs; off_t offset = sector_num * 512; @@ -284,26 +275,22 @@ out_free_aiocb: return NULL; } -void laio_detach_aio_context(void *s_, AioContext *old_context) +void laio_detach_aio_context(LinuxAioState *s, AioContext *old_context) { - struct qemu_laio_state *s = s_; - aio_set_event_notifier(old_context, &s->e, false, NULL); qemu_bh_delete(s->completion_bh); } -void laio_attach_aio_context(void *s_, AioContext *new_context) +void laio_attach_aio_context(LinuxAioState *s, AioContext *new_context) { - struct qemu_laio_state *s = s_; - s->completion_bh = aio_bh_new(new_context, qemu_laio_completion_bh, s); aio_set_event_notifier(new_context, &s->e, false, qemu_laio_completion_cb); } -void *laio_init(void) +LinuxAioState *laio_init(void) { - struct qemu_laio_state *s; + LinuxAioState *s; s = g_malloc0(sizeof(*s)); if (event_notifier_init(&s->e, false) < 0) { @@ -325,10 +312,8 @@ out_free_state: return NULL; } -void laio_cleanup(void *s_) +void laio_cleanup(LinuxAioState *s) { - struct qemu_laio_state *s = s_; - event_notifier_cleanup(&s->e); if (io_destroy(s->ctx) != 0) { diff --git a/block/nbd-client.c b/block/nbd-client.c index 878e879ace..4d13444409 100644 --- a/block/nbd-client.c +++ b/block/nbd-client.c @@ -243,15 +243,15 @@ static int nbd_co_readv_1(BlockDriverState *bs, int64_t sector_num, static int nbd_co_writev_1(BlockDriverState *bs, int64_t sector_num, int nb_sectors, QEMUIOVector *qiov, - int offset, int *flags) + int offset, int flags) { NbdClientSession *client = nbd_get_client_session(bs); struct nbd_request request = { .type = NBD_CMD_WRITE }; struct nbd_reply reply; ssize_t ret; - if ((*flags & BDRV_REQ_FUA) && (client->nbdflags & NBD_FLAG_SEND_FUA)) { - *flags &= ~BDRV_REQ_FUA; + if (flags & BDRV_REQ_FUA) { + assert(client->nbdflags & NBD_FLAG_SEND_FUA); request.type |= NBD_CMD_FLAG_FUA; } @@ -291,7 +291,7 @@ int nbd_client_co_readv(BlockDriverState *bs, int64_t sector_num, } int nbd_client_co_writev(BlockDriverState *bs, int64_t sector_num, - int nb_sectors, QEMUIOVector *qiov, int *flags) + int nb_sectors, QEMUIOVector *qiov, int flags) { int offset = 0; int ret; @@ -414,6 +414,9 @@ int nbd_client_init(BlockDriverState *bs, logout("Failed to negotiate with the NBD server\n"); return ret; } + if (client->nbdflags & NBD_FLAG_SEND_FUA) { + bs->supported_write_flags = BDRV_REQ_FUA; + } qemu_co_mutex_init(&client->send_mutex); qemu_co_mutex_init(&client->free_sema); diff --git a/block/nbd-client.h b/block/nbd-client.h index bc7aec0795..c618dadc39 100644 --- a/block/nbd-client.h +++ b/block/nbd-client.h @@ -48,7 +48,7 @@ int nbd_client_co_discard(BlockDriverState *bs, int64_t sector_num, int nb_sectors); int nbd_client_co_flush(BlockDriverState *bs); int nbd_client_co_writev(BlockDriverState *bs, int64_t sector_num, - int nb_sectors, QEMUIOVector *qiov, int *flags); + int nb_sectors, QEMUIOVector *qiov, int flags); int nbd_client_co_readv(BlockDriverState *bs, int64_t sector_num, int nb_sectors, QEMUIOVector *qiov); diff --git a/block/nbd.c b/block/nbd.c index f7ea3b3608..6015e8b537 100644 --- a/block/nbd.c +++ b/block/nbd.c @@ -355,31 +355,6 @@ static int nbd_co_readv(BlockDriverState *bs, int64_t sector_num, return nbd_client_co_readv(bs, sector_num, nb_sectors, qiov); } -static int nbd_co_writev_flags(BlockDriverState *bs, int64_t sector_num, - int nb_sectors, QEMUIOVector *qiov, int flags) -{ - int ret; - - ret = nbd_client_co_writev(bs, sector_num, nb_sectors, qiov, &flags); - if (ret < 0) { - return ret; - } - - /* The flag wasn't sent to the server, so we need to emulate it with an - * explicit flush */ - if (flags & BDRV_REQ_FUA) { - ret = nbd_client_co_flush(bs); - } - - return ret; -} - -static int nbd_co_writev(BlockDriverState *bs, int64_t sector_num, - int nb_sectors, QEMUIOVector *qiov) -{ - return nbd_co_writev_flags(bs, sector_num, nb_sectors, qiov, 0); -} - static int nbd_co_flush(BlockDriverState *bs) { return nbd_client_co_flush(bs); @@ -476,9 +451,7 @@ static BlockDriver bdrv_nbd = { .bdrv_parse_filename = nbd_parse_filename, .bdrv_file_open = nbd_open, .bdrv_co_readv = nbd_co_readv, - .bdrv_co_writev = nbd_co_writev, - .bdrv_co_writev_flags = nbd_co_writev_flags, - .supported_write_flags = BDRV_REQ_FUA, + .bdrv_co_writev_flags = nbd_client_co_writev, .bdrv_close = nbd_close, .bdrv_co_flush_to_os = nbd_co_flush, .bdrv_co_discard = nbd_co_discard, @@ -496,9 +469,7 @@ static BlockDriver bdrv_nbd_tcp = { .bdrv_parse_filename = nbd_parse_filename, .bdrv_file_open = nbd_open, .bdrv_co_readv = nbd_co_readv, - .bdrv_co_writev = nbd_co_writev, - .bdrv_co_writev_flags = nbd_co_writev_flags, - .supported_write_flags = BDRV_REQ_FUA, + .bdrv_co_writev_flags = nbd_client_co_writev, .bdrv_close = nbd_close, .bdrv_co_flush_to_os = nbd_co_flush, .bdrv_co_discard = nbd_co_discard, @@ -516,9 +487,7 @@ static BlockDriver bdrv_nbd_unix = { .bdrv_parse_filename = nbd_parse_filename, .bdrv_file_open = nbd_open, .bdrv_co_readv = nbd_co_readv, - .bdrv_co_writev = nbd_co_writev, - .bdrv_co_writev_flags = nbd_co_writev_flags, - .supported_write_flags = BDRV_REQ_FUA, + .bdrv_co_writev_flags = nbd_client_co_writev, .bdrv_close = nbd_close, .bdrv_co_flush_to_os = nbd_co_flush, .bdrv_co_discard = nbd_co_discard, diff --git a/block/parallels.c b/block/parallels.c index 324ed43ac4..cddbfc4012 100644 --- a/block/parallels.c +++ b/block/parallels.c @@ -512,11 +512,12 @@ static int parallels_create(const char *filename, QemuOpts *opts, Error **errp) memset(tmp, 0, sizeof(tmp)); memcpy(tmp, &header, sizeof(header)); - ret = blk_pwrite(file, 0, tmp, BDRV_SECTOR_SIZE); + ret = blk_pwrite(file, 0, tmp, BDRV_SECTOR_SIZE, 0); if (ret < 0) { goto exit; } - ret = blk_write_zeroes(file, 1, bat_sectors - 1, 0); + ret = blk_write_zeroes(file, BDRV_SECTOR_SIZE, + (bat_sectors - 1) << BDRV_SECTOR_BITS, 0); if (ret < 0) { goto exit; } diff --git a/block/qcow.c b/block/qcow.c index 60ddb12eca..d6dc1b05b3 100644 --- a/block/qcow.c +++ b/block/qcow.c @@ -853,14 +853,14 @@ static int qcow_create(const char *filename, QemuOpts *opts, Error **errp) } /* write all the data */ - ret = blk_pwrite(qcow_blk, 0, &header, sizeof(header)); + ret = blk_pwrite(qcow_blk, 0, &header, sizeof(header), 0); if (ret != sizeof(header)) { goto exit; } if (backing_file) { ret = blk_pwrite(qcow_blk, sizeof(header), - backing_file, backing_filename_len); + backing_file, backing_filename_len, 0); if (ret != backing_filename_len) { goto exit; } @@ -869,8 +869,8 @@ static int qcow_create(const char *filename, QemuOpts *opts, Error **errp) tmp = g_malloc0(BDRV_SECTOR_SIZE); for (i = 0; i < ((sizeof(uint64_t)*l1_size + BDRV_SECTOR_SIZE - 1)/ BDRV_SECTOR_SIZE); i++) { - ret = blk_pwrite(qcow_blk, header_size + - BDRV_SECTOR_SIZE*i, tmp, BDRV_SECTOR_SIZE); + ret = blk_pwrite(qcow_blk, header_size + BDRV_SECTOR_SIZE * i, + tmp, BDRV_SECTOR_SIZE, 0); if (ret != BDRV_SECTOR_SIZE) { g_free(tmp); goto exit; diff --git a/block/qcow2.c b/block/qcow2.c index 470734be9f..62febfc386 100644 --- a/block/qcow2.c +++ b/block/qcow2.c @@ -1757,13 +1757,6 @@ static void qcow2_invalidate_cache(BlockDriverState *bs, Error **errp) qcow2_close(bs); - bdrv_invalidate_cache(bs->file->bs, &local_err); - if (local_err) { - error_propagate(errp, local_err); - bs->drv = NULL; - return; - } - memset(s, 0, sizeof(BDRVQcow2State)); options = qdict_clone_shallow(bs->options); @@ -2207,7 +2200,7 @@ static int qcow2_create2(const char *filename, int64_t total_size, cpu_to_be64(QCOW2_COMPAT_LAZY_REFCOUNTS); } - ret = blk_pwrite(blk, 0, header, cluster_size); + ret = blk_pwrite(blk, 0, header, cluster_size, 0); g_free(header); if (ret < 0) { error_setg_errno(errp, -ret, "Could not write qcow2 header"); @@ -2217,7 +2210,7 @@ static int qcow2_create2(const char *filename, int64_t total_size, /* Write a refcount table with one refcount block */ refcount_table = g_malloc0(2 * cluster_size); refcount_table[0] = cpu_to_be64(2 * cluster_size); - ret = blk_pwrite(blk, cluster_size, refcount_table, 2 * cluster_size); + ret = blk_pwrite(blk, cluster_size, refcount_table, 2 * cluster_size, 0); g_free(refcount_table); if (ret < 0) { @@ -2411,21 +2404,74 @@ finish: return ret; } + +static bool is_zero_cluster(BlockDriverState *bs, int64_t start) +{ + BDRVQcow2State *s = bs->opaque; + int nr; + BlockDriverState *file; + int64_t res = bdrv_get_block_status_above(bs, NULL, start, + s->cluster_sectors, &nr, &file); + return res >= 0 && ((res & BDRV_BLOCK_ZERO) || !(res & BDRV_BLOCK_DATA)); +} + +static bool is_zero_cluster_top_locked(BlockDriverState *bs, int64_t start) +{ + BDRVQcow2State *s = bs->opaque; + int nr = s->cluster_sectors; + uint64_t off; + int ret; + + ret = qcow2_get_cluster_offset(bs, start << BDRV_SECTOR_BITS, &nr, &off); + return ret == QCOW2_CLUSTER_UNALLOCATED || ret == QCOW2_CLUSTER_ZERO; +} + static coroutine_fn int qcow2_co_write_zeroes(BlockDriverState *bs, int64_t sector_num, int nb_sectors, BdrvRequestFlags flags) { int ret; BDRVQcow2State *s = bs->opaque; - /* Emulate misaligned zero writes */ - if (sector_num % s->cluster_sectors || nb_sectors % s->cluster_sectors) { - return -ENOTSUP; + int head = sector_num % s->cluster_sectors; + int tail = (sector_num + nb_sectors) % s->cluster_sectors; + + if (head != 0 || tail != 0) { + int64_t cl_end = -1; + + sector_num -= head; + nb_sectors += head; + + if (tail != 0) { + nb_sectors += s->cluster_sectors - tail; + } + + if (!is_zero_cluster(bs, sector_num)) { + return -ENOTSUP; + } + + if (nb_sectors > s->cluster_sectors) { + /* Technically the request can cover 2 clusters, f.e. 4k write + at s->cluster_sectors - 2k offset. One of these cluster can + be zeroed, one unallocated */ + cl_end = sector_num + nb_sectors - s->cluster_sectors; + if (!is_zero_cluster(bs, cl_end)) { + return -ENOTSUP; + } + } + + qemu_co_mutex_lock(&s->lock); + /* We can have new write after previous check */ + if (!is_zero_cluster_top_locked(bs, sector_num) || + (cl_end > 0 && !is_zero_cluster_top_locked(bs, cl_end))) { + qemu_co_mutex_unlock(&s->lock); + return -ENOTSUP; + } + } else { + qemu_co_mutex_lock(&s->lock); } /* Whatever is left can use real zero clusters */ - qemu_co_mutex_lock(&s->lock); - ret = qcow2_zero_clusters(bs, sector_num << BDRV_SECTOR_BITS, - nb_sectors); + ret = qcow2_zero_clusters(bs, sector_num << BDRV_SECTOR_BITS, nb_sectors); qemu_co_mutex_unlock(&s->lock); return ret; diff --git a/block/qed.c b/block/qed.c index 0af52741df..10ce18eb66 100644 --- a/block/qed.c +++ b/block/qed.c @@ -601,18 +601,18 @@ static int qed_create(const char *filename, uint32_t cluster_size, } qed_header_cpu_to_le(&header, &le_header); - ret = blk_pwrite(blk, 0, &le_header, sizeof(le_header)); + ret = blk_pwrite(blk, 0, &le_header, sizeof(le_header), 0); if (ret < 0) { goto out; } ret = blk_pwrite(blk, sizeof(le_header), backing_file, - header.backing_filename_size); + header.backing_filename_size, 0); if (ret < 0) { goto out; } l1_table = g_malloc0(l1_size); - ret = blk_pwrite(blk, header.l1_table_offset, l1_table, l1_size); + ret = blk_pwrite(blk, header.l1_table_offset, l1_table, l1_size, 0); if (ret < 0) { goto out; } @@ -1594,12 +1594,6 @@ static void bdrv_qed_invalidate_cache(BlockDriverState *bs, Error **errp) bdrv_qed_close(bs); - bdrv_invalidate_cache(bs->file->bs, &local_err); - if (local_err) { - error_propagate(errp, local_err); - return; - } - memset(s, 0, sizeof(BDRVQEDState)); ret = bdrv_qed_open(bs, NULL, bs->open_flags, &local_err); if (local_err) { diff --git a/block/quorum.c b/block/quorum.c index da15465a9a..1ec3511528 100644 --- a/block/quorum.c +++ b/block/quorum.c @@ -14,6 +14,7 @@ */ #include "qemu/osdep.h" +#include "qemu/cutils.h" #include "block/block_int.h" #include "qapi/qmp/qbool.h" #include "qapi/qmp/qdict.h" @@ -67,6 +68,9 @@ typedef struct QuorumVotes { typedef struct BDRVQuorumState { BdrvChild **children; /* children BlockDriverStates */ int num_children; /* children count */ + unsigned next_child_index; /* the index of the next child that should + * be added + */ int threshold; /* if less than threshold children reads gave the * same result a quorum error occurs. */ @@ -747,21 +751,6 @@ static int64_t quorum_getlength(BlockDriverState *bs) return result; } -static void quorum_invalidate_cache(BlockDriverState *bs, Error **errp) -{ - BDRVQuorumState *s = bs->opaque; - Error *local_err = NULL; - int i; - - for (i = 0; i < s->num_children; i++) { - bdrv_invalidate_cache(s->children[i]->bs, &local_err); - if (local_err) { - error_propagate(errp, local_err); - return; - } - } -} - static coroutine_fn int quorum_co_flush(BlockDriverState *bs) { BDRVQuorumState *s = bs->opaque; @@ -898,9 +887,9 @@ static int quorum_open(BlockDriverState *bs, QDict *options, int flags, ret = -EINVAL; goto exit; } - if (s->num_children < 2) { + if (s->num_children < 1) { error_setg(&local_err, - "Number of provided children must be greater than 1"); + "Number of provided children must be 1 or more"); ret = -EINVAL; goto exit; } @@ -964,6 +953,7 @@ static int quorum_open(BlockDriverState *bs, QDict *options, int flags, opened[i] = true; } + s->next_child_index = s->num_children; g_free(opened); goto exit; @@ -1020,6 +1010,72 @@ static void quorum_attach_aio_context(BlockDriverState *bs, } } +static void quorum_add_child(BlockDriverState *bs, BlockDriverState *child_bs, + Error **errp) +{ + BDRVQuorumState *s = bs->opaque; + BdrvChild *child; + char indexstr[32]; + int ret; + + assert(s->num_children <= INT_MAX / sizeof(BdrvChild *)); + if (s->num_children == INT_MAX / sizeof(BdrvChild *) || + s->next_child_index == UINT_MAX) { + error_setg(errp, "Too many children"); + return; + } + + ret = snprintf(indexstr, 32, "children.%u", s->next_child_index); + if (ret < 0 || ret >= 32) { + error_setg(errp, "cannot generate child name"); + return; + } + s->next_child_index++; + + bdrv_drained_begin(bs); + + /* We can safely add the child now */ + bdrv_ref(child_bs); + child = bdrv_attach_child(bs, child_bs, indexstr, &child_format); + s->children = g_renew(BdrvChild *, s->children, s->num_children + 1); + s->children[s->num_children++] = child; + + bdrv_drained_end(bs); +} + +static void quorum_del_child(BlockDriverState *bs, BdrvChild *child, + Error **errp) +{ + BDRVQuorumState *s = bs->opaque; + int i; + + for (i = 0; i < s->num_children; i++) { + if (s->children[i] == child) { + break; + } + } + + /* we have checked it in bdrv_del_child() */ + assert(i < s->num_children); + + if (s->num_children <= s->threshold) { + error_setg(errp, + "The number of children cannot be lower than the vote threshold %d", + s->threshold); + return; + } + + bdrv_drained_begin(bs); + + /* We can safely remove this child now */ + memmove(&s->children[i], &s->children[i + 1], + (s->num_children - i - 1) * sizeof(BdrvChild *)); + s->children = g_renew(BdrvChild *, s->children, --s->num_children); + bdrv_unref_child(bs, child); + + bdrv_drained_end(bs); +} + static void quorum_refresh_filename(BlockDriverState *bs, QDict *options) { BDRVQuorumState *s = bs->opaque; @@ -1070,11 +1126,13 @@ static BlockDriver bdrv_quorum = { .bdrv_aio_readv = quorum_aio_readv, .bdrv_aio_writev = quorum_aio_writev, - .bdrv_invalidate_cache = quorum_invalidate_cache, .bdrv_detach_aio_context = quorum_detach_aio_context, .bdrv_attach_aio_context = quorum_attach_aio_context, + .bdrv_add_child = quorum_add_child, + .bdrv_del_child = quorum_del_child, + .is_filter = true, .bdrv_recurse_is_first_non_filter = quorum_recurse_is_first_non_filter, }; diff --git a/block/raw-aio.h b/block/raw-aio.h index 811e375018..714714e016 100644 --- a/block/raw-aio.h +++ b/block/raw-aio.h @@ -35,15 +35,16 @@ /* linux-aio.c - Linux native implementation */ #ifdef CONFIG_LINUX_AIO -void *laio_init(void); -void laio_cleanup(void *s); -BlockAIOCB *laio_submit(BlockDriverState *bs, void *aio_ctx, int fd, +typedef struct LinuxAioState LinuxAioState; +LinuxAioState *laio_init(void); +void laio_cleanup(LinuxAioState *s); +BlockAIOCB *laio_submit(BlockDriverState *bs, LinuxAioState *s, int fd, int64_t sector_num, QEMUIOVector *qiov, int nb_sectors, BlockCompletionFunc *cb, void *opaque, int type); -void laio_detach_aio_context(void *s, AioContext *old_context); -void laio_attach_aio_context(void *s, AioContext *new_context); -void laio_io_plug(BlockDriverState *bs, void *aio_ctx); -void laio_io_unplug(BlockDriverState *bs, void *aio_ctx, bool unplug); +void laio_detach_aio_context(LinuxAioState *s, AioContext *old_context); +void laio_attach_aio_context(LinuxAioState *s, AioContext *new_context); +void laio_io_plug(BlockDriverState *bs, LinuxAioState *s); +void laio_io_unplug(BlockDriverState *bs, LinuxAioState *s); #endif #ifdef _WIN32 diff --git a/block/raw-posix.c b/block/raw-posix.c index 906d5c9411..a4f5a1ba5f 100644 --- a/block/raw-posix.c +++ b/block/raw-posix.c @@ -139,7 +139,7 @@ typedef struct BDRVRawState { #ifdef CONFIG_LINUX_AIO int use_aio; - void *aio_ctx; + LinuxAioState *aio_ctx; #endif #ifdef CONFIG_XFS bool is_xfs:1; @@ -398,7 +398,7 @@ static void raw_attach_aio_context(BlockDriverState *bs, } #ifdef CONFIG_LINUX_AIO -static int raw_set_aio(void **aio_ctx, int *use_aio, int bdrv_flags) +static int raw_set_aio(LinuxAioState **aio_ctx, int *use_aio, int bdrv_flags) { int ret = -1; assert(aio_ctx != NULL); @@ -517,6 +517,7 @@ static int raw_open_common(BlockDriverState *bs, QDict *options, s->has_discard = true; s->has_write_zeroes = true; + bs->supported_zero_flags = BDRV_REQ_MAY_UNMAP; if ((bs->open_flags & BDRV_O_NOCACHE) != 0) { s->needs_alignment = true; } @@ -1345,17 +1346,7 @@ static void raw_aio_unplug(BlockDriverState *bs) #ifdef CONFIG_LINUX_AIO BDRVRawState *s = bs->opaque; if (s->use_aio) { - laio_io_unplug(bs, s->aio_ctx, true); - } -#endif -} - -static void raw_aio_flush_io_queue(BlockDriverState *bs) -{ -#ifdef CONFIG_LINUX_AIO - BDRVRawState *s = bs->opaque; - if (s->use_aio) { - laio_io_unplug(bs, s->aio_ctx, false); + laio_io_unplug(bs, s->aio_ctx); } #endif } @@ -1949,7 +1940,6 @@ BlockDriver bdrv_file = { .bdrv_refresh_limits = raw_refresh_limits, .bdrv_io_plug = raw_aio_plug, .bdrv_io_unplug = raw_aio_unplug, - .bdrv_flush_io_queue = raw_aio_flush_io_queue, .bdrv_truncate = raw_truncate, .bdrv_getlength = raw_getlength, @@ -2398,7 +2388,6 @@ static BlockDriver bdrv_host_device = { .bdrv_refresh_limits = raw_refresh_limits, .bdrv_io_plug = raw_aio_plug, .bdrv_io_unplug = raw_aio_unplug, - .bdrv_flush_io_queue = raw_aio_flush_io_queue, .bdrv_truncate = raw_truncate, .bdrv_getlength = raw_getlength, @@ -2528,7 +2517,6 @@ static BlockDriver bdrv_host_cdrom = { .bdrv_refresh_limits = raw_refresh_limits, .bdrv_io_plug = raw_aio_plug, .bdrv_io_unplug = raw_aio_unplug, - .bdrv_flush_io_queue = raw_aio_flush_io_queue, .bdrv_truncate = raw_truncate, .bdrv_getlength = raw_getlength, @@ -2664,7 +2652,6 @@ static BlockDriver bdrv_host_cdrom = { .bdrv_refresh_limits = raw_refresh_limits, .bdrv_io_plug = raw_aio_plug, .bdrv_io_unplug = raw_aio_unplug, - .bdrv_flush_io_queue = raw_aio_flush_io_queue, .bdrv_truncate = raw_truncate, .bdrv_getlength = raw_getlength, diff --git a/block/raw_bsd.c b/block/raw_bsd.c index a6cc7e9918..3385ed448d 100644 --- a/block/raw_bsd.c +++ b/block/raw_bsd.c @@ -105,8 +105,8 @@ raw_co_writev_flags(BlockDriverState *bs, int64_t sector_num, int nb_sectors, } BLKDBG_EVENT(bs->file, BLKDBG_WRITE_AIO); - ret = bdrv_co_do_pwritev(bs->file->bs, sector_num * BDRV_SECTOR_SIZE, - nb_sectors * BDRV_SECTOR_SIZE, qiov, flags); + ret = bdrv_co_pwritev(bs->file->bs, sector_num * BDRV_SECTOR_SIZE, + nb_sectors * BDRV_SECTOR_SIZE, qiov, flags); fail: if (qiov == &local_qiov) { @@ -116,13 +116,6 @@ fail: return ret; } -static int coroutine_fn -raw_co_writev(BlockDriverState *bs, int64_t sector_num, int nb_sectors, - QEMUIOVector *qiov) -{ - return raw_co_writev_flags(bs, sector_num, nb_sectors, qiov, 0); -} - static int64_t coroutine_fn raw_co_get_block_status(BlockDriverState *bs, int64_t sector_num, int nb_sectors, int *pnum, @@ -211,6 +204,8 @@ static int raw_open(BlockDriverState *bs, QDict *options, int flags, Error **errp) { bs->sg = bs->file->bs->sg; + bs->supported_write_flags = BDRV_REQ_FUA; + bs->supported_zero_flags = BDRV_REQ_FUA | BDRV_REQ_MAY_UNMAP; if (bs->probed && !bdrv_is_read_only(bs)) { fprintf(stderr, @@ -256,9 +251,7 @@ BlockDriver bdrv_raw = { .bdrv_close = &raw_close, .bdrv_create = &raw_create, .bdrv_co_readv = &raw_co_readv, - .bdrv_co_writev = &raw_co_writev, .bdrv_co_writev_flags = &raw_co_writev_flags, - .supported_write_flags = BDRV_REQ_FUA, .bdrv_co_write_zeroes = &raw_co_write_zeroes, .bdrv_co_discard = &raw_co_discard, .bdrv_co_get_block_status = &raw_co_get_block_status, diff --git a/block/sheepdog.c b/block/sheepdog.c index 33e0a33824..23fbace1f9 100644 --- a/block/sheepdog.c +++ b/block/sheepdog.c @@ -294,13 +294,16 @@ static inline size_t count_data_objs(const struct SheepdogInode *inode) #undef DPRINTF #ifdef DEBUG_SDOG -#define DPRINTF(fmt, args...) \ - do { \ - fprintf(stdout, "%s %d: " fmt, __func__, __LINE__, ##args); \ - } while (0) +#define DEBUG_SDOG_PRINT 1 #else -#define DPRINTF(fmt, args...) +#define DEBUG_SDOG_PRINT 0 #endif +#define DPRINTF(fmt, args...) \ + do { \ + if (DEBUG_SDOG_PRINT) { \ + fprintf(stderr, "%s %d: " fmt, __func__, __LINE__, ##args); \ + } \ + } while (0) typedef struct SheepdogAIOCB SheepdogAIOCB; @@ -1678,7 +1681,7 @@ static int sd_prealloc(const char *filename, Error **errp) if (ret < 0) { goto out; } - ret = blk_pwrite(blk, idx * buf_size, buf, buf_size); + ret = blk_pwrite(blk, idx * buf_size, buf, buf_size, 0); if (ret < 0) { goto out; } diff --git a/block/throttle-groups.c b/block/throttle-groups.c index 4920e09495..9ac063a0cd 100644 --- a/block/throttle-groups.c +++ b/block/throttle-groups.c @@ -219,6 +219,10 @@ static bool throttle_group_schedule_timer(BlockDriverState *bs, ThrottleGroup *tg = container_of(ts, ThrottleGroup, ts); bool must_wait; + if (bs->io_limits_disabled) { + return false; + } + /* Check if any of the timers in this group is already armed */ if (tg->any_timer_armed[is_write]) { return true; @@ -313,6 +317,17 @@ void coroutine_fn throttle_group_co_io_limits_intercept(BlockDriverState *bs, qemu_mutex_unlock(&tg->lock); } +void throttle_group_restart_bs(BlockDriverState *bs) +{ + int i; + + for (i = 0; i < 2; i++) { + while (qemu_co_enter_next(&bs->throttled_reqs[i])) { + ; + } + } +} + /* Update the throttle configuration for a particular group. Similar * to throttle_config(), but guarantees atomicity within the * throttling group. @@ -335,6 +350,9 @@ void throttle_group_config(BlockDriverState *bs, ThrottleConfig *cfg) } throttle_config(ts, tt, cfg); qemu_mutex_unlock(&tg->lock); + + qemu_co_enter_next(&bs->throttled_reqs[0]); + qemu_co_enter_next(&bs->throttled_reqs[1]); } /* Get the throttle configuration from a particular group. Similar to diff --git a/block/vdi.c b/block/vdi.c index 75d4819edb..54e11447c3 100644 --- a/block/vdi.c +++ b/block/vdi.c @@ -557,98 +557,109 @@ static int64_t coroutine_fn vdi_co_get_block_status(BlockDriverState *bs, return BDRV_BLOCK_DATA | BDRV_BLOCK_OFFSET_VALID | offset; } -static int vdi_co_read(BlockDriverState *bs, - int64_t sector_num, uint8_t *buf, int nb_sectors) +static int coroutine_fn +vdi_co_preadv(BlockDriverState *bs, uint64_t offset, uint64_t bytes, + QEMUIOVector *qiov, int flags) { BDRVVdiState *s = bs->opaque; + QEMUIOVector local_qiov; uint32_t bmap_entry; uint32_t block_index; - uint32_t sector_in_block; - uint32_t n_sectors; + uint32_t offset_in_block; + uint32_t n_bytes; + uint64_t bytes_done = 0; int ret = 0; logout("\n"); - while (ret >= 0 && nb_sectors > 0) { - block_index = sector_num / s->block_sectors; - sector_in_block = sector_num % s->block_sectors; - n_sectors = s->block_sectors - sector_in_block; - if (n_sectors > nb_sectors) { - n_sectors = nb_sectors; - } + qemu_iovec_init(&local_qiov, qiov->niov); + + while (ret >= 0 && bytes > 0) { + block_index = offset / s->block_size; + offset_in_block = offset % s->block_size; + n_bytes = MIN(bytes, s->block_size - offset_in_block); - logout("will read %u sectors starting at sector %" PRIu64 "\n", - n_sectors, sector_num); + logout("will read %u bytes starting at offset %" PRIu64 "\n", + n_bytes, offset); /* prepare next AIO request */ bmap_entry = le32_to_cpu(s->bmap[block_index]); if (!VDI_IS_ALLOCATED(bmap_entry)) { /* Block not allocated, return zeros, no need to wait. */ - memset(buf, 0, n_sectors * SECTOR_SIZE); + qemu_iovec_memset(qiov, bytes_done, 0, n_bytes); ret = 0; } else { - uint64_t offset = s->header.offset_data / SECTOR_SIZE + - (uint64_t)bmap_entry * s->block_sectors + - sector_in_block; - ret = bdrv_read(bs->file->bs, offset, buf, n_sectors); + uint64_t data_offset = s->header.offset_data + + (uint64_t)bmap_entry * s->block_size + + offset_in_block; + + qemu_iovec_reset(&local_qiov); + qemu_iovec_concat(&local_qiov, qiov, bytes_done, n_bytes); + + ret = bdrv_co_preadv(bs->file->bs, data_offset, n_bytes, + &local_qiov, 0); } - logout("%u sectors read\n", n_sectors); + logout("%u bytes read\n", n_bytes); - nb_sectors -= n_sectors; - sector_num += n_sectors; - buf += n_sectors * SECTOR_SIZE; + bytes -= n_bytes; + offset += n_bytes; + bytes_done += n_bytes; } + qemu_iovec_destroy(&local_qiov); + return ret; } -static int vdi_co_write(BlockDriverState *bs, - int64_t sector_num, const uint8_t *buf, int nb_sectors) +static int coroutine_fn +vdi_co_pwritev(BlockDriverState *bs, uint64_t offset, uint64_t bytes, + QEMUIOVector *qiov, int flags) { BDRVVdiState *s = bs->opaque; + QEMUIOVector local_qiov; uint32_t bmap_entry; uint32_t block_index; - uint32_t sector_in_block; - uint32_t n_sectors; + uint32_t offset_in_block; + uint32_t n_bytes; uint32_t bmap_first = VDI_UNALLOCATED; uint32_t bmap_last = VDI_UNALLOCATED; uint8_t *block = NULL; + uint64_t bytes_done = 0; int ret = 0; logout("\n"); - while (ret >= 0 && nb_sectors > 0) { - block_index = sector_num / s->block_sectors; - sector_in_block = sector_num % s->block_sectors; - n_sectors = s->block_sectors - sector_in_block; - if (n_sectors > nb_sectors) { - n_sectors = nb_sectors; - } + qemu_iovec_init(&local_qiov, qiov->niov); + + while (ret >= 0 && bytes > 0) { + block_index = offset / s->block_size; + offset_in_block = offset % s->block_size; + n_bytes = MIN(bytes, s->block_size - offset_in_block); - logout("will write %u sectors starting at sector %" PRIu64 "\n", - n_sectors, sector_num); + logout("will write %u bytes starting at offset %" PRIu64 "\n", + n_bytes, offset); /* prepare next AIO request */ bmap_entry = le32_to_cpu(s->bmap[block_index]); if (!VDI_IS_ALLOCATED(bmap_entry)) { /* Allocate new block and write to it. */ - uint64_t offset; + uint64_t data_offset; bmap_entry = s->header.blocks_allocated; s->bmap[block_index] = cpu_to_le32(bmap_entry); s->header.blocks_allocated++; - offset = s->header.offset_data / SECTOR_SIZE + - (uint64_t)bmap_entry * s->block_sectors; + data_offset = s->header.offset_data + + (uint64_t)bmap_entry * s->block_size; if (block == NULL) { block = g_malloc(s->block_size); bmap_first = block_index; } bmap_last = block_index; /* Copy data to be written to new block and zero unused parts. */ - memset(block, 0, sector_in_block * SECTOR_SIZE); - memcpy(block + sector_in_block * SECTOR_SIZE, - buf, n_sectors * SECTOR_SIZE); - memset(block + (sector_in_block + n_sectors) * SECTOR_SIZE, 0, - (s->block_sectors - n_sectors - sector_in_block) * SECTOR_SIZE); + memset(block, 0, offset_in_block); + qemu_iovec_to_buf(qiov, bytes_done, block + offset_in_block, + n_bytes); + memset(block + offset_in_block + n_bytes, 0, + s->block_size - n_bytes - offset_in_block); /* Note that this coroutine does not yield anywhere from reading the * bmap entry until here, so in regards to all the coroutines trying @@ -658,12 +669,12 @@ static int vdi_co_write(BlockDriverState *bs, * acquire the lock and thus the padded cluster is written before * the other coroutines can write to the affected area. */ qemu_co_mutex_lock(&s->write_lock); - ret = bdrv_write(bs->file->bs, offset, block, s->block_sectors); + ret = bdrv_pwrite(bs->file->bs, data_offset, block, s->block_size); qemu_co_mutex_unlock(&s->write_lock); } else { - uint64_t offset = s->header.offset_data / SECTOR_SIZE + - (uint64_t)bmap_entry * s->block_sectors + - sector_in_block; + uint64_t data_offset = s->header.offset_data + + (uint64_t)bmap_entry * s->block_size + + offset_in_block; qemu_co_mutex_lock(&s->write_lock); /* This lock is only used to make sure the following write operation * is executed after the write issued by the coroutine allocating @@ -674,16 +685,23 @@ static int vdi_co_write(BlockDriverState *bs, * that that write operation has returned (there may be other writes * in flight, but they do not concern this very operation). */ qemu_co_mutex_unlock(&s->write_lock); - ret = bdrv_write(bs->file->bs, offset, buf, n_sectors); + + qemu_iovec_reset(&local_qiov); + qemu_iovec_concat(&local_qiov, qiov, bytes_done, n_bytes); + + ret = bdrv_co_pwritev(bs->file->bs, data_offset, n_bytes, + &local_qiov, 0); } - nb_sectors -= n_sectors; - sector_num += n_sectors; - buf += n_sectors * SECTOR_SIZE; + bytes -= n_bytes; + offset += n_bytes; + bytes_done += n_bytes; - logout("%u sectors written\n", n_sectors); + logout("%u bytes written\n", n_bytes); } + qemu_iovec_destroy(&local_qiov); + logout("finished data write\n"); if (ret < 0) { return ret; @@ -694,6 +712,7 @@ static int vdi_co_write(BlockDriverState *bs, VdiHeader *header = (VdiHeader *) block; uint8_t *base; uint64_t offset; + uint32_t n_sectors; logout("now writing modified header\n"); assert(VDI_IS_ALLOCATED(bmap_first)); @@ -808,7 +827,7 @@ static int vdi_create(const char *filename, QemuOpts *opts, Error **errp) vdi_header_print(&header); #endif vdi_header_to_le(&header); - ret = blk_pwrite(blk, offset, &header, sizeof(header)); + ret = blk_pwrite(blk, offset, &header, sizeof(header), 0); if (ret < 0) { error_setg(errp, "Error writing header to %s", filename); goto exit; @@ -829,7 +848,7 @@ static int vdi_create(const char *filename, QemuOpts *opts, Error **errp) bmap[i] = VDI_UNALLOCATED; } } - ret = blk_pwrite(blk, offset, bmap, bmap_size); + ret = blk_pwrite(blk, offset, bmap, bmap_size, 0); if (ret < 0) { error_setg(errp, "Error writing bmap to %s", filename); goto exit; @@ -903,9 +922,9 @@ static BlockDriver bdrv_vdi = { .bdrv_co_get_block_status = vdi_co_get_block_status, .bdrv_make_empty = vdi_make_empty, - .bdrv_read = vdi_co_read, + .bdrv_co_preadv = vdi_co_preadv, #if defined(CONFIG_VDI_WRITE) - .bdrv_write = vdi_co_write, + .bdrv_co_pwritev = vdi_co_pwritev, #endif .bdrv_get_info = vdi_get_info, diff --git a/block/vhdx.c b/block/vhdx.c index 2b7b332404..ec778fe2a7 100644 --- a/block/vhdx.c +++ b/block/vhdx.c @@ -1856,13 +1856,14 @@ static int vhdx_create(const char *filename, QemuOpts *opts, Error **errp) creator = g_utf8_to_utf16("QEMU v" QEMU_VERSION, -1, NULL, &creator_items, NULL); signature = cpu_to_le64(VHDX_FILE_SIGNATURE); - ret = blk_pwrite(blk, VHDX_FILE_ID_OFFSET, &signature, sizeof(signature)); + ret = blk_pwrite(blk, VHDX_FILE_ID_OFFSET, &signature, sizeof(signature), + 0); if (ret < 0) { goto delete_and_exit; } if (creator) { ret = blk_pwrite(blk, VHDX_FILE_ID_OFFSET + sizeof(signature), - creator, creator_items * sizeof(gunichar2)); + creator, creator_items * sizeof(gunichar2), 0); if (ret < 0) { goto delete_and_exit; } diff --git a/block/vmdk.c b/block/vmdk.c index 45f9d3c5b9..e6c97c25a6 100644 --- a/block/vmdk.c +++ b/block/vmdk.c @@ -1016,27 +1016,26 @@ static void vmdk_refresh_limits(BlockDriverState *bs, Error **errp) */ static int get_whole_cluster(BlockDriverState *bs, VmdkExtent *extent, - uint64_t cluster_sector_num, - uint64_t sector_num, - uint64_t skip_start_sector, - uint64_t skip_end_sector) + uint64_t cluster_offset, + uint64_t offset, + uint64_t skip_start_bytes, + uint64_t skip_end_bytes) { int ret = VMDK_OK; int64_t cluster_bytes; uint8_t *whole_grain; /* For COW, align request sector_num to cluster start */ - sector_num = QEMU_ALIGN_DOWN(sector_num, extent->cluster_sectors); cluster_bytes = extent->cluster_sectors << BDRV_SECTOR_BITS; + offset = QEMU_ALIGN_DOWN(offset, cluster_bytes); whole_grain = qemu_blockalign(bs, cluster_bytes); if (!bs->backing) { - memset(whole_grain, 0, skip_start_sector << BDRV_SECTOR_BITS); - memset(whole_grain + (skip_end_sector << BDRV_SECTOR_BITS), 0, - cluster_bytes - (skip_end_sector << BDRV_SECTOR_BITS)); + memset(whole_grain, 0, skip_start_bytes); + memset(whole_grain + skip_end_bytes, 0, cluster_bytes - skip_end_bytes); } - assert(skip_end_sector <= extent->cluster_sectors); + assert(skip_end_bytes <= cluster_bytes); /* we will be here if it's first write on non-exist grain(cluster). * try to read from parent image, if exist */ if (bs->backing && !vmdk_is_cid_valid(bs)) { @@ -1045,42 +1044,43 @@ static int get_whole_cluster(BlockDriverState *bs, } /* Read backing data before skip range */ - if (skip_start_sector > 0) { + if (skip_start_bytes > 0) { if (bs->backing) { - ret = bdrv_read(bs->backing->bs, sector_num, - whole_grain, skip_start_sector); + ret = bdrv_pread(bs->backing->bs, offset, whole_grain, + skip_start_bytes); if (ret < 0) { ret = VMDK_ERROR; goto exit; } } - ret = bdrv_write(extent->file->bs, cluster_sector_num, whole_grain, - skip_start_sector); + ret = bdrv_pwrite(extent->file->bs, cluster_offset, whole_grain, + skip_start_bytes); if (ret < 0) { ret = VMDK_ERROR; goto exit; } } /* Read backing data after skip range */ - if (skip_end_sector < extent->cluster_sectors) { + if (skip_end_bytes < cluster_bytes) { if (bs->backing) { - ret = bdrv_read(bs->backing->bs, sector_num + skip_end_sector, - whole_grain + (skip_end_sector << BDRV_SECTOR_BITS), - extent->cluster_sectors - skip_end_sector); + ret = bdrv_pread(bs->backing->bs, offset + skip_end_bytes, + whole_grain + skip_end_bytes, + cluster_bytes - skip_end_bytes); if (ret < 0) { ret = VMDK_ERROR; goto exit; } } - ret = bdrv_write(extent->file->bs, cluster_sector_num + skip_end_sector, - whole_grain + (skip_end_sector << BDRV_SECTOR_BITS), - extent->cluster_sectors - skip_end_sector); + ret = bdrv_pwrite(extent->file->bs, cluster_offset + skip_end_bytes, + whole_grain + skip_end_bytes, + cluster_bytes - skip_end_bytes); if (ret < 0) { ret = VMDK_ERROR; goto exit; } } + ret = VMDK_OK; exit: qemu_vfree(whole_grain); return ret; @@ -1142,8 +1142,8 @@ static int get_cluster_offset(BlockDriverState *bs, uint64_t offset, bool allocate, uint64_t *cluster_offset, - uint64_t skip_start_sector, - uint64_t skip_end_sector) + uint64_t skip_start_bytes, + uint64_t skip_end_bytes) { unsigned int l1_index, l2_offset, l2_index; int min_index, i, j; @@ -1230,10 +1230,8 @@ static int get_cluster_offset(BlockDriverState *bs, * This problem may occur because of insufficient space on host disk * or inappropriate VM shutdown. */ - ret = get_whole_cluster(bs, extent, - cluster_sector, - offset >> BDRV_SECTOR_BITS, - skip_start_sector, skip_end_sector); + ret = get_whole_cluster(bs, extent, cluster_sector * BDRV_SECTOR_SIZE, + offset, skip_start_bytes, skip_end_bytes); if (ret) { return ret; } @@ -1259,15 +1257,26 @@ static VmdkExtent *find_extent(BDRVVmdkState *s, return NULL; } +static inline uint64_t vmdk_find_offset_in_cluster(VmdkExtent *extent, + int64_t offset) +{ + uint64_t offset_in_cluster, extent_begin_offset, extent_relative_offset; + uint64_t cluster_size = extent->cluster_sectors * BDRV_SECTOR_SIZE; + + extent_begin_offset = + (extent->end_sector - extent->sectors) * BDRV_SECTOR_SIZE; + extent_relative_offset = offset - extent_begin_offset; + offset_in_cluster = extent_relative_offset % cluster_size; + + return offset_in_cluster; +} + static inline uint64_t vmdk_find_index_in_cluster(VmdkExtent *extent, int64_t sector_num) { - uint64_t index_in_cluster, extent_begin_sector, extent_relative_sector_num; - - extent_begin_sector = extent->end_sector - extent->sectors; - extent_relative_sector_num = sector_num - extent_begin_sector; - index_in_cluster = extent_relative_sector_num % extent->cluster_sectors; - return index_in_cluster; + uint64_t offset; + offset = vmdk_find_offset_in_cluster(extent, sector_num * BDRV_SECTOR_SIZE); + return offset / BDRV_SECTOR_SIZE; } static int64_t coroutine_fn vmdk_co_get_block_status(BlockDriverState *bs, @@ -1319,38 +1328,57 @@ static int64_t coroutine_fn vmdk_co_get_block_status(BlockDriverState *bs, } static int vmdk_write_extent(VmdkExtent *extent, int64_t cluster_offset, - int64_t offset_in_cluster, const uint8_t *buf, - int nb_sectors, int64_t sector_num) + int64_t offset_in_cluster, QEMUIOVector *qiov, + uint64_t qiov_offset, uint64_t n_bytes, + uint64_t offset) { int ret; VmdkGrainMarker *data = NULL; uLongf buf_len; - const uint8_t *write_buf = buf; - int write_len = nb_sectors * 512; + QEMUIOVector local_qiov; + struct iovec iov; int64_t write_offset; int64_t write_end_sector; if (extent->compressed) { + void *compressed_data; + if (!extent->has_marker) { ret = -EINVAL; goto out; } buf_len = (extent->cluster_sectors << 9) * 2; data = g_malloc(buf_len + sizeof(VmdkGrainMarker)); - if (compress(data->data, &buf_len, buf, nb_sectors << 9) != Z_OK || - buf_len == 0) { + + compressed_data = g_malloc(n_bytes); + qemu_iovec_to_buf(qiov, qiov_offset, compressed_data, n_bytes); + ret = compress(data->data, &buf_len, compressed_data, n_bytes); + g_free(compressed_data); + + if (ret != Z_OK || buf_len == 0) { ret = -EINVAL; goto out; } - data->lba = sector_num; + + data->lba = offset >> BDRV_SECTOR_BITS; data->size = buf_len; - write_buf = (uint8_t *)data; - write_len = buf_len + sizeof(VmdkGrainMarker); + + n_bytes = buf_len + sizeof(VmdkGrainMarker); + iov = (struct iovec) { + .iov_base = data, + .iov_len = n_bytes, + }; + qemu_iovec_init_external(&local_qiov, &iov, 1); + } else { + qemu_iovec_init(&local_qiov, qiov->niov); + qemu_iovec_concat(&local_qiov, qiov, qiov_offset, n_bytes); } + write_offset = cluster_offset + offset_in_cluster, - ret = bdrv_pwrite(extent->file->bs, write_offset, write_buf, write_len); + ret = bdrv_co_pwritev(extent->file->bs, write_offset, n_bytes, + &local_qiov, 0); - write_end_sector = DIV_ROUND_UP(write_offset + write_len, BDRV_SECTOR_SIZE); + write_end_sector = DIV_ROUND_UP(write_offset + n_bytes, BDRV_SECTOR_SIZE); if (extent->compressed) { extent->next_cluster_sector = write_end_sector; @@ -1359,19 +1387,21 @@ static int vmdk_write_extent(VmdkExtent *extent, int64_t cluster_offset, write_end_sector); } - if (ret != write_len) { - ret = ret < 0 ? ret : -EIO; + if (ret < 0) { goto out; } ret = 0; out: g_free(data); + if (!extent->compressed) { + qemu_iovec_destroy(&local_qiov); + } return ret; } static int vmdk_read_extent(VmdkExtent *extent, int64_t cluster_offset, - int64_t offset_in_cluster, uint8_t *buf, - int nb_sectors) + int64_t offset_in_cluster, QEMUIOVector *qiov, + int bytes) { int ret; int cluster_bytes, buf_bytes; @@ -1383,14 +1413,13 @@ static int vmdk_read_extent(VmdkExtent *extent, int64_t cluster_offset, if (!extent->compressed) { - ret = bdrv_pread(extent->file->bs, - cluster_offset + offset_in_cluster, - buf, nb_sectors * 512); - if (ret == nb_sectors * 512) { - return 0; - } else { - return -EIO; + ret = bdrv_co_preadv(extent->file->bs, + cluster_offset + offset_in_cluster, bytes, + qiov, 0); + if (ret < 0) { + return ret; } + return 0; } cluster_bytes = extent->cluster_sectors * 512; /* Read two clusters in case GrainMarker + compressed data > one cluster */ @@ -1422,11 +1451,11 @@ static int vmdk_read_extent(VmdkExtent *extent, int64_t cluster_offset, } if (offset_in_cluster < 0 || - offset_in_cluster + nb_sectors * 512 > buf_len) { + offset_in_cluster + bytes > buf_len) { ret = -EINVAL; goto out; } - memcpy(buf, uncomp_buf + offset_in_cluster, nb_sectors * 512); + qemu_iovec_from_buf(qiov, 0, uncomp_buf + offset_in_cluster, bytes); ret = 0; out: @@ -1435,64 +1464,73 @@ static int vmdk_read_extent(VmdkExtent *extent, int64_t cluster_offset, return ret; } -static int vmdk_read(BlockDriverState *bs, int64_t sector_num, - uint8_t *buf, int nb_sectors) +static int coroutine_fn +vmdk_co_preadv(BlockDriverState *bs, uint64_t offset, uint64_t bytes, + QEMUIOVector *qiov, int flags) { BDRVVmdkState *s = bs->opaque; int ret; - uint64_t n, index_in_cluster; + uint64_t n_bytes, offset_in_cluster; VmdkExtent *extent = NULL; + QEMUIOVector local_qiov; uint64_t cluster_offset; + uint64_t bytes_done = 0; - while (nb_sectors > 0) { - extent = find_extent(s, sector_num, extent); + qemu_iovec_init(&local_qiov, qiov->niov); + qemu_co_mutex_lock(&s->lock); + + while (bytes > 0) { + extent = find_extent(s, offset >> BDRV_SECTOR_BITS, extent); if (!extent) { - return -EIO; + ret = -EIO; + goto fail; } ret = get_cluster_offset(bs, extent, NULL, - sector_num << 9, false, &cluster_offset, - 0, 0); - index_in_cluster = vmdk_find_index_in_cluster(extent, sector_num); - n = extent->cluster_sectors - index_in_cluster; - if (n > nb_sectors) { - n = nb_sectors; - } + offset, false, &cluster_offset, 0, 0); + offset_in_cluster = vmdk_find_offset_in_cluster(extent, offset); + + n_bytes = MIN(bytes, extent->cluster_sectors * BDRV_SECTOR_SIZE + - offset_in_cluster); + if (ret != VMDK_OK) { /* if not allocated, try to read from parent image, if exist */ if (bs->backing && ret != VMDK_ZEROED) { if (!vmdk_is_cid_valid(bs)) { - return -EINVAL; + ret = -EINVAL; + goto fail; } - ret = bdrv_read(bs->backing->bs, sector_num, buf, n); + + qemu_iovec_reset(&local_qiov); + qemu_iovec_concat(&local_qiov, qiov, bytes_done, n_bytes); + + ret = bdrv_co_preadv(bs->backing->bs, offset, n_bytes, + &local_qiov, 0); if (ret < 0) { - return ret; + goto fail; } } else { - memset(buf, 0, 512 * n); + qemu_iovec_memset(qiov, bytes_done, 0, n_bytes); } } else { - ret = vmdk_read_extent(extent, - cluster_offset, index_in_cluster * 512, - buf, n); + qemu_iovec_reset(&local_qiov); + qemu_iovec_concat(&local_qiov, qiov, bytes_done, n_bytes); + + ret = vmdk_read_extent(extent, cluster_offset, offset_in_cluster, + &local_qiov, n_bytes); if (ret) { - return ret; + goto fail; } } - nb_sectors -= n; - sector_num += n; - buf += n * 512; + bytes -= n_bytes; + offset += n_bytes; + bytes_done += n_bytes; } - return 0; -} -static coroutine_fn int vmdk_co_read(BlockDriverState *bs, int64_t sector_num, - uint8_t *buf, int nb_sectors) -{ - int ret; - BDRVVmdkState *s = bs->opaque; - qemu_co_mutex_lock(&s->lock); - ret = vmdk_read(bs, sector_num, buf, nb_sectors); + ret = 0; +fail: qemu_co_mutex_unlock(&s->lock); + qemu_iovec_destroy(&local_qiov); + return ret; } @@ -1506,38 +1544,38 @@ static coroutine_fn int vmdk_co_read(BlockDriverState *bs, int64_t sector_num, * * Returns: error code with 0 for success. */ -static int vmdk_write(BlockDriverState *bs, int64_t sector_num, - const uint8_t *buf, int nb_sectors, - bool zeroed, bool zero_dry_run) +static int vmdk_pwritev(BlockDriverState *bs, uint64_t offset, + uint64_t bytes, QEMUIOVector *qiov, + bool zeroed, bool zero_dry_run) { BDRVVmdkState *s = bs->opaque; VmdkExtent *extent = NULL; int ret; - int64_t index_in_cluster, n; + int64_t offset_in_cluster, n_bytes; uint64_t cluster_offset; + uint64_t bytes_done = 0; VmdkMetaData m_data; - if (sector_num > bs->total_sectors) { - error_report("Wrong offset: sector_num=0x%" PRIx64 + if (DIV_ROUND_UP(offset, BDRV_SECTOR_SIZE) > bs->total_sectors) { + error_report("Wrong offset: offset=0x%" PRIx64 " total_sectors=0x%" PRIx64, - sector_num, bs->total_sectors); + offset, bs->total_sectors); return -EIO; } - while (nb_sectors > 0) { - extent = find_extent(s, sector_num, extent); + while (bytes > 0) { + extent = find_extent(s, offset >> BDRV_SECTOR_BITS, extent); if (!extent) { return -EIO; } - index_in_cluster = vmdk_find_index_in_cluster(extent, sector_num); - n = extent->cluster_sectors - index_in_cluster; - if (n > nb_sectors) { - n = nb_sectors; - } - ret = get_cluster_offset(bs, extent, &m_data, sector_num << 9, + offset_in_cluster = vmdk_find_offset_in_cluster(extent, offset); + n_bytes = MIN(bytes, extent->cluster_sectors * BDRV_SECTOR_SIZE + - offset_in_cluster); + + ret = get_cluster_offset(bs, extent, &m_data, offset, !(extent->compressed || zeroed), - &cluster_offset, - index_in_cluster, index_in_cluster + n); + &cluster_offset, offset_in_cluster, + offset_in_cluster + n_bytes); if (extent->compressed) { if (ret == VMDK_OK) { /* Refuse write to allocated cluster for streamOptimized */ @@ -1546,7 +1584,7 @@ static int vmdk_write(BlockDriverState *bs, int64_t sector_num, return -EIO; } else { /* allocate */ - ret = get_cluster_offset(bs, extent, &m_data, sector_num << 9, + ret = get_cluster_offset(bs, extent, &m_data, offset, true, &cluster_offset, 0, 0); } } @@ -1556,9 +1594,9 @@ static int vmdk_write(BlockDriverState *bs, int64_t sector_num, if (zeroed) { /* Do zeroed write, buf is ignored */ if (extent->has_zero_grain && - index_in_cluster == 0 && - n >= extent->cluster_sectors) { - n = extent->cluster_sectors; + offset_in_cluster == 0 && + n_bytes >= extent->cluster_sectors * BDRV_SECTOR_SIZE) { + n_bytes = extent->cluster_sectors * BDRV_SECTOR_SIZE; if (!zero_dry_run) { /* update L2 tables */ if (vmdk_L2update(extent, &m_data, VMDK_GTE_ZEROED) @@ -1570,9 +1608,8 @@ static int vmdk_write(BlockDriverState *bs, int64_t sector_num, return -ENOTSUP; } } else { - ret = vmdk_write_extent(extent, - cluster_offset, index_in_cluster * 512, - buf, n, sector_num); + ret = vmdk_write_extent(extent, cluster_offset, offset_in_cluster, + qiov, bytes_done, n_bytes, offset); if (ret) { return ret; } @@ -1585,9 +1622,9 @@ static int vmdk_write(BlockDriverState *bs, int64_t sector_num, } } } - nb_sectors -= n; - sector_num += n; - buf += n * 512; + bytes -= n_bytes; + offset += n_bytes; + bytes_done += n_bytes; /* update CID on the first write every time the virtual disk is * opened */ @@ -1602,25 +1639,65 @@ static int vmdk_write(BlockDriverState *bs, int64_t sector_num, return 0; } -static coroutine_fn int vmdk_co_write(BlockDriverState *bs, int64_t sector_num, - const uint8_t *buf, int nb_sectors) +static int coroutine_fn +vmdk_co_pwritev(BlockDriverState *bs, uint64_t offset, uint64_t bytes, + QEMUIOVector *qiov, int flags) { int ret; BDRVVmdkState *s = bs->opaque; qemu_co_mutex_lock(&s->lock); - ret = vmdk_write(bs, sector_num, buf, nb_sectors, false, false); + ret = vmdk_pwritev(bs, offset, bytes, qiov, false, false); qemu_co_mutex_unlock(&s->lock); return ret; } +typedef struct VmdkWriteCompressedCo { + BlockDriverState *bs; + int64_t sector_num; + const uint8_t *buf; + int nb_sectors; + int ret; +} VmdkWriteCompressedCo; + +static void vmdk_co_write_compressed(void *opaque) +{ + VmdkWriteCompressedCo *co = opaque; + QEMUIOVector local_qiov; + uint64_t offset = co->sector_num * BDRV_SECTOR_SIZE; + uint64_t bytes = co->nb_sectors * BDRV_SECTOR_SIZE; + + struct iovec iov = (struct iovec) { + .iov_base = (uint8_t*) co->buf, + .iov_len = bytes, + }; + qemu_iovec_init_external(&local_qiov, &iov, 1); + + co->ret = vmdk_pwritev(co->bs, offset, bytes, &local_qiov, false, false); +} + static int vmdk_write_compressed(BlockDriverState *bs, int64_t sector_num, const uint8_t *buf, int nb_sectors) { BDRVVmdkState *s = bs->opaque; + if (s->num_extents == 1 && s->extents[0].compressed) { - return vmdk_write(bs, sector_num, buf, nb_sectors, false, false); + Coroutine *co; + AioContext *aio_context = bdrv_get_aio_context(bs); + VmdkWriteCompressedCo data = { + .bs = bs, + .sector_num = sector_num, + .buf = buf, + .nb_sectors = nb_sectors, + .ret = -EINPROGRESS, + }; + co = qemu_coroutine_create(vmdk_co_write_compressed); + qemu_coroutine_enter(co, &data); + while (data.ret == -EINPROGRESS) { + aio_poll(aio_context, true); + } + return data.ret; } else { return -ENOTSUP; } @@ -1633,12 +1710,15 @@ static int coroutine_fn vmdk_co_write_zeroes(BlockDriverState *bs, { int ret; BDRVVmdkState *s = bs->opaque; + uint64_t offset = sector_num * BDRV_SECTOR_SIZE; + uint64_t bytes = nb_sectors * BDRV_SECTOR_SIZE; + qemu_co_mutex_lock(&s->lock); /* write zeroes could fail if sectors not aligned to cluster, test it with * dry_run == true before really updating image */ - ret = vmdk_write(bs, sector_num, NULL, nb_sectors, true, true); + ret = vmdk_pwritev(bs, offset, bytes, NULL, true, true); if (!ret) { - ret = vmdk_write(bs, sector_num, NULL, nb_sectors, true, false); + ret = vmdk_pwritev(bs, offset, bytes, NULL, true, false); } qemu_co_mutex_unlock(&s->lock); return ret; @@ -1728,12 +1808,12 @@ static int vmdk_create_extent(const char *filename, int64_t filesize, header.check_bytes[3] = 0xa; /* write all the data */ - ret = blk_pwrite(blk, 0, &magic, sizeof(magic)); + ret = blk_pwrite(blk, 0, &magic, sizeof(magic), 0); if (ret < 0) { error_setg(errp, QERR_IO_ERROR); goto exit; } - ret = blk_pwrite(blk, sizeof(magic), &header, sizeof(header)); + ret = blk_pwrite(blk, sizeof(magic), &header, sizeof(header), 0); if (ret < 0) { error_setg(errp, QERR_IO_ERROR); goto exit; @@ -1753,7 +1833,7 @@ static int vmdk_create_extent(const char *filename, int64_t filesize, gd_buf[i] = cpu_to_le32(tmp); } ret = blk_pwrite(blk, le64_to_cpu(header.rgd_offset) * BDRV_SECTOR_SIZE, - gd_buf, gd_buf_size); + gd_buf, gd_buf_size, 0); if (ret < 0) { error_setg(errp, QERR_IO_ERROR); goto exit; @@ -1765,7 +1845,7 @@ static int vmdk_create_extent(const char *filename, int64_t filesize, gd_buf[i] = cpu_to_le32(tmp); } ret = blk_pwrite(blk, le64_to_cpu(header.gd_offset) * BDRV_SECTOR_SIZE, - gd_buf, gd_buf_size); + gd_buf, gd_buf_size, 0); if (ret < 0) { error_setg(errp, QERR_IO_ERROR); goto exit; @@ -1829,8 +1909,8 @@ static int vmdk_create(const char *filename, QemuOpts *opts, Error **errp) int64_t total_size = 0, filesize; char *adapter_type = NULL; char *backing_file = NULL; + char *hw_version = NULL; char *fmt = NULL; - int flags = 0; int ret = 0; bool flat, split, compress; GString *ext_desc_lines; @@ -1861,7 +1941,7 @@ static int vmdk_create(const char *filename, QemuOpts *opts, Error **errp) "# The Disk Data Base\n" "#DDB\n" "\n" - "ddb.virtualHWVersion = \"%d\"\n" + "ddb.virtualHWVersion = \"%s\"\n" "ddb.geometry.cylinders = \"%" PRId64 "\"\n" "ddb.geometry.heads = \"%" PRIu32 "\"\n" "ddb.geometry.sectors = \"63\"\n" @@ -1878,8 +1958,20 @@ static int vmdk_create(const char *filename, QemuOpts *opts, Error **errp) BDRV_SECTOR_SIZE); adapter_type = qemu_opt_get_del(opts, BLOCK_OPT_ADAPTER_TYPE); backing_file = qemu_opt_get_del(opts, BLOCK_OPT_BACKING_FILE); + hw_version = qemu_opt_get_del(opts, BLOCK_OPT_HWVERSION); if (qemu_opt_get_bool_del(opts, BLOCK_OPT_COMPAT6, false)) { - flags |= BLOCK_FLAG_COMPAT6; + if (strcmp(hw_version, "undefined")) { + error_setg(errp, + "compat6 cannot be enabled with hwversion set"); + ret = -EINVAL; + goto exit; + } + g_free(hw_version); + hw_version = g_strdup("6"); + } + if (strcmp(hw_version, "undefined") == 0) { + g_free(hw_version); + hw_version = g_strdup("4"); } fmt = qemu_opt_get_del(opts, BLOCK_OPT_SUBFMT); if (qemu_opt_get_bool_del(opts, BLOCK_OPT_ZEROED_GRAIN, false)) { @@ -2001,7 +2093,7 @@ static int vmdk_create(const char *filename, QemuOpts *opts, Error **errp) fmt, parent_desc_line, ext_desc_lines->str, - (flags & BLOCK_FLAG_COMPAT6 ? 6 : 4), + hw_version, total_size / (int64_t)(63 * number_heads * BDRV_SECTOR_SIZE), number_heads, @@ -2028,7 +2120,7 @@ static int vmdk_create(const char *filename, QemuOpts *opts, Error **errp) blk_set_allow_write_beyond_eof(new_blk, true); - ret = blk_pwrite(new_blk, desc_offset, desc, desc_len); + ret = blk_pwrite(new_blk, desc_offset, desc, desc_len, 0); if (ret < 0) { error_setg_errno(errp, -ret, "Could not write description"); goto exit; @@ -2047,6 +2139,7 @@ exit: } g_free(adapter_type); g_free(backing_file); + g_free(hw_version); g_free(fmt); g_free(desc); g_free(path); @@ -2298,6 +2391,12 @@ static QemuOptsList vmdk_create_opts = { .def_value_str = "off" }, { + .name = BLOCK_OPT_HWVERSION, + .type = QEMU_OPT_STRING, + .help = "VMDK hardware version", + .def_value_str = "undefined" + }, + { .name = BLOCK_OPT_SUBFMT, .type = QEMU_OPT_STRING, .help = @@ -2321,8 +2420,8 @@ static BlockDriver bdrv_vmdk = { .bdrv_open = vmdk_open, .bdrv_check = vmdk_check, .bdrv_reopen_prepare = vmdk_reopen_prepare, - .bdrv_read = vmdk_co_read, - .bdrv_write = vmdk_co_write, + .bdrv_co_preadv = vmdk_co_preadv, + .bdrv_co_pwritev = vmdk_co_pwritev, .bdrv_write_compressed = vmdk_write_compressed, .bdrv_co_write_zeroes = vmdk_co_write_zeroes, .bdrv_close = vmdk_close, diff --git a/block/vpc.c b/block/vpc.c index 3e2ea698d9..0379813e2f 100644 --- a/block/vpc.c +++ b/block/vpc.c @@ -454,22 +454,21 @@ static int vpc_reopen_prepare(BDRVReopenState *state, * The parameter write must be 1 if the offset will be used for a write * operation (the block bitmaps is updated then), 0 otherwise. */ -static inline int64_t get_sector_offset(BlockDriverState *bs, - int64_t sector_num, int write) +static inline int64_t get_image_offset(BlockDriverState *bs, uint64_t offset, + bool write) { BDRVVPCState *s = bs->opaque; - uint64_t offset = sector_num * 512; uint64_t bitmap_offset, block_offset; - uint32_t pagetable_index, pageentry_index; + uint32_t pagetable_index, offset_in_block; pagetable_index = offset / s->block_size; - pageentry_index = (offset % s->block_size) / 512; + offset_in_block = offset % s->block_size; if (pagetable_index >= s->max_table_entries || s->pagetable[pagetable_index] == 0xffffffff) return -1; /* not allocated */ bitmap_offset = 512 * (uint64_t) s->pagetable[pagetable_index]; - block_offset = bitmap_offset + s->bitmap_size + (512 * pageentry_index); + block_offset = bitmap_offset + s->bitmap_size + offset_in_block; /* We must ensure that we don't write to any sectors which are marked as unused in the bitmap. We get away with setting all bits in the block @@ -487,6 +486,12 @@ static inline int64_t get_sector_offset(BlockDriverState *bs, return block_offset; } +static inline int64_t get_sector_offset(BlockDriverState *bs, + int64_t sector_num, bool write) +{ + return get_image_offset(bs, sector_num * BDRV_SECTOR_SIZE, write); +} + /* * Writes the footer to the end of the image file. This is needed when the * file grows as it overwrites the old footer @@ -513,7 +518,7 @@ static int rewrite_footer(BlockDriverState* bs) * * Returns the sectors' offset in the image file on success and < 0 on error */ -static int64_t alloc_block(BlockDriverState* bs, int64_t sector_num) +static int64_t alloc_block(BlockDriverState* bs, int64_t offset) { BDRVVPCState *s = bs->opaque; int64_t bat_offset; @@ -522,14 +527,13 @@ static int64_t alloc_block(BlockDriverState* bs, int64_t sector_num) uint8_t bitmap[s->bitmap_size]; /* Check if sector_num is valid */ - if ((sector_num < 0) || (sector_num > bs->total_sectors)) - return -1; + if ((offset < 0) || (offset > bs->total_sectors * BDRV_SECTOR_SIZE)) { + return -EINVAL; + } /* Write entry into in-memory BAT */ - index = (sector_num * 512) / s->block_size; - if (s->pagetable[index] != 0xFFFFFFFF) - return -1; - + index = offset / s->block_size; + assert(s->pagetable[index] == 0xFFFFFFFF); s->pagetable[index] = s->free_data_block_offset / 512; /* Initialize the block's bitmap */ @@ -553,11 +557,11 @@ static int64_t alloc_block(BlockDriverState* bs, int64_t sector_num) if (ret < 0) goto fail; - return get_sector_offset(bs, sector_num, 0); + return get_image_offset(bs, offset, false); fail: s->free_data_block_offset -= (s->block_size + s->bitmap_size); - return -1; + return ret; } static int vpc_get_info(BlockDriverState *bs, BlockDriverInfo *bdi) @@ -573,104 +577,105 @@ static int vpc_get_info(BlockDriverState *bs, BlockDriverInfo *bdi) return 0; } -static int vpc_read(BlockDriverState *bs, int64_t sector_num, - uint8_t *buf, int nb_sectors) +static int coroutine_fn +vpc_co_preadv(BlockDriverState *bs, uint64_t offset, uint64_t bytes, + QEMUIOVector *qiov, int flags) { BDRVVPCState *s = bs->opaque; int ret; - int64_t offset; - int64_t sectors, sectors_per_block; + int64_t image_offset; + int64_t n_bytes; + int64_t bytes_done = 0; VHDFooter *footer = (VHDFooter *) s->footer_buf; + QEMUIOVector local_qiov; if (be32_to_cpu(footer->type) == VHD_FIXED) { - return bdrv_read(bs->file->bs, sector_num, buf, nb_sectors); + return bdrv_co_preadv(bs->file->bs, offset, bytes, qiov, 0); } - while (nb_sectors > 0) { - offset = get_sector_offset(bs, sector_num, 0); - sectors_per_block = s->block_size >> BDRV_SECTOR_BITS; - sectors = sectors_per_block - (sector_num % sectors_per_block); - if (sectors > nb_sectors) { - sectors = nb_sectors; - } + qemu_co_mutex_lock(&s->lock); + qemu_iovec_init(&local_qiov, qiov->niov); + + while (bytes > 0) { + image_offset = get_image_offset(bs, offset, false); + n_bytes = MIN(bytes, s->block_size - (offset % s->block_size)); - if (offset == -1) { - memset(buf, 0, sectors * BDRV_SECTOR_SIZE); + if (image_offset == -1) { + qemu_iovec_memset(qiov, bytes_done, 0, n_bytes); } else { - ret = bdrv_pread(bs->file->bs, offset, buf, - sectors * BDRV_SECTOR_SIZE); - if (ret != sectors * BDRV_SECTOR_SIZE) { - return -1; + qemu_iovec_reset(&local_qiov); + qemu_iovec_concat(&local_qiov, qiov, bytes_done, n_bytes); + + ret = bdrv_co_preadv(bs->file->bs, image_offset, n_bytes, + &local_qiov, 0); + if (ret < 0) { + goto fail; } } - nb_sectors -= sectors; - sector_num += sectors; - buf += sectors * BDRV_SECTOR_SIZE; + bytes -= n_bytes; + offset += n_bytes; + bytes_done += n_bytes; } - return 0; -} -static coroutine_fn int vpc_co_read(BlockDriverState *bs, int64_t sector_num, - uint8_t *buf, int nb_sectors) -{ - int ret; - BDRVVPCState *s = bs->opaque; - qemu_co_mutex_lock(&s->lock); - ret = vpc_read(bs, sector_num, buf, nb_sectors); + ret = 0; +fail: + qemu_iovec_destroy(&local_qiov); qemu_co_mutex_unlock(&s->lock); + return ret; } -static int vpc_write(BlockDriverState *bs, int64_t sector_num, - const uint8_t *buf, int nb_sectors) +static int coroutine_fn +vpc_co_pwritev(BlockDriverState *bs, uint64_t offset, uint64_t bytes, + QEMUIOVector *qiov, int flags) { BDRVVPCState *s = bs->opaque; - int64_t offset; - int64_t sectors, sectors_per_block; + int64_t image_offset; + int64_t n_bytes; + int64_t bytes_done = 0; int ret; VHDFooter *footer = (VHDFooter *) s->footer_buf; + QEMUIOVector local_qiov; if (be32_to_cpu(footer->type) == VHD_FIXED) { - return bdrv_write(bs->file->bs, sector_num, buf, nb_sectors); + return bdrv_co_pwritev(bs->file->bs, offset, bytes, qiov, 0); } - while (nb_sectors > 0) { - offset = get_sector_offset(bs, sector_num, 1); - sectors_per_block = s->block_size >> BDRV_SECTOR_BITS; - sectors = sectors_per_block - (sector_num % sectors_per_block); - if (sectors > nb_sectors) { - sectors = nb_sectors; - } + qemu_co_mutex_lock(&s->lock); + qemu_iovec_init(&local_qiov, qiov->niov); + + while (bytes > 0) { + image_offset = get_image_offset(bs, offset, true); + n_bytes = MIN(bytes, s->block_size - (offset % s->block_size)); - if (offset == -1) { - offset = alloc_block(bs, sector_num); - if (offset < 0) - return -1; + if (image_offset == -1) { + image_offset = alloc_block(bs, offset); + if (image_offset < 0) { + ret = image_offset; + goto fail; + } } - ret = bdrv_pwrite(bs->file->bs, offset, buf, - sectors * BDRV_SECTOR_SIZE); - if (ret != sectors * BDRV_SECTOR_SIZE) { - return -1; + qemu_iovec_reset(&local_qiov); + qemu_iovec_concat(&local_qiov, qiov, bytes_done, n_bytes); + + ret = bdrv_co_pwritev(bs->file->bs, image_offset, n_bytes, + &local_qiov, 0); + if (ret < 0) { + goto fail; } - nb_sectors -= sectors; - sector_num += sectors; - buf += sectors * BDRV_SECTOR_SIZE; + bytes -= n_bytes; + offset += n_bytes; + bytes_done += n_bytes; } - return 0; -} - -static coroutine_fn int vpc_co_write(BlockDriverState *bs, int64_t sector_num, - const uint8_t *buf, int nb_sectors) -{ - int ret; - BDRVVPCState *s = bs->opaque; - qemu_co_mutex_lock(&s->lock); - ret = vpc_write(bs, sector_num, buf, nb_sectors); + ret = 0; +fail: + qemu_iovec_destroy(&local_qiov); qemu_co_mutex_unlock(&s->lock); + return ret; } @@ -783,13 +788,13 @@ static int create_dynamic_disk(BlockBackend *blk, uint8_t *buf, block_size = 0x200000; num_bat_entries = (total_sectors + block_size / 512) / (block_size / 512); - ret = blk_pwrite(blk, offset, buf, HEADER_SIZE); + ret = blk_pwrite(blk, offset, buf, HEADER_SIZE, 0); if (ret < 0) { goto fail; } offset = 1536 + ((num_bat_entries * 4 + 511) & ~511); - ret = blk_pwrite(blk, offset, buf, HEADER_SIZE); + ret = blk_pwrite(blk, offset, buf, HEADER_SIZE, 0); if (ret < 0) { goto fail; } @@ -799,7 +804,7 @@ static int create_dynamic_disk(BlockBackend *blk, uint8_t *buf, memset(buf, 0xFF, 512); for (i = 0; i < (num_bat_entries * 4 + 511) / 512; i++) { - ret = blk_pwrite(blk, offset, buf, 512); + ret = blk_pwrite(blk, offset, buf, 512, 0); if (ret < 0) { goto fail; } @@ -826,7 +831,7 @@ static int create_dynamic_disk(BlockBackend *blk, uint8_t *buf, /* Write the header */ offset = 512; - ret = blk_pwrite(blk, offset, buf, 1024); + ret = blk_pwrite(blk, offset, buf, 1024, 0); if (ret < 0) { goto fail; } @@ -848,7 +853,7 @@ static int create_fixed_disk(BlockBackend *blk, uint8_t *buf, return ret; } - ret = blk_pwrite(blk, total_size - HEADER_SIZE, buf, HEADER_SIZE); + ret = blk_pwrite(blk, total_size - HEADER_SIZE, buf, HEADER_SIZE, 0); if (ret < 0) { return ret; } @@ -1056,8 +1061,8 @@ static BlockDriver bdrv_vpc = { .bdrv_reopen_prepare = vpc_reopen_prepare, .bdrv_create = vpc_create, - .bdrv_read = vpc_co_read, - .bdrv_write = vpc_co_write, + .bdrv_co_preadv = vpc_co_preadv, + .bdrv_co_pwritev = vpc_co_pwritev, .bdrv_co_get_block_status = vpc_co_get_block_status, .bdrv_get_info = vpc_get_info, diff --git a/block/vvfat.c b/block/vvfat.c index 183fc4f049..5b0c8dd639 100644 --- a/block/vvfat.c +++ b/block/vvfat.c @@ -1179,6 +1179,7 @@ static int vvfat_open(BlockDriverState *bs, QDict *options, int flags, bs->read_only = 0; } + bs->request_alignment = BDRV_SECTOR_SIZE; /* No sub-sector I/O supported */ bs->total_sectors = cyls * heads * secs; if (init_directories(s, dirname, heads, secs, errp)) { @@ -1421,14 +1422,31 @@ DLOG(fprintf(stderr, "sector %d not allocated\n", (int)sector_num)); return 0; } -static coroutine_fn int vvfat_co_read(BlockDriverState *bs, int64_t sector_num, - uint8_t *buf, int nb_sectors) +static int coroutine_fn +vvfat_co_preadv(BlockDriverState *bs, uint64_t offset, uint64_t bytes, + QEMUIOVector *qiov, int flags) { int ret; BDRVVVFATState *s = bs->opaque; + uint64_t sector_num = offset >> BDRV_SECTOR_BITS; + int nb_sectors = bytes >> BDRV_SECTOR_BITS; + void *buf; + + assert((offset & (BDRV_SECTOR_SIZE - 1)) == 0); + assert((bytes & (BDRV_SECTOR_SIZE - 1)) == 0); + + buf = g_try_malloc(bytes); + if (bytes && buf == NULL) { + return -ENOMEM; + } + qemu_co_mutex_lock(&s->lock); ret = vvfat_read(bs, sector_num, buf, nb_sectors); qemu_co_mutex_unlock(&s->lock); + + qemu_iovec_from_buf(qiov, 0, buf, bytes); + g_free(buf); + return ret; } @@ -2880,14 +2898,31 @@ DLOG(checkpoint()); return 0; } -static coroutine_fn int vvfat_co_write(BlockDriverState *bs, int64_t sector_num, - const uint8_t *buf, int nb_sectors) +static int coroutine_fn +vvfat_co_pwritev(BlockDriverState *bs, uint64_t offset, uint64_t bytes, + QEMUIOVector *qiov, int flags) { int ret; BDRVVVFATState *s = bs->opaque; + uint64_t sector_num = offset >> BDRV_SECTOR_BITS; + int nb_sectors = bytes >> BDRV_SECTOR_BITS; + void *buf; + + assert((offset & (BDRV_SECTOR_SIZE - 1)) == 0); + assert((bytes & (BDRV_SECTOR_SIZE - 1)) == 0); + + buf = g_try_malloc(bytes); + if (bytes && buf == NULL) { + return -ENOMEM; + } + qemu_iovec_to_buf(qiov, 0, buf, bytes); + qemu_co_mutex_lock(&s->lock); ret = vvfat_write(bs, sector_num, buf, nb_sectors); qemu_co_mutex_unlock(&s->lock); + + g_free(buf); + return ret; } @@ -2904,8 +2939,10 @@ static int64_t coroutine_fn vvfat_co_get_block_status(BlockDriverState *bs, return BDRV_BLOCK_DATA; } -static int write_target_commit(BlockDriverState *bs, int64_t sector_num, - const uint8_t* buffer, int nb_sectors) { +static int coroutine_fn +write_target_commit(BlockDriverState *bs, uint64_t offset, uint64_t bytes, + QEMUIOVector *qiov, int flags) +{ BDRVVVFATState* s = *((BDRVVVFATState**) bs->opaque); return try_commit(s); } @@ -2918,7 +2955,7 @@ static void write_target_close(BlockDriverState *bs) { static BlockDriver vvfat_write_target = { .format_name = "vvfat_write_target", - .bdrv_write = write_target_commit, + .bdrv_co_pwritev = write_target_commit, .bdrv_close = write_target_close, }; @@ -3014,8 +3051,8 @@ static BlockDriver bdrv_vvfat = { .bdrv_file_open = vvfat_open, .bdrv_close = vvfat_close, - .bdrv_read = vvfat_co_read, - .bdrv_write = vvfat_co_write, + .bdrv_co_preadv = vvfat_co_preadv, + .bdrv_co_pwritev = vvfat_co_pwritev, .bdrv_co_get_block_status = vvfat_co_get_block_status, }; diff --git a/blockdev.c b/blockdev.c index f1f520a265..1892b8ec8e 100644 --- a/blockdev.c +++ b/blockdev.c @@ -73,7 +73,7 @@ static int if_max_devs[IF_COUNT] = { * Do not change these numbers! They govern how drive option * index maps to unit and bus. That mapping is ABI. * - * All controllers used to imlement if=T drives need to support + * All controllers used to implement if=T drives need to support * if_max_devs[T] units, for any T with if_max_devs[T] != 0. * Otherwise, some index values map to "impossible" bus, unit * values. @@ -4092,6 +4092,61 @@ out: aio_context_release(aio_context); } +static BdrvChild *bdrv_find_child(BlockDriverState *parent_bs, + const char *child_name) +{ + BdrvChild *child; + + QLIST_FOREACH(child, &parent_bs->children, next) { + if (strcmp(child->name, child_name) == 0) { + return child; + } + } + + return NULL; +} + +void qmp_x_blockdev_change(const char *parent, bool has_child, + const char *child, bool has_node, + const char *node, Error **errp) +{ + BlockDriverState *parent_bs, *new_bs = NULL; + BdrvChild *p_child; + + parent_bs = bdrv_lookup_bs(parent, parent, errp); + if (!parent_bs) { + return; + } + + if (has_child == has_node) { + if (has_child) { + error_setg(errp, "The parameters child and node are in conflict"); + } else { + error_setg(errp, "Either child or node must be specified"); + } + return; + } + + if (has_child) { + p_child = bdrv_find_child(parent_bs, child); + if (!p_child) { + error_setg(errp, "Node '%s' does not have child '%s'", + parent, child); + return; + } + bdrv_del_child(parent_bs, p_child, errp); + } + + if (has_node) { + new_bs = bdrv_find_node(node); + if (!new_bs) { + error_setg(errp, "Node '%s' not found", node); + return; + } + bdrv_add_child(parent_bs, new_bs, errp); + } +} + BlockJobInfoList *qmp_query_block_jobs(Error **errp) { BlockJobInfoList *head = NULL, **p_next = &head; diff --git a/dma-helpers.c b/dma-helpers.c index 4ad0bca67e..a6cc15f534 100644 --- a/dma-helpers.c +++ b/dma-helpers.c @@ -73,7 +73,7 @@ typedef struct { BlockBackend *blk; BlockAIOCB *acb; QEMUSGList *sg; - uint64_t sector_num; + uint64_t offset; DMADirection dir; int sg_cur_index; dma_addr_t sg_cur_byte; @@ -130,7 +130,7 @@ static void dma_blk_cb(void *opaque, int ret) trace_dma_blk_cb(dbs, ret); dbs->acb = NULL; - dbs->sector_num += dbs->iov.size / 512; + dbs->offset += dbs->iov.size; if (dbs->sg_cur_index == dbs->sg->nsg || ret < 0) { dma_complete(dbs, ret); @@ -164,8 +164,8 @@ static void dma_blk_cb(void *opaque, int ret) qemu_iovec_discard_back(&dbs->iov, dbs->iov.size & ~BDRV_SECTOR_MASK); } - dbs->acb = dbs->io_func(dbs->blk, dbs->sector_num, &dbs->iov, - dbs->iov.size / 512, dma_blk_cb, dbs); + dbs->acb = dbs->io_func(dbs->blk, dbs->offset, &dbs->iov, 0, + dma_blk_cb, dbs); assert(dbs->acb); } @@ -203,7 +203,7 @@ BlockAIOCB *dma_blk_io( dbs->acb = NULL; dbs->blk = blk; dbs->sg = sg; - dbs->sector_num = sector_num; + dbs->offset = sector_num << BDRV_SECTOR_BITS; dbs->sg_cur_index = 0; dbs->sg_cur_byte = 0; dbs->dir = dir; @@ -219,7 +219,7 @@ BlockAIOCB *dma_blk_read(BlockBackend *blk, QEMUSGList *sg, uint64_t sector, void (*cb)(void *opaque, int ret), void *opaque) { - return dma_blk_io(blk, sg, sector, blk_aio_readv, cb, opaque, + return dma_blk_io(blk, sg, sector, blk_aio_preadv, cb, opaque, DMA_DIRECTION_FROM_DEVICE); } @@ -227,7 +227,7 @@ BlockAIOCB *dma_blk_write(BlockBackend *blk, QEMUSGList *sg, uint64_t sector, void (*cb)(void *opaque, int ret), void *opaque) { - return dma_blk_io(blk, sg, sector, blk_aio_writev, cb, opaque, + return dma_blk_io(blk, sg, sector, blk_aio_pwritev, cb, opaque, DMA_DIRECTION_TO_DEVICE); } diff --git a/hw/block/fdc.c b/hw/block/fdc.c index 372227569e..f73af7db46 100644 --- a/hw/block/fdc.c +++ b/hw/block/fdc.c @@ -223,6 +223,13 @@ static int fd_sector(FDrive *drv) NUM_SIDES(drv)); } +/* Returns current position, in bytes, for given drive */ +static int fd_offset(FDrive *drv) +{ + g_assert(fd_sector(drv) < INT_MAX >> BDRV_SECTOR_BITS); + return fd_sector(drv) << BDRV_SECTOR_BITS; +} + /* Seek to a new position: * returns 0 if already on right track * returns 1 if track changed @@ -1629,8 +1636,8 @@ static int fdctrl_transfer_handler (void *opaque, int nchan, if (fdctrl->data_dir != FD_DIR_WRITE || len < FD_SECTOR_LEN || rel_pos != 0) { /* READ & SCAN commands and realign to a sector for WRITE */ - if (blk_read(cur_drv->blk, fd_sector(cur_drv), - fdctrl->fifo, 1) < 0) { + if (blk_pread(cur_drv->blk, fd_offset(cur_drv), + fdctrl->fifo, BDRV_SECTOR_SIZE) < 0) { FLOPPY_DPRINTF("Floppy: error getting sector %d\n", fd_sector(cur_drv)); /* Sure, image size is too small... */ @@ -1657,8 +1664,8 @@ static int fdctrl_transfer_handler (void *opaque, int nchan, k->read_memory(fdctrl->dma, nchan, fdctrl->fifo + rel_pos, fdctrl->data_pos, len); - if (blk_write(cur_drv->blk, fd_sector(cur_drv), - fdctrl->fifo, 1) < 0) { + if (blk_pwrite(cur_drv->blk, fd_offset(cur_drv), + fdctrl->fifo, BDRV_SECTOR_SIZE, 0) < 0) { FLOPPY_DPRINTF("error writing sector %d\n", fd_sector(cur_drv)); fdctrl_stop_transfer(fdctrl, FD_SR0_ABNTERM | FD_SR0_SEEK, 0x00, 0x00); @@ -1741,7 +1748,8 @@ static uint32_t fdctrl_read_data(FDCtrl *fdctrl) fd_sector(cur_drv)); return 0; } - if (blk_read(cur_drv->blk, fd_sector(cur_drv), fdctrl->fifo, 1) + if (blk_pread(cur_drv->blk, fd_offset(cur_drv), fdctrl->fifo, + BDRV_SECTOR_SIZE) < 0) { FLOPPY_DPRINTF("error getting sector %d\n", fd_sector(cur_drv)); @@ -1820,7 +1828,8 @@ static void fdctrl_format_sector(FDCtrl *fdctrl) } memset(fdctrl->fifo, 0, FD_SECTOR_LEN); if (cur_drv->blk == NULL || - blk_write(cur_drv->blk, fd_sector(cur_drv), fdctrl->fifo, 1) < 0) { + blk_pwrite(cur_drv->blk, fd_offset(cur_drv), fdctrl->fifo, + BDRV_SECTOR_SIZE, 0) < 0) { FLOPPY_DPRINTF("error formatting sector %d\n", fd_sector(cur_drv)); fdctrl_stop_transfer(fdctrl, FD_SR0_ABNTERM | FD_SR0_SEEK, 0x00, 0x00); } else { @@ -2243,8 +2252,8 @@ static void fdctrl_write_data(FDCtrl *fdctrl, uint32_t value) if (pos == FD_SECTOR_LEN - 1 || fdctrl->data_pos == fdctrl->data_len) { cur_drv = get_cur_drv(fdctrl); - if (blk_write(cur_drv->blk, fd_sector(cur_drv), fdctrl->fifo, 1) - < 0) { + if (blk_pwrite(cur_drv->blk, fd_offset(cur_drv), fdctrl->fifo, + BDRV_SECTOR_SIZE, 0) < 0) { FLOPPY_DPRINTF("error writing sector %d\n", fd_sector(cur_drv)); break; diff --git a/hw/block/hd-geometry.c b/hw/block/hd-geometry.c index 6d02192dbb..d388f13e9d 100644 --- a/hw/block/hd-geometry.c +++ b/hw/block/hd-geometry.c @@ -66,7 +66,7 @@ static int guess_disk_lchs(BlockBackend *blk, * but also in async I/O mode. So the I/O throttling function has to * be disabled temporarily here, not permanently. */ - if (blk_read_unthrottled(blk, 0, buf, 1) < 0) { + if (blk_pread_unthrottled(blk, 0, buf, BDRV_SECTOR_SIZE) < 0) { return -1; } /* test msdos magic */ diff --git a/hw/block/m25p80.c b/hw/block/m25p80.c index 906b71257e..5d308637df 100644 --- a/hw/block/m25p80.c +++ b/hw/block/m25p80.c @@ -358,25 +358,21 @@ static void blk_sync_complete(void *opaque, int ret) static void flash_sync_page(Flash *s, int page) { - int blk_sector, nb_sectors; QEMUIOVector iov; if (!s->blk || blk_is_read_only(s->blk)) { return; } - blk_sector = (page * s->pi->page_size) / BDRV_SECTOR_SIZE; - nb_sectors = DIV_ROUND_UP(s->pi->page_size, BDRV_SECTOR_SIZE); qemu_iovec_init(&iov, 1); - qemu_iovec_add(&iov, s->storage + blk_sector * BDRV_SECTOR_SIZE, - nb_sectors * BDRV_SECTOR_SIZE); - blk_aio_writev(s->blk, blk_sector, &iov, nb_sectors, blk_sync_complete, - NULL); + qemu_iovec_add(&iov, s->storage + page * s->pi->page_size, + s->pi->page_size); + blk_aio_pwritev(s->blk, page * s->pi->page_size, &iov, 0, + blk_sync_complete, NULL); } static inline void flash_sync_area(Flash *s, int64_t off, int64_t len) { - int64_t start, end, nb_sectors; QEMUIOVector iov; if (!s->blk || blk_is_read_only(s->blk)) { @@ -384,13 +380,9 @@ static inline void flash_sync_area(Flash *s, int64_t off, int64_t len) } assert(!(len % BDRV_SECTOR_SIZE)); - start = off / BDRV_SECTOR_SIZE; - end = (off + len) / BDRV_SECTOR_SIZE; - nb_sectors = end - start; qemu_iovec_init(&iov, 1); - qemu_iovec_add(&iov, s->storage + (start * BDRV_SECTOR_SIZE), - nb_sectors * BDRV_SECTOR_SIZE); - blk_aio_writev(s->blk, start, &iov, nb_sectors, blk_sync_complete, NULL); + qemu_iovec_add(&iov, s->storage + off, len); + blk_aio_pwritev(s->blk, off, &iov, 0, blk_sync_complete, NULL); } static void flash_erase(Flash *s, int offset, FlashCMD cmd) @@ -907,8 +899,7 @@ static int m25p80_init(SSISlave *ss) s->storage = blk_blockalign(s->blk, s->size); /* FIXME: Move to late init */ - if (blk_read(s->blk, 0, s->storage, - DIV_ROUND_UP(s->size, BDRV_SECTOR_SIZE))) { + if (blk_pread(s->blk, 0, s->storage, s->size)) { fprintf(stderr, "Failed to initialize SPI flash!\n"); return 1; } diff --git a/hw/block/nand.c b/hw/block/nand.c index 29c6596810..c69e6755d9 100644 --- a/hw/block/nand.c +++ b/hw/block/nand.c @@ -663,7 +663,8 @@ static void glue(nand_blk_write_, PAGE_SIZE)(NANDFlashState *s) sector = SECTOR(s->addr); off = (s->addr & PAGE_MASK) + s->offset; soff = SECTOR_OFFSET(s->addr); - if (blk_read(s->blk, sector, iobuf, PAGE_SECTORS) < 0) { + if (blk_pread(s->blk, sector << BDRV_SECTOR_BITS, iobuf, + PAGE_SECTORS << BDRV_SECTOR_BITS) < 0) { printf("%s: read error in sector %" PRIu64 "\n", __func__, sector); return; } @@ -675,21 +676,24 @@ static void glue(nand_blk_write_, PAGE_SIZE)(NANDFlashState *s) MIN(OOB_SIZE, off + s->iolen - PAGE_SIZE)); } - if (blk_write(s->blk, sector, iobuf, PAGE_SECTORS) < 0) { + if (blk_pwrite(s->blk, sector << BDRV_SECTOR_BITS, iobuf, + PAGE_SECTORS << BDRV_SECTOR_BITS, 0) < 0) { printf("%s: write error in sector %" PRIu64 "\n", __func__, sector); } } else { off = PAGE_START(s->addr) + (s->addr & PAGE_MASK) + s->offset; sector = off >> 9; soff = off & 0x1ff; - if (blk_read(s->blk, sector, iobuf, PAGE_SECTORS + 2) < 0) { + if (blk_pread(s->blk, sector << BDRV_SECTOR_BITS, iobuf, + (PAGE_SECTORS + 2) << BDRV_SECTOR_BITS) < 0) { printf("%s: read error in sector %" PRIu64 "\n", __func__, sector); return; } mem_and(iobuf + soff, s->io, s->iolen); - if (blk_write(s->blk, sector, iobuf, PAGE_SECTORS + 2) < 0) { + if (blk_pwrite(s->blk, sector << BDRV_SECTOR_BITS, iobuf, + (PAGE_SECTORS + 2) << BDRV_SECTOR_BITS, 0) < 0) { printf("%s: write error in sector %" PRIu64 "\n", __func__, sector); } } @@ -716,17 +720,20 @@ static void glue(nand_blk_erase_, PAGE_SIZE)(NANDFlashState *s) i = SECTOR(addr); page = SECTOR(addr + (1 << (ADDR_SHIFT + s->erase_shift))); for (; i < page; i ++) - if (blk_write(s->blk, i, iobuf, 1) < 0) { + if (blk_pwrite(s->blk, i << BDRV_SECTOR_BITS, iobuf, + BDRV_SECTOR_SIZE, 0) < 0) { printf("%s: write error in sector %" PRIu64 "\n", __func__, i); } } else { addr = PAGE_START(addr); page = addr >> 9; - if (blk_read(s->blk, page, iobuf, 1) < 0) { + if (blk_pread(s->blk, page << BDRV_SECTOR_BITS, iobuf, + BDRV_SECTOR_SIZE) < 0) { printf("%s: read error in sector %" PRIu64 "\n", __func__, page); } memset(iobuf + (addr & 0x1ff), 0xff, (~addr & 0x1ff) + 1); - if (blk_write(s->blk, page, iobuf, 1) < 0) { + if (blk_pwrite(s->blk, page << BDRV_SECTOR_BITS, iobuf, + BDRV_SECTOR_SIZE, 0) < 0) { printf("%s: write error in sector %" PRIu64 "\n", __func__, page); } @@ -734,18 +741,20 @@ static void glue(nand_blk_erase_, PAGE_SIZE)(NANDFlashState *s) i = (addr & ~0x1ff) + 0x200; for (addr += ((PAGE_SIZE + OOB_SIZE) << s->erase_shift) - 0x200; i < addr; i += 0x200) { - if (blk_write(s->blk, i >> 9, iobuf, 1) < 0) { + if (blk_pwrite(s->blk, i, iobuf, BDRV_SECTOR_SIZE, 0) < 0) { printf("%s: write error in sector %" PRIu64 "\n", __func__, i >> 9); } } page = i >> 9; - if (blk_read(s->blk, page, iobuf, 1) < 0) { + if (blk_pread(s->blk, page << BDRV_SECTOR_BITS, iobuf, + BDRV_SECTOR_SIZE) < 0) { printf("%s: read error in sector %" PRIu64 "\n", __func__, page); } memset(iobuf, 0xff, ((addr - 1) & 0x1ff) + 1); - if (blk_write(s->blk, page, iobuf, 1) < 0) { + if (blk_pwrite(s->blk, page << BDRV_SECTOR_BITS, iobuf, + BDRV_SECTOR_SIZE, 0) < 0) { printf("%s: write error in sector %" PRIu64 "\n", __func__, page); } } @@ -760,7 +769,8 @@ static void glue(nand_blk_load_, PAGE_SIZE)(NANDFlashState *s, if (s->blk) { if (s->mem_oob) { - if (blk_read(s->blk, SECTOR(addr), s->io, PAGE_SECTORS) < 0) { + if (blk_pread(s->blk, SECTOR(addr) << BDRV_SECTOR_BITS, s->io, + PAGE_SECTORS << BDRV_SECTOR_BITS) < 0) { printf("%s: read error in sector %" PRIu64 "\n", __func__, SECTOR(addr)); } @@ -769,8 +779,8 @@ static void glue(nand_blk_load_, PAGE_SIZE)(NANDFlashState *s, OOB_SIZE); s->ioaddr = s->io + SECTOR_OFFSET(s->addr) + offset; } else { - if (blk_read(s->blk, PAGE_START(addr) >> 9, - s->io, (PAGE_SECTORS + 2)) < 0) { + if (blk_pread(s->blk, PAGE_START(addr), s->io, + (PAGE_SECTORS + 2) << BDRV_SECTOR_BITS) < 0) { printf("%s: read error in sector %" PRIu64 "\n", __func__, PAGE_START(addr) >> 9); } diff --git a/hw/block/onenand.c b/hw/block/onenand.c index 883f4b1faa..8d8422739e 100644 --- a/hw/block/onenand.c +++ b/hw/block/onenand.c @@ -224,7 +224,8 @@ static void onenand_reset(OneNANDState *s, int cold) /* Lock the whole flash */ memset(s->blockwp, ONEN_LOCK_LOCKED, s->blocks); - if (s->blk_cur && blk_read(s->blk_cur, 0, s->boot[0], 8) < 0) { + if (s->blk_cur && blk_pread(s->blk_cur, 0, s->boot[0], + 8 << BDRV_SECTOR_BITS) < 0) { hw_error("%s: Loading the BootRAM failed.\n", __func__); } } @@ -240,8 +241,11 @@ static void onenand_system_reset(DeviceState *dev) static inline int onenand_load_main(OneNANDState *s, int sec, int secn, void *dest) { + assert(UINT32_MAX >> BDRV_SECTOR_BITS > sec); + assert(UINT32_MAX >> BDRV_SECTOR_BITS > secn); if (s->blk_cur) { - return blk_read(s->blk_cur, sec, dest, secn) < 0; + return blk_pread(s->blk_cur, sec << BDRV_SECTOR_BITS, dest, + secn << BDRV_SECTOR_BITS) < 0; } else if (sec + secn > s->secs_cur) { return 1; } @@ -257,19 +261,22 @@ static inline int onenand_prog_main(OneNANDState *s, int sec, int secn, int result = 0; if (secn > 0) { - uint32_t size = (uint32_t)secn * 512; + uint32_t size = secn << BDRV_SECTOR_BITS; + uint32_t offset = sec << BDRV_SECTOR_BITS; + assert(UINT32_MAX >> BDRV_SECTOR_BITS > sec); + assert(UINT32_MAX >> BDRV_SECTOR_BITS > secn); const uint8_t *sp = (const uint8_t *)src; uint8_t *dp = 0; if (s->blk_cur) { dp = g_malloc(size); - if (!dp || blk_read(s->blk_cur, sec, dp, secn) < 0) { + if (!dp || blk_pread(s->blk_cur, offset, dp, size) < 0) { result = 1; } } else { if (sec + secn > s->secs_cur) { result = 1; } else { - dp = (uint8_t *)s->current + (sec << 9); + dp = (uint8_t *)s->current + offset; } } if (!result) { @@ -278,7 +285,7 @@ static inline int onenand_prog_main(OneNANDState *s, int sec, int secn, dp[i] &= sp[i]; } if (s->blk_cur) { - result = blk_write(s->blk_cur, sec, dp, secn) < 0; + result = blk_pwrite(s->blk_cur, offset, dp, size, 0) < 0; } } if (dp && s->blk_cur) { @@ -295,7 +302,8 @@ static inline int onenand_load_spare(OneNANDState *s, int sec, int secn, uint8_t buf[512]; if (s->blk_cur) { - if (blk_read(s->blk_cur, s->secs_cur + (sec >> 5), buf, 1) < 0) { + uint32_t offset = (s->secs_cur + (sec >> 5)) << BDRV_SECTOR_BITS; + if (blk_pread(s->blk_cur, offset, buf, BDRV_SECTOR_SIZE) < 0) { return 1; } memcpy(dest, buf + ((sec & 31) << 4), secn << 4); @@ -304,7 +312,7 @@ static inline int onenand_load_spare(OneNANDState *s, int sec, int secn, } else { memcpy(dest, s->current + (s->secs_cur << 9) + (sec << 4), secn << 4); } - + return 0; } @@ -315,10 +323,12 @@ static inline int onenand_prog_spare(OneNANDState *s, int sec, int secn, if (secn > 0) { const uint8_t *sp = (const uint8_t *)src; uint8_t *dp = 0, *dpp = 0; + uint32_t offset = (s->secs_cur + (sec >> 5)) << BDRV_SECTOR_BITS; + assert(UINT32_MAX >> BDRV_SECTOR_BITS > s->secs_cur + (sec >> 5)); if (s->blk_cur) { dp = g_malloc(512); if (!dp - || blk_read(s->blk_cur, s->secs_cur + (sec >> 5), dp, 1) < 0) { + || blk_pread(s->blk_cur, offset, dp, BDRV_SECTOR_SIZE) < 0) { result = 1; } else { dpp = dp + ((sec & 31) << 4); @@ -336,8 +346,8 @@ static inline int onenand_prog_spare(OneNANDState *s, int sec, int secn, dpp[i] &= sp[i]; } if (s->blk_cur) { - result = blk_write(s->blk_cur, s->secs_cur + (sec >> 5), - dp, 1) < 0; + result = blk_pwrite(s->blk_cur, offset, dp, + BDRV_SECTOR_SIZE, 0) < 0; } } g_free(dp); @@ -355,14 +365,17 @@ static inline int onenand_erase(OneNANDState *s, int sec, int num) for (; num > 0; num--, sec++) { if (s->blk_cur) { int erasesec = s->secs_cur + (sec >> 5); - if (blk_write(s->blk_cur, sec, blankbuf, 1) < 0) { + if (blk_pwrite(s->blk_cur, sec << BDRV_SECTOR_BITS, blankbuf, + BDRV_SECTOR_SIZE, 0) < 0) { goto fail; } - if (blk_read(s->blk_cur, erasesec, tmpbuf, 1) < 0) { + if (blk_pread(s->blk_cur, erasesec << BDRV_SECTOR_BITS, tmpbuf, + BDRV_SECTOR_SIZE) < 0) { goto fail; } memcpy(tmpbuf + ((sec & 31) << 4), blankbuf, 1 << 4); - if (blk_write(s->blk_cur, erasesec, tmpbuf, 1) < 0) { + if (blk_pwrite(s->blk_cur, erasesec << BDRV_SECTOR_BITS, tmpbuf, + BDRV_SECTOR_SIZE, 0) < 0) { goto fail; } } else { diff --git a/hw/block/pflash_cfi01.c b/hw/block/pflash_cfi01.c index 106a775232..3a1f85d279 100644 --- a/hw/block/pflash_cfi01.c +++ b/hw/block/pflash_cfi01.c @@ -413,11 +413,11 @@ static void pflash_update(pflash_t *pfl, int offset, int offset_end; if (pfl->blk) { offset_end = offset + size; - /* round to sectors */ - offset = offset >> 9; - offset_end = (offset_end + 511) >> 9; - blk_write(pfl->blk, offset, pfl->storage + (offset << 9), - offset_end - offset); + /* widen to sector boundaries */ + offset = QEMU_ALIGN_DOWN(offset, BDRV_SECTOR_SIZE); + offset_end = QEMU_ALIGN_UP(offset_end, BDRV_SECTOR_SIZE); + blk_pwrite(pfl->blk, offset, pfl->storage + offset, + offset_end - offset, 0); } } @@ -739,7 +739,7 @@ static void pflash_cfi01_realize(DeviceState *dev, Error **errp) if (pfl->blk) { /* read the initial flash content */ - ret = blk_read(pfl->blk, 0, pfl->storage, total_len >> 9); + ret = blk_pread(pfl->blk, 0, pfl->storage, total_len); if (ret < 0) { vmstate_unregister_ram(&pfl->mem, DEVICE(pfl)); diff --git a/hw/block/pflash_cfi02.c b/hw/block/pflash_cfi02.c index b13172c6e1..5f106102c5 100644 --- a/hw/block/pflash_cfi02.c +++ b/hw/block/pflash_cfi02.c @@ -253,11 +253,11 @@ static void pflash_update(pflash_t *pfl, int offset, int offset_end; if (pfl->blk) { offset_end = offset + size; - /* round to sectors */ - offset = offset >> 9; - offset_end = (offset_end + 511) >> 9; - blk_write(pfl->blk, offset, pfl->storage + (offset << 9), - offset_end - offset); + /* widen to sector boundaries */ + offset = QEMU_ALIGN_DOWN(offset, BDRV_SECTOR_SIZE); + offset_end = QEMU_ALIGN_UP(offset_end, BDRV_SECTOR_SIZE); + blk_pwrite(pfl->blk, offset, pfl->storage + offset, + offset_end - offset, 0); } } @@ -622,7 +622,7 @@ static void pflash_cfi02_realize(DeviceState *dev, Error **errp) pfl->chip_len = chip_len; if (pfl->blk) { /* read the initial flash content */ - ret = blk_read(pfl->blk, 0, pfl->storage, chip_len >> 9); + ret = blk_pread(pfl->blk, 0, pfl->storage, chip_len); if (ret < 0) { vmstate_unregister_ram(&pfl->orig_mem, DEVICE(pfl)); error_setg(errp, "failed to read the initial flash content"); diff --git a/hw/block/virtio-blk.c b/hw/block/virtio-blk.c index 3f88f8cf59..284e64667c 100644 --- a/hw/block/virtio-blk.c +++ b/hw/block/virtio-blk.c @@ -322,7 +322,6 @@ static inline void submit_requests(BlockBackend *blk, MultiReqBuffer *mrb, { QEMUIOVector *qiov = &mrb->reqs[start]->qiov; int64_t sector_num = mrb->reqs[start]->sector_num; - int nb_sectors = mrb->reqs[start]->qiov.size / BDRV_SECTOR_SIZE; bool is_write = mrb->is_write; if (num_reqs > 1) { @@ -331,7 +330,7 @@ static inline void submit_requests(BlockBackend *blk, MultiReqBuffer *mrb, int tmp_niov = qiov->niov; /* mrb->reqs[start]->qiov was initialized from external so we can't - * modifiy it here. We need to initialize it locally and then add the + * modify it here. We need to initialize it locally and then add the * external iovecs. */ qemu_iovec_init(qiov, niov); @@ -343,23 +342,22 @@ static inline void submit_requests(BlockBackend *blk, MultiReqBuffer *mrb, qemu_iovec_concat(qiov, &mrb->reqs[i]->qiov, 0, mrb->reqs[i]->qiov.size); mrb->reqs[i - 1]->mr_next = mrb->reqs[i]; - nb_sectors += mrb->reqs[i]->qiov.size / BDRV_SECTOR_SIZE; } - assert(nb_sectors == qiov->size / BDRV_SECTOR_SIZE); - trace_virtio_blk_submit_multireq(mrb, start, num_reqs, sector_num, - nb_sectors, is_write); + trace_virtio_blk_submit_multireq(mrb, start, num_reqs, + sector_num << BDRV_SECTOR_BITS, + qiov->size, is_write); block_acct_merge_done(blk_get_stats(blk), is_write ? BLOCK_ACCT_WRITE : BLOCK_ACCT_READ, num_reqs - 1); } if (is_write) { - blk_aio_writev(blk, sector_num, qiov, nb_sectors, - virtio_blk_rw_complete, mrb->reqs[start]); + blk_aio_pwritev(blk, sector_num << BDRV_SECTOR_BITS, qiov, 0, + virtio_blk_rw_complete, mrb->reqs[start]); } else { - blk_aio_readv(blk, sector_num, qiov, nb_sectors, - virtio_blk_rw_complete, mrb->reqs[start]); + blk_aio_preadv(blk, sector_num << BDRV_SECTOR_BITS, qiov, 0, + virtio_blk_rw_complete, mrb->reqs[start]); } } diff --git a/hw/block/xen_disk.c b/hw/block/xen_disk.c index d4ce380fee..064c116a7c 100644 --- a/hw/block/xen_disk.c +++ b/hw/block/xen_disk.c @@ -554,9 +554,8 @@ static int ioreq_runio_qemu_aio(struct ioreq *ioreq) block_acct_start(blk_get_stats(blkdev->blk), &ioreq->acct, ioreq->v.size, BLOCK_ACCT_READ); ioreq->aio_inflight++; - blk_aio_readv(blkdev->blk, ioreq->start / BLOCK_SIZE, - &ioreq->v, ioreq->v.size / BLOCK_SIZE, - qemu_aio_complete, ioreq); + blk_aio_preadv(blkdev->blk, ioreq->start, &ioreq->v, 0, + qemu_aio_complete, ioreq); break; case BLKIF_OP_WRITE: case BLKIF_OP_FLUSH_DISKCACHE: @@ -569,9 +568,8 @@ static int ioreq_runio_qemu_aio(struct ioreq *ioreq) ioreq->req.operation == BLKIF_OP_WRITE ? BLOCK_ACCT_WRITE : BLOCK_ACCT_FLUSH); ioreq->aio_inflight++; - blk_aio_writev(blkdev->blk, ioreq->start / BLOCK_SIZE, - &ioreq->v, ioreq->v.size / BLOCK_SIZE, - qemu_aio_complete, ioreq); + blk_aio_pwritev(blkdev->blk, ioreq->start, &ioreq->v, 0, + qemu_aio_complete, ioreq); break; case BLKIF_OP_DISCARD: { diff --git a/hw/ide/atapi.c b/hw/ide/atapi.c index 2bb606c1c5..95056d92e7 100644 --- a/hw/ide/atapi.c +++ b/hw/ide/atapi.c @@ -28,6 +28,9 @@ #include "hw/scsi/scsi.h" #include "sysemu/block-backend.h" +#define ATAPI_SECTOR_BITS (2 + BDRV_SECTOR_BITS) +#define ATAPI_SECTOR_SIZE (1 << ATAPI_SECTOR_BITS) + static void ide_atapi_cmd_read_dma_cb(void *opaque, int ret); static void padstr8(uint8_t *buf, int buf_size, const char *src) @@ -111,7 +114,7 @@ cd_read_sector_sync(IDEState *s) { int ret; block_acct_start(blk_get_stats(s->blk), &s->acct, - 4 * BDRV_SECTOR_SIZE, BLOCK_ACCT_READ); + ATAPI_SECTOR_SIZE, BLOCK_ACCT_READ); #ifdef DEBUG_IDE_ATAPI printf("cd_read_sector_sync: lba=%d\n", s->lba); @@ -119,12 +122,12 @@ cd_read_sector_sync(IDEState *s) switch (s->cd_sector_size) { case 2048: - ret = blk_read(s->blk, (int64_t)s->lba << 2, - s->io_buffer, 4); + ret = blk_pread(s->blk, (int64_t)s->lba << ATAPI_SECTOR_BITS, + s->io_buffer, ATAPI_SECTOR_SIZE); break; case 2352: - ret = blk_read(s->blk, (int64_t)s->lba << 2, - s->io_buffer + 16, 4); + ret = blk_pread(s->blk, (int64_t)s->lba << ATAPI_SECTOR_BITS, + s->io_buffer + 16, ATAPI_SECTOR_SIZE); if (ret >= 0) { cd_data_to_raw(s->io_buffer, s->lba); } @@ -182,7 +185,7 @@ static int cd_read_sector(IDEState *s) s->iov.iov_base = (s->cd_sector_size == 2352) ? s->io_buffer + 16 : s->io_buffer; - s->iov.iov_len = 4 * BDRV_SECTOR_SIZE; + s->iov.iov_len = ATAPI_SECTOR_SIZE; qemu_iovec_init_external(&s->qiov, &s->iov, 1); #ifdef DEBUG_IDE_ATAPI @@ -190,7 +193,7 @@ static int cd_read_sector(IDEState *s) #endif block_acct_start(blk_get_stats(s->blk), &s->acct, - 4 * BDRV_SECTOR_SIZE, BLOCK_ACCT_READ); + ATAPI_SECTOR_SIZE, BLOCK_ACCT_READ); ide_buffered_readv(s, (int64_t)s->lba << 2, &s->qiov, 4, cd_read_sector_cb, s); @@ -435,7 +438,7 @@ static void ide_atapi_cmd_read_dma_cb(void *opaque, int ret) #endif s->bus->dma->iov.iov_base = (void *)(s->io_buffer + data_offset); - s->bus->dma->iov.iov_len = n * 4 * 512; + s->bus->dma->iov.iov_len = n * ATAPI_SECTOR_SIZE; qemu_iovec_init_external(&s->bus->dma->qiov, &s->bus->dma->iov, 1); s->bus->dma->aiocb = ide_buffered_readv(s, (int64_t)s->lba << 2, diff --git a/hw/ide/core.c b/hw/ide/core.c index 41e6a2dc45..fe2bfba489 100644 --- a/hw/ide/core.c +++ b/hw/ide/core.c @@ -442,7 +442,7 @@ static void ide_issue_trim_cb(void *opaque, int ret) } BlockAIOCB *ide_issue_trim(BlockBackend *blk, - int64_t sector_num, QEMUIOVector *qiov, int nb_sectors, + int64_t offset, QEMUIOVector *qiov, BdrvRequestFlags flags, BlockCompletionFunc *cb, void *opaque) { TrimAIOCB *iocb; @@ -616,8 +616,8 @@ BlockAIOCB *ide_buffered_readv(IDEState *s, int64_t sector_num, req->iov.iov_len = iov->size; qemu_iovec_init_external(&req->qiov, &req->iov, 1); - aioreq = blk_aio_readv(s->blk, sector_num, &req->qiov, nb_sectors, - ide_buffered_readv_cb, req); + aioreq = blk_aio_preadv(s->blk, sector_num << BDRV_SECTOR_BITS, + &req->qiov, 0, ide_buffered_readv_cb, req); QLIST_INSERT_HEAD(&s->buffered_requests, req, list); return aioreq; @@ -1006,8 +1006,8 @@ static void ide_sector_write(IDEState *s) block_acct_start(blk_get_stats(s->blk), &s->acct, n * BDRV_SECTOR_SIZE, BLOCK_ACCT_WRITE); - s->pio_aiocb = blk_aio_writev(s->blk, sector_num, &s->qiov, n, - ide_sector_write_cb, s); + s->pio_aiocb = blk_aio_pwritev(s->blk, sector_num << BDRV_SECTOR_BITS, + &s->qiov, 0, ide_sector_write_cb, s); } static void ide_flush_cb(void *opaque, int ret) diff --git a/hw/ide/internal.h b/hw/ide/internal.h index d2c458f579..ceb9e5994a 100644 --- a/hw/ide/internal.h +++ b/hw/ide/internal.h @@ -614,7 +614,7 @@ void ide_transfer_start(IDEState *s, uint8_t *buf, int size, void ide_transfer_stop(IDEState *s); void ide_set_inactive(IDEState *s, bool more); BlockAIOCB *ide_issue_trim(BlockBackend *blk, - int64_t sector_num, QEMUIOVector *qiov, int nb_sectors, + int64_t offset, QEMUIOVector *qiov, BdrvRequestFlags flags, BlockCompletionFunc *cb, void *opaque); BlockAIOCB *ide_buffered_readv(IDEState *s, int64_t sector_num, QEMUIOVector *iov, int nb_sectors, diff --git a/hw/ide/macio.c b/hw/ide/macio.c index 76256eb8a8..d7d9c0ff3a 100644 --- a/hw/ide/macio.c +++ b/hw/ide/macio.c @@ -55,8 +55,8 @@ static const int debug_macio = 0; /* * Unaligned DMA read/write access functions required for OS X/Darwin which * don't perform DMA transactions on sector boundaries. These functions are - * modelled on bdrv_co_do_preadv()/bdrv_co_do_pwritev() and so should be - * easy to remove if the unaligned block APIs are ever exposed. + * modelled on bdrv_co_preadv()/bdrv_co_pwritev() and so should be easy to + * remove if the unaligned block APIs are ever exposed. */ static void pmac_dma_read(BlockBackend *blk, @@ -120,8 +120,7 @@ static void pmac_dma_read(BlockBackend *blk, MACIO_DPRINTF("--- Block read transfer - sector_num: %" PRIx64 " " "nsector: %x\n", (offset >> 9), (bytes >> 9)); - s->bus->dma->aiocb = blk_aio_readv(blk, (offset >> 9), &io->iov, - (bytes >> 9), cb, io); + s->bus->dma->aiocb = blk_aio_preadv(blk, offset, &io->iov, 0, cb, io); } static void pmac_dma_write(BlockBackend *blk, @@ -205,8 +204,7 @@ static void pmac_dma_write(BlockBackend *blk, MACIO_DPRINTF("--- Block write transfer - sector_num: %" PRIx64 " " "nsector: %x\n", (offset >> 9), (bytes >> 9)); - s->bus->dma->aiocb = blk_aio_writev(blk, (offset >> 9), &io->iov, - (bytes >> 9), cb, io); + s->bus->dma->aiocb = blk_aio_pwritev(blk, offset, &io->iov, 0, cb, io); } static void pmac_dma_trim(BlockBackend *blk, @@ -232,8 +230,7 @@ static void pmac_dma_trim(BlockBackend *blk, s->io_buffer_index += io->len; io->len = 0; - s->bus->dma->aiocb = ide_issue_trim(blk, (offset >> 9), &io->iov, - (bytes >> 9), cb, io); + s->bus->dma->aiocb = ide_issue_trim(blk, offset, &io->iov, 0, cb, io); } static void pmac_ide_atapi_transfer_cb(void *opaque, int ret) diff --git a/hw/nvram/spapr_nvram.c b/hw/nvram/spapr_nvram.c index 802636ef35..019f25dc58 100644 --- a/hw/nvram/spapr_nvram.c +++ b/hw/nvram/spapr_nvram.c @@ -124,7 +124,7 @@ static void rtas_nvram_store(PowerPCCPU *cpu, sPAPRMachineState *spapr, alen = len; if (nvram->blk) { - alen = blk_pwrite(nvram->blk, offset, membuf, len); + alen = blk_pwrite(nvram->blk, offset, membuf, len, 0); } assert(nvram->buf); @@ -190,7 +190,7 @@ static int spapr_nvram_post_load(void *opaque, int version_id) sPAPRNVRAM *nvram = VIO_SPAPR_NVRAM(opaque); if (nvram->blk) { - int alen = blk_pwrite(nvram->blk, 0, nvram->buf, nvram->size); + int alen = blk_pwrite(nvram->blk, 0, nvram->buf, nvram->size, 0); if (alen < 0) { return alen; diff --git a/hw/scsi/scsi-disk.c b/hw/scsi/scsi-disk.c index c3ce54a203..ce89c98b4e 100644 --- a/hw/scsi/scsi-disk.c +++ b/hw/scsi/scsi-disk.c @@ -108,7 +108,7 @@ static void scsi_check_condition(SCSIDiskReq *r, SCSISense sense) scsi_req_complete(&r->req, CHECK_CONDITION); } -static uint32_t scsi_init_iovec(SCSIDiskReq *r, size_t size) +static void scsi_init_iovec(SCSIDiskReq *r, size_t size) { SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, r->req.dev); @@ -118,7 +118,6 @@ static uint32_t scsi_init_iovec(SCSIDiskReq *r, size_t size) } r->iov.iov_len = MIN(r->sector_count * 512, r->buflen); qemu_iovec_init_external(&r->qiov, &r->iov, 1); - return r->qiov.size / 512; } static void scsi_disk_save_request(QEMUFile *f, SCSIRequest *req) @@ -316,7 +315,6 @@ done: static void scsi_do_read(SCSIDiskReq *r, int ret) { SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, r->req.dev); - uint32_t n; assert (r->req.aiocb == NULL); @@ -340,11 +338,12 @@ static void scsi_do_read(SCSIDiskReq *r, int ret) r->req.aiocb = dma_blk_read(s->qdev.conf.blk, r->req.sg, r->sector, scsi_dma_complete, r); } else { - n = scsi_init_iovec(r, SCSI_DMA_BUF_SIZE); + scsi_init_iovec(r, SCSI_DMA_BUF_SIZE); block_acct_start(blk_get_stats(s->qdev.conf.blk), &r->acct, - n * BDRV_SECTOR_SIZE, BLOCK_ACCT_READ); - r->req.aiocb = blk_aio_readv(s->qdev.conf.blk, r->sector, &r->qiov, n, - scsi_read_complete, r); + r->qiov.size, BLOCK_ACCT_READ); + r->req.aiocb = blk_aio_preadv(s->qdev.conf.blk, + r->sector << BDRV_SECTOR_BITS, &r->qiov, + 0, scsi_read_complete, r); } done: @@ -504,7 +503,6 @@ static void scsi_write_data(SCSIRequest *req) { SCSIDiskReq *r = DO_UPCAST(SCSIDiskReq, req, req); SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, r->req.dev); - uint32_t n; /* No data transfer may already be in progress */ assert(r->req.aiocb == NULL); @@ -544,11 +542,11 @@ static void scsi_write_data(SCSIRequest *req) r->req.aiocb = dma_blk_write(s->qdev.conf.blk, r->req.sg, r->sector, scsi_dma_complete, r); } else { - n = r->qiov.size / 512; block_acct_start(blk_get_stats(s->qdev.conf.blk), &r->acct, - n * BDRV_SECTOR_SIZE, BLOCK_ACCT_WRITE); - r->req.aiocb = blk_aio_writev(s->qdev.conf.blk, r->sector, &r->qiov, n, - scsi_write_complete, r); + r->qiov.size, BLOCK_ACCT_WRITE); + r->req.aiocb = blk_aio_pwritev(s->qdev.conf.blk, + r->sector << BDRV_SECTOR_BITS, &r->qiov, + 0, scsi_write_complete, r); } } @@ -1730,13 +1728,13 @@ static void scsi_write_same_complete(void *opaque, int ret) if (data->iov.iov_len) { block_acct_start(blk_get_stats(s->qdev.conf.blk), &r->acct, data->iov.iov_len, BLOCK_ACCT_WRITE); - /* blk_aio_write doesn't like the qiov size being different from - * nb_sectors, make sure they match. - */ + /* Reinitialize qiov, to handle unaligned WRITE SAME request + * where final qiov may need smaller size */ qemu_iovec_init_external(&data->qiov, &data->iov, 1); - r->req.aiocb = blk_aio_writev(s->qdev.conf.blk, data->sector, - &data->qiov, data->iov.iov_len / 512, - scsi_write_same_complete, data); + r->req.aiocb = blk_aio_pwritev(s->qdev.conf.blk, + data->sector << BDRV_SECTOR_BITS, + &data->qiov, 0, + scsi_write_same_complete, data); return; } @@ -1781,8 +1779,8 @@ static void scsi_disk_emulate_write_same(SCSIDiskReq *r, uint8_t *inbuf) nb_sectors * s->qdev.blocksize, BLOCK_ACCT_WRITE); r->req.aiocb = blk_aio_write_zeroes(s->qdev.conf.blk, - r->req.cmd.lba * (s->qdev.blocksize / 512), - nb_sectors * (s->qdev.blocksize / 512), + r->req.cmd.lba * s->qdev.blocksize, + nb_sectors * s->qdev.blocksize, flags, scsi_aio_complete, r); return; } @@ -1803,9 +1801,10 @@ static void scsi_disk_emulate_write_same(SCSIDiskReq *r, uint8_t *inbuf) scsi_req_ref(&r->req); block_acct_start(blk_get_stats(s->qdev.conf.blk), &r->acct, data->iov.iov_len, BLOCK_ACCT_WRITE); - r->req.aiocb = blk_aio_writev(s->qdev.conf.blk, data->sector, - &data->qiov, data->iov.iov_len / 512, - scsi_write_same_complete, data); + r->req.aiocb = blk_aio_pwritev(s->qdev.conf.blk, + data->sector << BDRV_SECTOR_BITS, + &data->qiov, 0, + scsi_write_same_complete, data); } static void scsi_disk_emulate_write_data(SCSIRequest *req) diff --git a/hw/sd/sd.c b/hw/sd/sd.c index b66e5d2dba..87e3d23a3d 100644 --- a/hw/sd/sd.c +++ b/hw/sd/sd.c @@ -123,7 +123,6 @@ struct SDState { qemu_irq readonly_cb; qemu_irq inserted_cb; BlockBackend *blk; - uint8_t *buf; bool enable; }; @@ -551,7 +550,7 @@ static const VMStateDescription sd_vmstate = { VMSTATE_UINT64(data_start, SDState), VMSTATE_UINT32(data_offset, SDState), VMSTATE_UINT8_ARRAY(data, SDState, 512), - VMSTATE_BUFFER_POINTER_UNSAFE(buf, SDState, 1, 512), + VMSTATE_UNUSED_V(1, 512), VMSTATE_BOOL(enable, SDState), VMSTATE_END_OF_LIST() }, @@ -1577,57 +1576,17 @@ send_response: static void sd_blk_read(SDState *sd, uint64_t addr, uint32_t len) { - uint64_t end = addr + len; - DPRINTF("sd_blk_read: addr = 0x%08llx, len = %d\n", (unsigned long long) addr, len); - if (!sd->blk || blk_read(sd->blk, addr >> 9, sd->buf, 1) < 0) { + if (!sd->blk || blk_pread(sd->blk, addr, sd->data, len) < 0) { fprintf(stderr, "sd_blk_read: read error on host side\n"); - return; } - - if (end > (addr & ~511) + 512) { - memcpy(sd->data, sd->buf + (addr & 511), 512 - (addr & 511)); - - if (blk_read(sd->blk, end >> 9, sd->buf, 1) < 0) { - fprintf(stderr, "sd_blk_read: read error on host side\n"); - return; - } - memcpy(sd->data + 512 - (addr & 511), sd->buf, end & 511); - } else - memcpy(sd->data, sd->buf + (addr & 511), len); } static void sd_blk_write(SDState *sd, uint64_t addr, uint32_t len) { - uint64_t end = addr + len; - - if ((addr & 511) || len < 512) - if (!sd->blk || blk_read(sd->blk, addr >> 9, sd->buf, 1) < 0) { - fprintf(stderr, "sd_blk_write: read error on host side\n"); - return; - } - - if (end > (addr & ~511) + 512) { - memcpy(sd->buf + (addr & 511), sd->data, 512 - (addr & 511)); - if (blk_write(sd->blk, addr >> 9, sd->buf, 1) < 0) { - fprintf(stderr, "sd_blk_write: write error on host side\n"); - return; - } - - if (blk_read(sd->blk, end >> 9, sd->buf, 1) < 0) { - fprintf(stderr, "sd_blk_write: read error on host side\n"); - return; - } - memcpy(sd->buf, sd->data + 512 - (addr & 511), end & 511); - if (blk_write(sd->blk, end >> 9, sd->buf, 1) < 0) { - fprintf(stderr, "sd_blk_write: write error on host side\n"); - } - } else { - memcpy(sd->buf + (addr & 511), sd->data, len); - if (!sd->blk || blk_write(sd->blk, addr >> 9, sd->buf, 1) < 0) { - fprintf(stderr, "sd_blk_write: write error on host side\n"); - } + if (!sd->blk || blk_pwrite(sd->blk, addr, sd->data, len, 0) < 0) { + fprintf(stderr, "sd_blk_write: write error on host side\n"); } } @@ -1925,8 +1884,6 @@ static void sd_realize(DeviceState *dev, Error **errp) return; } - sd->buf = blk_blockalign(sd->blk, 512); - if (sd->blk) { blk_set_dev_ops(sd->blk, &sd_block_ops, sd); } diff --git a/include/block/block.h b/include/block/block.h index 3a731377db..b210832778 100644 --- a/include/block/block.h +++ b/include/block/block.h @@ -476,6 +476,10 @@ void bdrv_disable_copy_on_read(BlockDriverState *bs); void bdrv_ref(BlockDriverState *bs); void bdrv_unref(BlockDriverState *bs); void bdrv_unref_child(BlockDriverState *parent, BdrvChild *child); +BdrvChild *bdrv_attach_child(BlockDriverState *parent_bs, + BlockDriverState *child_bs, + const char *child_name, + const BdrvChildRole *child_role); bool bdrv_op_is_blocked(BlockDriverState *bs, BlockOpType op, Error **errp); void bdrv_op_block(BlockDriverState *bs, BlockOpType op, Error *reason); @@ -520,7 +524,8 @@ int bdrv_probe_geometry(BlockDriverState *bs, HDGeometry *geo); void bdrv_io_plug(BlockDriverState *bs); void bdrv_io_unplug(BlockDriverState *bs); -void bdrv_flush_io_queue(BlockDriverState *bs); +void bdrv_io_unplugged_begin(BlockDriverState *bs); +void bdrv_io_unplugged_end(BlockDriverState *bs); /** * bdrv_drained_begin: @@ -541,4 +546,8 @@ void bdrv_drained_begin(BlockDriverState *bs); */ void bdrv_drained_end(BlockDriverState *bs); +void bdrv_add_child(BlockDriverState *parent, BlockDriverState *child, + Error **errp); +void bdrv_del_child(BlockDriverState *parent, BdrvChild *child, Error **errp); + #endif diff --git a/include/block/block_int.h b/include/block/block_int.h index 10d87595be..a029c2003f 100644 --- a/include/block/block_int.h +++ b/include/block/block_int.h @@ -38,12 +38,12 @@ #include "qemu/throttle.h" #define BLOCK_FLAG_ENCRYPT 1 -#define BLOCK_FLAG_COMPAT6 4 #define BLOCK_FLAG_LAZY_REFCOUNTS 8 #define BLOCK_OPT_SIZE "size" #define BLOCK_OPT_ENCRYPT "encryption" #define BLOCK_OPT_COMPAT6 "compat6" +#define BLOCK_OPT_HWVERSION "hwversion" #define BLOCK_OPT_BACKING_FILE "backing_file" #define BLOCK_OPT_BACKING_FMT "backing_fmt" #define BLOCK_OPT_CLUSTER_SIZE "cluster_size" @@ -127,10 +127,6 @@ struct BlockDriver { Error **errp); int (*bdrv_file_open)(BlockDriverState *bs, QDict *options, int flags, Error **errp); - int (*bdrv_read)(BlockDriverState *bs, int64_t sector_num, - uint8_t *buf, int nb_sectors); - int (*bdrv_write)(BlockDriverState *bs, int64_t sector_num, - const uint8_t *buf, int nb_sectors); void (*bdrv_close)(BlockDriverState *bs); int (*bdrv_create)(const char *filename, QemuOpts *opts, Error **errp); int (*bdrv_set_key)(BlockDriverState *bs, const char *key); @@ -153,18 +149,20 @@ struct BlockDriver { int coroutine_fn (*bdrv_co_readv)(BlockDriverState *bs, int64_t sector_num, int nb_sectors, QEMUIOVector *qiov); + int coroutine_fn (*bdrv_co_preadv)(BlockDriverState *bs, + uint64_t offset, uint64_t bytes, QEMUIOVector *qiov, int flags); int coroutine_fn (*bdrv_co_writev)(BlockDriverState *bs, int64_t sector_num, int nb_sectors, QEMUIOVector *qiov); int coroutine_fn (*bdrv_co_writev_flags)(BlockDriverState *bs, int64_t sector_num, int nb_sectors, QEMUIOVector *qiov, int flags); - - int supported_write_flags; + int coroutine_fn (*bdrv_co_pwritev)(BlockDriverState *bs, + uint64_t offset, uint64_t bytes, QEMUIOVector *qiov, int flags); /* * Efficiently zero a region of the disk image. Typically an image format * would use a compact metadata representation to implement this. This - * function pointer may be NULL and .bdrv_co_writev() will be called - * instead. + * function pointer may be NULL or return -ENOSUP and .bdrv_co_writev() + * will be called instead. */ int coroutine_fn (*bdrv_co_write_zeroes)(BlockDriverState *bs, int64_t sector_num, int nb_sectors, BdrvRequestFlags flags); @@ -294,7 +292,6 @@ struct BlockDriver { /* io queue for linux-aio */ void (*bdrv_io_plug)(BlockDriverState *bs); void (*bdrv_io_unplug)(BlockDriverState *bs); - void (*bdrv_flush_io_queue)(BlockDriverState *bs); /** * Try to get @bs's logical and physical block size. @@ -317,6 +314,11 @@ struct BlockDriver { */ void (*bdrv_drain)(BlockDriverState *bs); + void (*bdrv_add_child)(BlockDriverState *parent, BlockDriverState *child, + Error **errp); + void (*bdrv_del_child)(BlockDriverState *parent, BdrvChild *child, + Error **errp); + QLIST_ENTRY(BlockDriver) list; }; @@ -424,10 +426,10 @@ struct BlockDriverState { /* I/O throttling. * throttle_state tells us if this BDS has I/O limits configured. - * io_limits_enabled tells us if they are currently being - * enforced, but it can be temporarily set to false */ + * io_limits_disabled tells us if they are currently being enforced */ CoQueue throttled_reqs[2]; - bool io_limits_enabled; + unsigned int io_limits_disabled; + /* The following fields are protected by the ThrottleGroup lock. * See the ThrottleGroup documentation for details. */ ThrottleState *throttle_state; @@ -446,6 +448,11 @@ struct BlockDriverState { /* Alignment requirement for offset/length of I/O requests */ unsigned int request_alignment; + /* Flags honored during pwrite (so far: BDRV_REQ_FUA) */ + unsigned int supported_write_flags; + /* Flags honored during write_zeroes (so far: BDRV_REQ_FUA, + * BDRV_REQ_MAY_UNMAP) */ + unsigned int supported_zero_flags; /* the following member gives a name to every node on the bs graph. */ char node_name[32]; @@ -484,6 +491,10 @@ struct BlockDriverState { uint64_t write_threshold_offset; NotifierWithReturn write_threshold_notifier; + /* counters for nested bdrv_io_plug and bdrv_io_unplugged_begin */ + unsigned io_plugged; + unsigned io_plug_disabled; + int quiesce_counter; }; @@ -517,10 +528,10 @@ extern BlockDriver bdrv_qcow2; */ void bdrv_setup_io_funcs(BlockDriver *bdrv); -int coroutine_fn bdrv_co_do_preadv(BlockDriverState *bs, +int coroutine_fn bdrv_co_preadv(BlockDriverState *bs, int64_t offset, unsigned int bytes, QEMUIOVector *qiov, BdrvRequestFlags flags); -int coroutine_fn bdrv_co_do_pwritev(BlockDriverState *bs, +int coroutine_fn bdrv_co_pwritev(BlockDriverState *bs, int64_t offset, unsigned int bytes, QEMUIOVector *qiov, BdrvRequestFlags flags); @@ -713,6 +724,9 @@ BdrvChild *bdrv_root_attach_child(BlockDriverState *child_bs, const BdrvChildRole *child_role); void bdrv_root_unref_child(BdrvChild *child); +void bdrv_no_throttling_begin(BlockDriverState *bs); +void bdrv_no_throttling_end(BlockDriverState *bs); + void blk_dev_change_media_cb(BlockBackend *blk, bool load); bool blk_dev_has_removable_media(BlockBackend *blk); bool blk_dev_has_tray(BlockBackend *blk); diff --git a/include/block/throttle-groups.h b/include/block/throttle-groups.h index aba28f30b6..395f72d444 100644 --- a/include/block/throttle-groups.h +++ b/include/block/throttle-groups.h @@ -38,6 +38,7 @@ void throttle_group_get_config(BlockDriverState *bs, ThrottleConfig *cfg); void throttle_group_register_bs(BlockDriverState *bs, const char *groupname); void throttle_group_unregister_bs(BlockDriverState *bs); +void throttle_group_restart_bs(BlockDriverState *bs); void coroutine_fn throttle_group_co_io_limits_intercept(BlockDriverState *bs, unsigned int bytes, diff --git a/include/sysemu/block-backend.h b/include/sysemu/block-backend.h index c62b6fe96d..26736ed84e 100644 --- a/include/sysemu/block-backend.h +++ b/include/sysemu/block-backend.h @@ -1,7 +1,7 @@ /* * QEMU Block backends * - * Copyright (C) 2014 Red Hat, Inc. + * Copyright (C) 2014-2016 Red Hat, Inc. * * Authors: * Markus Armbruster <armbru@redhat.com>, @@ -90,28 +90,25 @@ void blk_attach_dev_nofail(BlockBackend *blk, void *dev); void blk_detach_dev(BlockBackend *blk, void *dev); void *blk_get_attached_dev(BlockBackend *blk); void blk_set_dev_ops(BlockBackend *blk, const BlockDevOps *ops, void *opaque); -int blk_read(BlockBackend *blk, int64_t sector_num, uint8_t *buf, - int nb_sectors); -int blk_read_unthrottled(BlockBackend *blk, int64_t sector_num, uint8_t *buf, - int nb_sectors); -int blk_write(BlockBackend *blk, int64_t sector_num, const uint8_t *buf, - int nb_sectors); -int blk_write_zeroes(BlockBackend *blk, int64_t sector_num, - int nb_sectors, BdrvRequestFlags flags); -BlockAIOCB *blk_aio_write_zeroes(BlockBackend *blk, int64_t sector_num, - int nb_sectors, BdrvRequestFlags flags, +int blk_pread_unthrottled(BlockBackend *blk, int64_t offset, uint8_t *buf, + int count); +int blk_write_zeroes(BlockBackend *blk, int64_t offset, + int count, BdrvRequestFlags flags); +BlockAIOCB *blk_aio_write_zeroes(BlockBackend *blk, int64_t offset, + int count, BdrvRequestFlags flags, BlockCompletionFunc *cb, void *opaque); int blk_pread(BlockBackend *blk, int64_t offset, void *buf, int count); -int blk_pwrite(BlockBackend *blk, int64_t offset, const void *buf, int count); +int blk_pwrite(BlockBackend *blk, int64_t offset, const void *buf, int count, + BdrvRequestFlags flags); int64_t blk_getlength(BlockBackend *blk); void blk_get_geometry(BlockBackend *blk, uint64_t *nb_sectors_ptr); int64_t blk_nb_sectors(BlockBackend *blk); -BlockAIOCB *blk_aio_readv(BlockBackend *blk, int64_t sector_num, - QEMUIOVector *iov, int nb_sectors, - BlockCompletionFunc *cb, void *opaque); -BlockAIOCB *blk_aio_writev(BlockBackend *blk, int64_t sector_num, - QEMUIOVector *iov, int nb_sectors, +BlockAIOCB *blk_aio_preadv(BlockBackend *blk, int64_t offset, + QEMUIOVector *qiov, BdrvRequestFlags flags, BlockCompletionFunc *cb, void *opaque); +BlockAIOCB *blk_aio_pwritev(BlockBackend *blk, int64_t offset, + QEMUIOVector *qiov, BdrvRequestFlags flags, + BlockCompletionFunc *cb, void *opaque); BlockAIOCB *blk_aio_flush(BlockBackend *blk, BlockCompletionFunc *cb, void *opaque); BlockAIOCB *blk_aio_discard(BlockBackend *blk, @@ -178,8 +175,8 @@ int blk_get_open_flags_from_root_state(BlockBackend *blk); void *blk_aio_get(const AIOCBInfo *aiocb_info, BlockBackend *blk, BlockCompletionFunc *cb, void *opaque); -int coroutine_fn blk_co_write_zeroes(BlockBackend *blk, int64_t sector_num, - int nb_sectors, BdrvRequestFlags flags); +int coroutine_fn blk_co_write_zeroes(BlockBackend *blk, int64_t offset, + int count, BdrvRequestFlags flags); int blk_write_compressed(BlockBackend *blk, int64_t sector_num, const uint8_t *buf, int nb_sectors); int blk_truncate(BlockBackend *blk, int64_t offset); diff --git a/include/sysemu/dma.h b/include/sysemu/dma.h index b0fbb9bb35..0f7cd4d3ce 100644 --- a/include/sysemu/dma.h +++ b/include/sysemu/dma.h @@ -197,8 +197,8 @@ void qemu_sglist_add(QEMUSGList *qsg, dma_addr_t base, dma_addr_t len); void qemu_sglist_destroy(QEMUSGList *qsg); #endif -typedef BlockAIOCB *DMAIOFunc(BlockBackend *blk, int64_t sector_num, - QEMUIOVector *iov, int nb_sectors, +typedef BlockAIOCB *DMAIOFunc(BlockBackend *blk, int64_t offset, + QEMUIOVector *iov, BdrvRequestFlags flags, BlockCompletionFunc *cb, void *opaque); BlockAIOCB *dma_blk_io(BlockBackend *blk, diff --git a/nbd/server.c b/nbd/server.c index 2184c64fef..fa862cd622 100644 --- a/nbd/server.c +++ b/nbd/server.c @@ -1115,7 +1115,7 @@ static void nbd_trip(void *opaque) TRACE("Writing to device"); ret = blk_pwrite(exp->blk, request.from + exp->dev_offset, - req->data, request.len); + req->data, request.len, 0); if (ret < 0) { LOG("writing to file failed"); reply.error = -ret; diff --git a/qapi/block-core.json b/qapi/block-core.json index 1d09079cc1..98a20d22f4 100644 --- a/qapi/block-core.json +++ b/qapi/block-core.json @@ -2556,3 +2556,35 @@ ## { 'command': 'block-set-write-threshold', 'data': { 'node-name': 'str', 'write-threshold': 'uint64' } } + +## +# @x-blockdev-change +# +# Dynamically reconfigure the block driver state graph. It can be used +# to add, remove, insert or replace a graph node. Currently only the +# Quorum driver implements this feature to add or remove its child. This +# is useful to fix a broken quorum child. +# +# If @node is specified, it will be inserted under @parent. @child +# may not be specified in this case. If both @parent and @child are +# specified but @node is not, @child will be detached from @parent. +# +# @parent: the id or name of the parent node. +# +# @child: #optional the name of a child under the given parent node. +# +# @node: #optional the name of the node that will be added. +# +# Note: this command is experimental, and its API is not stable. It +# does not support all kinds of operations, all kinds of children, nor +# all block drivers. +# +# Warning: The data in a new quorum child MUST be consistent with that of +# the rest of the array. +# +# Since: 2.7 +## +{ 'command': 'x-blockdev-change', + 'data' : { 'parent': 'str', + '*child': 'str', + '*node': 'str' } } diff --git a/qemu-doc.texi b/qemu-doc.texi index 79141d3582..f37fd3130e 100644 --- a/qemu-doc.texi +++ b/qemu-doc.texi @@ -693,6 +693,9 @@ Supported options: File name of a base image (see @option{create} subcommand). @item compat6 Create a VMDK version 6 image (instead of version 4) +@item hwversion +Specify vmdk virtual hardware version. Compat6 flag cannot be enabled +if hwversion is specified. @item subformat Specifies which VMDK subformat to use. Valid options are @code{monolithicSparse} (default), diff --git a/qemu-img.c b/qemu-img.c index 46f2a6def4..47923663be 100644 --- a/qemu-img.c +++ b/qemu-img.c @@ -1088,7 +1088,8 @@ static int check_empty_sectors(BlockBackend *blk, int64_t sect_num, uint8_t *buffer, bool quiet) { int pnum, ret = 0; - ret = blk_read(blk, sect_num, buffer, sect_count); + ret = blk_pread(blk, sect_num << BDRV_SECTOR_BITS, buffer, + sect_count << BDRV_SECTOR_BITS); if (ret < 0) { error_report("Error while reading offset %" PRId64 " of %s: %s", sectors_to_bytes(sect_num), filename, strerror(-ret)); @@ -1301,7 +1302,8 @@ static int img_compare(int argc, char **argv) nb_sectors = MIN(pnum1, pnum2); } else if (allocated1 == allocated2) { if (allocated1) { - ret = blk_read(blk1, sector_num, buf1, nb_sectors); + ret = blk_pread(blk1, sector_num << BDRV_SECTOR_BITS, buf1, + nb_sectors << BDRV_SECTOR_BITS); if (ret < 0) { error_report("Error while reading offset %" PRId64 " of %s:" " %s", sectors_to_bytes(sector_num), filename1, @@ -1309,7 +1311,8 @@ static int img_compare(int argc, char **argv) ret = 4; goto out; } - ret = blk_read(blk2, sector_num, buf2, nb_sectors); + ret = blk_pread(blk2, sector_num << BDRV_SECTOR_BITS, buf2, + nb_sectors << BDRV_SECTOR_BITS); if (ret < 0) { error_report("Error while reading offset %" PRId64 " of %s: %s", sectors_to_bytes(sector_num), @@ -1472,10 +1475,21 @@ static int convert_iteration_sectors(ImgConvertState *s, int64_t sector_num) } else if (!s->target_has_backing) { /* Without a target backing file we must copy over the contents of * the backing file as well. */ - /* TODO Check block status of the backing file chain to avoid + /* Check block status of the backing file chain to avoid * needlessly reading zeroes and limiting the iteration to the * buffer size */ - s->status = BLK_DATA; + ret = bdrv_get_block_status_above(blk_bs(s->src[s->src_cur]), NULL, + sector_num - s->src_cur_offset, + n, &n, &file); + if (ret < 0) { + return ret; + } + + if (ret & BDRV_BLOCK_ZERO) { + s->status = BLK_ZERO; + } else { + s->status = BLK_DATA; + } } else { s->status = BLK_BACKING_FILE; } @@ -1522,7 +1536,9 @@ static int convert_read(ImgConvertState *s, int64_t sector_num, int nb_sectors, bs_sectors = s->src_sectors[s->src_cur]; n = MIN(nb_sectors, bs_sectors - (sector_num - s->src_cur_offset)); - ret = blk_read(blk, sector_num - s->src_cur_offset, buf, n); + ret = blk_pread(blk, + (sector_num - s->src_cur_offset) << BDRV_SECTOR_BITS, + buf, n << BDRV_SECTOR_BITS); if (ret < 0) { return ret; } @@ -1577,7 +1593,8 @@ static int convert_write(ImgConvertState *s, int64_t sector_num, int nb_sectors, if (!s->min_sparse || is_allocated_sectors_min(buf, n, &n, s->min_sparse)) { - ret = blk_write(s->target, sector_num, buf, n); + ret = blk_pwrite(s->target, sector_num << BDRV_SECTOR_BITS, + buf, n << BDRV_SECTOR_BITS, 0); if (ret < 0) { return ret; } @@ -1589,7 +1606,8 @@ static int convert_write(ImgConvertState *s, int64_t sector_num, int nb_sectors, if (s->has_zero_init) { break; } - ret = blk_write_zeroes(s->target, sector_num, n, 0); + ret = blk_write_zeroes(s->target, sector_num << BDRV_SECTOR_BITS, + n << BDRV_SECTOR_BITS, 0); if (ret < 0) { return ret; } @@ -3023,7 +3041,8 @@ static int img_rebase(int argc, char **argv) n = old_backing_num_sectors - sector; } - ret = blk_read(blk_old_backing, sector, buf_old, n); + ret = blk_pread(blk_old_backing, sector << BDRV_SECTOR_BITS, + buf_old, n << BDRV_SECTOR_BITS); if (ret < 0) { error_report("error while reading from old backing file"); goto out; @@ -3037,7 +3056,8 @@ static int img_rebase(int argc, char **argv) n = new_backing_num_sectors - sector; } - ret = blk_read(blk_new_backing, sector, buf_new, n); + ret = blk_pread(blk_new_backing, sector << BDRV_SECTOR_BITS, + buf_new, n << BDRV_SECTOR_BITS); if (ret < 0) { error_report("error while reading from new backing file"); goto out; @@ -3053,8 +3073,10 @@ static int img_rebase(int argc, char **argv) if (compare_sectors(buf_old + written * 512, buf_new + written * 512, n - written, &pnum)) { - ret = blk_write(blk, sector + written, - buf_old + written * 512, pnum); + ret = blk_pwrite(blk, + (sector + written) << BDRV_SECTOR_BITS, + buf_old + written * 512, + pnum << BDRV_SECTOR_BITS, 0); if (ret < 0) { error_report("Error while writing to COW image: %s", strerror(-ret)); diff --git a/qemu-io-cmds.c b/qemu-io-cmds.c index e34f777118..4a00bc604d 100644 --- a/qemu-io-cmds.c +++ b/qemu-io-cmds.c @@ -1,7 +1,7 @@ /* * Command line utility to exercise the QEMU I/O path. * - * Copyright (C) 2009 Red Hat, Inc. + * Copyright (C) 2009-2016 Red Hat, Inc. * Copyright (c) 2003-2005 Silicon Graphics, Inc. * * This work is licensed under the terms of the GNU GPL, version 2 or later. @@ -345,7 +345,7 @@ static void dump_buffer(const void *buffer, int64_t offset, int64_t len) } static void print_report(const char *op, struct timeval *t, int64_t offset, - int64_t count, int64_t total, int cnt, int Cflag) + int64_t count, int64_t total, int cnt, bool Cflag) { char s1[64], s2[64], ts[64]; @@ -395,12 +395,6 @@ create_iovec(BlockBackend *blk, QEMUIOVector *qiov, char **argv, int nr_iov, goto fail; } - if (len & 0x1ff) { - printf("length argument %" PRId64 - " is not sector aligned\n", len); - goto fail; - } - sizes[i] = len; count += len; } @@ -419,40 +413,6 @@ fail: return buf; } -static int do_read(BlockBackend *blk, char *buf, int64_t offset, int64_t count, - int64_t *total) -{ - int ret; - - if (count >> 9 > INT_MAX) { - return -ERANGE; - } - - ret = blk_read(blk, offset >> 9, (uint8_t *)buf, count >> 9); - if (ret < 0) { - return ret; - } - *total = count; - return 1; -} - -static int do_write(BlockBackend *blk, char *buf, int64_t offset, int64_t count, - int64_t *total) -{ - int ret; - - if (count >> 9 > INT_MAX) { - return -ERANGE; - } - - ret = blk_write(blk, offset >> 9, (uint8_t *)buf, count >> 9); - if (ret < 0) { - return ret; - } - *total = count; - return 1; -} - static int do_pread(BlockBackend *blk, char *buf, int64_t offset, int64_t count, int64_t *total) { @@ -468,13 +428,13 @@ static int do_pread(BlockBackend *blk, char *buf, int64_t offset, } static int do_pwrite(BlockBackend *blk, char *buf, int64_t offset, - int64_t count, int64_t *total) + int64_t count, int flags, int64_t *total) { if (count > INT_MAX) { return -ERANGE; } - *total = blk_pwrite(blk, offset, (uint8_t *)buf, count); + *total = blk_pwrite(blk, offset, (uint8_t *)buf, count, flags); if (*total < 0) { return *total; } @@ -486,6 +446,7 @@ typedef struct { int64_t offset; int64_t count; int64_t *total; + int flags; int ret; bool done; } CoWriteZeroes; @@ -494,8 +455,8 @@ static void coroutine_fn co_write_zeroes_entry(void *opaque) { CoWriteZeroes *data = opaque; - data->ret = blk_co_write_zeroes(data->blk, data->offset / BDRV_SECTOR_SIZE, - data->count / BDRV_SECTOR_SIZE, 0); + data->ret = blk_co_write_zeroes(data->blk, data->offset, data->count, + data->flags); data->done = true; if (data->ret < 0) { *data->total = data->ret; @@ -506,7 +467,7 @@ static void coroutine_fn co_write_zeroes_entry(void *opaque) } static int do_co_write_zeroes(BlockBackend *blk, int64_t offset, int64_t count, - int64_t *total) + int flags, int64_t *total) { Coroutine *co; CoWriteZeroes data = { @@ -514,6 +475,7 @@ static int do_co_write_zeroes(BlockBackend *blk, int64_t offset, int64_t count, .offset = offset, .count = count, .total = total, + .flags = flags, .done = false, }; @@ -589,8 +551,7 @@ static int do_aio_readv(BlockBackend *blk, QEMUIOVector *qiov, { int async_ret = NOT_DONE; - blk_aio_readv(blk, offset >> 9, qiov, qiov->size >> 9, - aio_rw_done, &async_ret); + blk_aio_preadv(blk, offset, qiov, 0, aio_rw_done, &async_ret); while (async_ret == NOT_DONE) { main_loop_wait(false); } @@ -600,12 +561,11 @@ static int do_aio_readv(BlockBackend *blk, QEMUIOVector *qiov, } static int do_aio_writev(BlockBackend *blk, QEMUIOVector *qiov, - int64_t offset, int *total) + int64_t offset, int flags, int *total) { int async_ret = NOT_DONE; - blk_aio_writev(blk, offset >> 9, qiov, qiov->size >> 9, - aio_rw_done, &async_ret); + blk_aio_pwritev(blk, offset, qiov, flags, aio_rw_done, &async_ret); while (async_ret == NOT_DONE) { main_loop_wait(false); } @@ -671,7 +631,7 @@ static void read_help(void) " -b, -- read from the VM state rather than the virtual disk\n" " -C, -- report statistics in a machine parsable format\n" " -l, -- length for pattern verification (only with -P)\n" -" -p, -- use blk_pread to read the file\n" +" -p, -- ignored for backwards compatibility\n" " -P, -- use a pattern to verify read data\n" " -q, -- quiet mode, do not show I/O statistics\n" " -s, -- start offset for pattern verification (only with -P)\n" @@ -687,7 +647,7 @@ static const cmdinfo_t read_cmd = { .cfunc = read_f, .argmin = 2, .argmax = -1, - .args = "[-abCpqv] [-P pattern [-s off] [-l len]] off len", + .args = "[-abCqv] [-P pattern [-s off] [-l len]] off len", .oneline = "reads a number of bytes at a specified offset", .help = read_help, }; @@ -695,8 +655,8 @@ static const cmdinfo_t read_cmd = { static int read_f(BlockBackend *blk, int argc, char **argv) { struct timeval t1, t2; - int Cflag = 0, pflag = 0, qflag = 0, vflag = 0; - int Pflag = 0, sflag = 0, lflag = 0, bflag = 0; + bool Cflag = false, qflag = false, vflag = false; + bool Pflag = false, sflag = false, lflag = false, bflag = false; int c, cnt; char *buf; int64_t offset; @@ -709,13 +669,13 @@ static int read_f(BlockBackend *blk, int argc, char **argv) while ((c = getopt(argc, argv, "bCl:pP:qs:v")) != -1) { switch (c) { case 'b': - bflag = 1; + bflag = true; break; case 'C': - Cflag = 1; + Cflag = true; break; case 'l': - lflag = 1; + lflag = true; pattern_count = cvtnum(optarg); if (pattern_count < 0) { print_cvtnum_err(pattern_count, optarg); @@ -723,20 +683,20 @@ static int read_f(BlockBackend *blk, int argc, char **argv) } break; case 'p': - pflag = 1; + /* Ignored for backwards compatibility */ break; case 'P': - Pflag = 1; + Pflag = true; pattern = parse_pattern(optarg); if (pattern < 0) { return 0; } break; case 'q': - qflag = 1; + qflag = true; break; case 's': - sflag = 1; + sflag = true; pattern_offset = cvtnum(optarg); if (pattern_offset < 0) { print_cvtnum_err(pattern_offset, optarg); @@ -744,7 +704,7 @@ static int read_f(BlockBackend *blk, int argc, char **argv) } break; case 'v': - vflag = 1; + vflag = true; break; default: return qemuio_command_usage(&read_cmd); @@ -755,11 +715,6 @@ static int read_f(BlockBackend *blk, int argc, char **argv) return qemuio_command_usage(&read_cmd); } - if (bflag && pflag) { - printf("-b and -p cannot be specified at the same time\n"); - return 0; - } - offset = cvtnum(argv[optind]); if (offset < 0) { print_cvtnum_err(offset, argv[optind]); @@ -790,7 +745,7 @@ static int read_f(BlockBackend *blk, int argc, char **argv) return 0; } - if (!pflag) { + if (bflag) { if (offset & 0x1ff) { printf("offset %" PRId64 " is not sector aligned\n", offset); @@ -806,12 +761,10 @@ static int read_f(BlockBackend *blk, int argc, char **argv) buf = qemu_io_alloc(blk, count, 0xab); gettimeofday(&t1, NULL); - if (pflag) { - cnt = do_pread(blk, buf, offset, count, &total); - } else if (bflag) { + if (bflag) { cnt = do_load_vmstate(blk, buf, offset, count, &total); } else { - cnt = do_read(blk, buf, offset, count, &total); + cnt = do_pread(blk, buf, offset, count, &total); } gettimeofday(&t2, NULL); @@ -875,7 +828,7 @@ static const cmdinfo_t readv_cmd = { .cfunc = readv_f, .argmin = 2, .argmax = -1, - .args = "[-Cqv] [-P pattern ] off len [len..]", + .args = "[-Cqv] [-P pattern] off len [len..]", .oneline = "reads a number of bytes at a specified offset", .help = readv_help, }; @@ -883,7 +836,7 @@ static const cmdinfo_t readv_cmd = { static int readv_f(BlockBackend *blk, int argc, char **argv) { struct timeval t1, t2; - int Cflag = 0, qflag = 0, vflag = 0; + bool Cflag = false, qflag = false, vflag = false; int c, cnt; char *buf; int64_t offset; @@ -892,25 +845,25 @@ static int readv_f(BlockBackend *blk, int argc, char **argv) int nr_iov; QEMUIOVector qiov; int pattern = 0; - int Pflag = 0; + bool Pflag = false; while ((c = getopt(argc, argv, "CP:qv")) != -1) { switch (c) { case 'C': - Cflag = 1; + Cflag = true; break; case 'P': - Pflag = 1; + Pflag = true; pattern = parse_pattern(optarg); if (pattern < 0) { return 0; } break; case 'q': - qflag = 1; + qflag = true; break; case 'v': - vflag = 1; + vflag = true; break; default: return qemuio_command_usage(&readv_cmd); @@ -929,12 +882,6 @@ static int readv_f(BlockBackend *blk, int argc, char **argv) } optind++; - if (offset & 0x1ff) { - printf("offset %" PRId64 " is not sector aligned\n", - offset); - return 0; - } - nr_iov = argc - optind; buf = create_iovec(blk, &qiov, &argv[optind], nr_iov, 0xab); if (buf == NULL) { @@ -991,10 +938,12 @@ static void write_help(void) " filled with a set pattern (0xcdcdcdcd).\n" " -b, -- write to the VM state rather than the virtual disk\n" " -c, -- write compressed data with blk_write_compressed\n" -" -p, -- use blk_pwrite to write the file\n" +" -f, -- use Force Unit Access semantics\n" +" -p, -- ignored for backwards compatibility\n" " -P, -- use different pattern to fill file\n" " -C, -- report statistics in a machine parsable format\n" " -q, -- quiet mode, do not show I/O statistics\n" +" -u, -- with -z, allow unmapping\n" " -z, -- write zeroes using blk_co_write_zeroes\n" "\n"); } @@ -1007,7 +956,7 @@ static const cmdinfo_t write_cmd = { .cfunc = write_f, .argmin = 2, .argmax = -1, - .args = "[-bcCpqz] [-P pattern ] off len", + .args = "[-bcCfquz] [-P pattern] off len", .oneline = "writes a number of bytes at a specified offset", .help = write_help, }; @@ -1015,8 +964,9 @@ static const cmdinfo_t write_cmd = { static int write_f(BlockBackend *blk, int argc, char **argv) { struct timeval t1, t2; - int Cflag = 0, pflag = 0, qflag = 0, bflag = 0, Pflag = 0, zflag = 0; - int cflag = 0; + bool Cflag = false, qflag = false, bflag = false; + bool Pflag = false, zflag = false, cflag = false; + int flags = 0; int c, cnt; char *buf = NULL; int64_t offset; @@ -1025,32 +975,38 @@ static int write_f(BlockBackend *blk, int argc, char **argv) int64_t total = 0; int pattern = 0xcd; - while ((c = getopt(argc, argv, "bcCpP:qz")) != -1) { + while ((c = getopt(argc, argv, "bcCfpP:quz")) != -1) { switch (c) { case 'b': - bflag = 1; + bflag = true; break; case 'c': - cflag = 1; + cflag = true; break; case 'C': - Cflag = 1; + Cflag = true; + break; + case 'f': + flags |= BDRV_REQ_FUA; break; case 'p': - pflag = 1; + /* Ignored for backwards compatibility */ break; case 'P': - Pflag = 1; + Pflag = true; pattern = parse_pattern(optarg); if (pattern < 0) { return 0; } break; case 'q': - qflag = 1; + qflag = true; + break; + case 'u': + flags |= BDRV_REQ_MAY_UNMAP; break; case 'z': - zflag = 1; + zflag = true; break; default: return qemuio_command_usage(&write_cmd); @@ -1061,8 +1017,18 @@ static int write_f(BlockBackend *blk, int argc, char **argv) return qemuio_command_usage(&write_cmd); } - if (bflag + pflag + zflag > 1) { - printf("-b, -p, or -z cannot be specified at the same time\n"); + if (bflag && zflag) { + printf("-b and -z cannot be specified at the same time\n"); + return 0; + } + + if ((flags & BDRV_REQ_FUA) && (bflag || cflag)) { + printf("-f and -b or -c cannot be specified at the same time\n"); + return 0; + } + + if ((flags & BDRV_REQ_MAY_UNMAP) && !zflag) { + printf("-u requires -z to be specified\n"); return 0; } @@ -1088,7 +1054,7 @@ static int write_f(BlockBackend *blk, int argc, char **argv) return 0; } - if (!pflag) { + if (bflag || cflag) { if (offset & 0x1ff) { printf("offset %" PRId64 " is not sector aligned\n", offset); @@ -1107,16 +1073,14 @@ static int write_f(BlockBackend *blk, int argc, char **argv) } gettimeofday(&t1, NULL); - if (pflag) { - cnt = do_pwrite(blk, buf, offset, count, &total); - } else if (bflag) { + if (bflag) { cnt = do_save_vmstate(blk, buf, offset, count, &total); } else if (zflag) { - cnt = do_co_write_zeroes(blk, offset, count, &total); + cnt = do_co_write_zeroes(blk, offset, count, flags, &total); } else if (cflag) { cnt = do_write_compressed(blk, buf, offset, count, &total); } else { - cnt = do_write(blk, buf, offset, count, &total); + cnt = do_pwrite(blk, buf, offset, count, flags, &total); } gettimeofday(&t2, NULL); @@ -1155,6 +1119,7 @@ writev_help(void) " filled with a set pattern (0xcdcdcdcd).\n" " -P, -- use different pattern to fill file\n" " -C, -- report statistics in a machine parsable format\n" +" -f, -- use Force Unit Access semantics\n" " -q, -- quiet mode, do not show I/O statistics\n" "\n"); } @@ -1166,7 +1131,7 @@ static const cmdinfo_t writev_cmd = { .cfunc = writev_f, .argmin = 2, .argmax = -1, - .args = "[-Cq] [-P pattern ] off len [len..]", + .args = "[-Cfq] [-P pattern] off len [len..]", .oneline = "writes a number of bytes at a specified offset", .help = writev_help, }; @@ -1174,7 +1139,8 @@ static const cmdinfo_t writev_cmd = { static int writev_f(BlockBackend *blk, int argc, char **argv) { struct timeval t1, t2; - int Cflag = 0, qflag = 0; + bool Cflag = false, qflag = false; + int flags = 0; int c, cnt; char *buf; int64_t offset; @@ -1187,10 +1153,13 @@ static int writev_f(BlockBackend *blk, int argc, char **argv) while ((c = getopt(argc, argv, "CqP:")) != -1) { switch (c) { case 'C': - Cflag = 1; + Cflag = true; + break; + case 'f': + flags |= BDRV_REQ_FUA; break; case 'q': - qflag = 1; + qflag = true; break; case 'P': pattern = parse_pattern(optarg); @@ -1214,12 +1183,6 @@ static int writev_f(BlockBackend *blk, int argc, char **argv) } optind++; - if (offset & 0x1ff) { - printf("offset %" PRId64 " is not sector aligned\n", - offset); - return 0; - } - nr_iov = argc - optind; buf = create_iovec(blk, &qiov, &argv[optind], nr_iov, pattern); if (buf == NULL) { @@ -1227,7 +1190,7 @@ static int writev_f(BlockBackend *blk, int argc, char **argv) } gettimeofday(&t1, NULL); - cnt = do_aio_writev(blk, &qiov, offset, &total); + cnt = do_aio_writev(blk, &qiov, offset, flags, &total); gettimeofday(&t2, NULL); if (cnt < 0) { @@ -1283,7 +1246,7 @@ static const cmdinfo_t multiwrite_cmd = { static int multiwrite_f(BlockBackend *blk, int argc, char **argv) { struct timeval t1, t2; - int Cflag = 0, qflag = 0; + bool Cflag = false, qflag = false; int c, cnt; char **buf; int64_t offset, first_offset = 0; @@ -1299,10 +1262,10 @@ static int multiwrite_f(BlockBackend *blk, int argc, char **argv) while ((c = getopt(argc, argv, "CqP:")) != -1) { switch (c) { case 'C': - Cflag = 1; + Cflag = true; break; case 'q': - qflag = 1; + qflag = true; break; case 'P': pattern = parse_pattern(optarg); @@ -1412,11 +1375,11 @@ struct aio_ctx { QEMUIOVector qiov; int64_t offset; char *buf; - int qflag; - int vflag; - int Cflag; - int Pflag; - int zflag; + bool qflag; + bool vflag; + bool Cflag; + bool Pflag; + bool zflag; BlockAcctCookie acct; int pattern; struct timeval t1; @@ -1525,7 +1488,7 @@ static const cmdinfo_t aio_read_cmd = { .cfunc = aio_read_f, .argmin = 2, .argmax = -1, - .args = "[-Cqv] [-P pattern ] off len [len..]", + .args = "[-Cqv] [-P pattern] off len [len..]", .oneline = "asynchronously reads a number of bytes", .help = aio_read_help, }; @@ -1539,10 +1502,10 @@ static int aio_read_f(BlockBackend *blk, int argc, char **argv) while ((c = getopt(argc, argv, "CP:qv")) != -1) { switch (c) { case 'C': - ctx->Cflag = 1; + ctx->Cflag = true; break; case 'P': - ctx->Pflag = 1; + ctx->Pflag = true; ctx->pattern = parse_pattern(optarg); if (ctx->pattern < 0) { g_free(ctx); @@ -1550,10 +1513,10 @@ static int aio_read_f(BlockBackend *blk, int argc, char **argv) } break; case 'q': - ctx->qflag = 1; + ctx->qflag = true; break; case 'v': - ctx->vflag = 1; + ctx->vflag = true; break; default: g_free(ctx); @@ -1574,14 +1537,6 @@ static int aio_read_f(BlockBackend *blk, int argc, char **argv) } optind++; - if (ctx->offset & 0x1ff) { - printf("offset %" PRId64 " is not sector aligned\n", - ctx->offset); - block_acct_invalid(blk_get_stats(blk), BLOCK_ACCT_READ); - g_free(ctx); - return 0; - } - nr_iov = argc - optind; ctx->buf = create_iovec(blk, &ctx->qiov, &argv[optind], nr_iov, 0xab); if (ctx->buf == NULL) { @@ -1593,8 +1548,7 @@ static int aio_read_f(BlockBackend *blk, int argc, char **argv) gettimeofday(&ctx->t1, NULL); block_acct_start(blk_get_stats(blk), &ctx->acct, ctx->qiov.size, BLOCK_ACCT_READ); - blk_aio_readv(blk, ctx->offset >> 9, &ctx->qiov, - ctx->qiov.size >> 9, aio_read_done, ctx); + blk_aio_preadv(blk, ctx->offset, &ctx->qiov, 0, aio_read_done, ctx); return 0; } @@ -1614,7 +1568,9 @@ static void aio_write_help(void) " used to ensure all outstanding aio requests have been completed.\n" " -P, -- use different pattern to fill file\n" " -C, -- report statistics in a machine parsable format\n" +" -f, -- use Force Unit Access semantics\n" " -q, -- quiet mode, do not show I/O statistics\n" +" -u, -- with -z, allow unmapping\n" " -z, -- write zeroes using blk_aio_write_zeroes\n" "\n"); } @@ -1626,7 +1582,7 @@ static const cmdinfo_t aio_write_cmd = { .cfunc = aio_write_f, .argmin = 2, .argmax = -1, - .args = "[-Cqz] [-P pattern ] off len [len..]", + .args = "[-Cfquz] [-P pattern] off len [len..]", .oneline = "asynchronously writes a number of bytes", .help = aio_write_help, }; @@ -1636,15 +1592,22 @@ static int aio_write_f(BlockBackend *blk, int argc, char **argv) int nr_iov, c; int pattern = 0xcd; struct aio_ctx *ctx = g_new0(struct aio_ctx, 1); + int flags = 0; ctx->blk = blk; - while ((c = getopt(argc, argv, "CqP:z")) != -1) { + while ((c = getopt(argc, argv, "CfqP:z")) != -1) { switch (c) { case 'C': - ctx->Cflag = 1; + ctx->Cflag = true; + break; + case 'f': + flags |= BDRV_REQ_FUA; break; case 'q': - ctx->qflag = 1; + ctx->qflag = true; + break; + case 'u': + flags |= BDRV_REQ_MAY_UNMAP; break; case 'P': pattern = parse_pattern(optarg); @@ -1654,7 +1617,7 @@ static int aio_write_f(BlockBackend *blk, int argc, char **argv) } break; case 'z': - ctx->zflag = 1; + ctx->zflag = true; break; default: g_free(ctx); @@ -1673,6 +1636,11 @@ static int aio_write_f(BlockBackend *blk, int argc, char **argv) return 0; } + if ((flags & BDRV_REQ_MAY_UNMAP) && !ctx->zflag) { + printf("-u requires -z to be specified\n"); + return 0; + } + if (ctx->zflag && ctx->Pflag) { printf("-z and -P cannot be specified at the same time\n"); g_free(ctx); @@ -1687,24 +1655,17 @@ static int aio_write_f(BlockBackend *blk, int argc, char **argv) } optind++; - if (ctx->offset & 0x1ff) { - printf("offset %" PRId64 " is not sector aligned\n", - ctx->offset); - block_acct_invalid(blk_get_stats(blk), BLOCK_ACCT_WRITE); - g_free(ctx); - return 0; - } - if (ctx->zflag) { int64_t count = cvtnum(argv[optind]); if (count < 0) { print_cvtnum_err(count, argv[optind]); + g_free(ctx); return 0; } ctx->qiov.size = count; - blk_aio_write_zeroes(blk, ctx->offset >> 9, count >> 9, 0, - aio_write_done, ctx); + blk_aio_write_zeroes(blk, ctx->offset, count, flags, aio_write_done, + ctx); } else { nr_iov = argc - optind; ctx->buf = create_iovec(blk, &ctx->qiov, &argv[optind], nr_iov, @@ -1719,8 +1680,8 @@ static int aio_write_f(BlockBackend *blk, int argc, char **argv) block_acct_start(blk_get_stats(blk), &ctx->acct, ctx->qiov.size, BLOCK_ACCT_WRITE); - blk_aio_writev(blk, ctx->offset >> 9, &ctx->qiov, - ctx->qiov.size >> 9, aio_write_done, ctx); + blk_aio_pwritev(blk, ctx->offset, &ctx->qiov, flags, aio_write_done, + ctx); } return 0; } @@ -1884,17 +1845,17 @@ static const cmdinfo_t discard_cmd = { static int discard_f(BlockBackend *blk, int argc, char **argv) { struct timeval t1, t2; - int Cflag = 0, qflag = 0; + bool Cflag = false, qflag = false; int c, ret; int64_t offset, count; while ((c = getopt(argc, argv, "Cq")) != -1) { switch (c) { case 'C': - Cflag = 1; + Cflag = true; break; case 'q': - qflag = 1; + qflag = true; break; default: return qemuio_command_usage(&discard_cmd); @@ -101,12 +101,15 @@ static void open_help(void) " opens a new file in the requested mode\n" "\n" " Example:\n" -" 'open -Cn /tmp/data' - creates/opens data file read-write and uncached\n" +" 'open -n -o driver=raw /tmp/data' - opens raw data file read-write, uncached\n" "\n" " Opens a file for subsequent use by all of the other qemu-io commands.\n" " -r, -- open file read-only\n" " -s, -- use snapshot file\n" -" -n, -- disable host cache\n" +" -n, -- disable host cache, short for -t none\n" +" -k, -- use kernel AIO implementation (on Linux only)\n" +" -t, -- use the given cache mode for the image\n" +" -d, -- use the given discard mode for the image\n" " -o, -- options to be given to the block driver" "\n"); } @@ -120,7 +123,7 @@ static const cmdinfo_t open_cmd = { .argmin = 1, .argmax = -1, .flags = CMD_NOFILE_OK, - .args = "[-Crsn] [-o options] [path]", + .args = "[-rsnk] [-t cache] [-d discard] [-o options] [path]", .oneline = "open the file specified by path", .help = open_help, }; @@ -137,14 +140,14 @@ static QemuOptsList empty_opts = { static int open_f(BlockBackend *blk, int argc, char **argv) { - int flags = 0; + int flags = BDRV_O_UNMAP; int readonly = 0; bool writethrough = true; int c; QemuOpts *qopts; QDict *opts; - while ((c = getopt(argc, argv, "snrgo:")) != -1) { + while ((c = getopt(argc, argv, "snro:kt:d:")) != -1) { switch (c) { case 's': flags |= BDRV_O_SNAPSHOT; @@ -156,9 +159,27 @@ static int open_f(BlockBackend *blk, int argc, char **argv) case 'r': readonly = 1; break; + case 'k': + flags |= BDRV_O_NATIVE_AIO; + break; + case 't': + if (bdrv_parse_cache_mode(optarg, &flags, &writethrough) < 0) { + error_report("Invalid cache option: %s", optarg); + qemu_opts_reset(&empty_opts); + return 0; + } + break; + case 'd': + if (bdrv_parse_discard_flags(optarg, &flags) < 0) { + error_report("Invalid discard option: %s", optarg); + qemu_opts_reset(&empty_opts); + return 0; + } + break; case 'o': if (imageOpts) { printf("--image-opts and 'open -o' are mutually exclusive\n"); + qemu_opts_reset(&empty_opts); return 0; } if (!qemu_opts_parse_noisily(&empty_opts, optarg, false)) { @@ -216,20 +237,22 @@ static const cmdinfo_t quit_cmd = { static void usage(const char *name) { printf( -"Usage: %s [-h] [-V] [-rsnm] [-f FMT] [-c STRING] ... [file]\n" +"Usage: %s [OPTIONS]... [-c STRING]... [file]\n" "QEMU Disk exerciser\n" "\n" " --object OBJECTDEF define an object such as 'secret' for\n" " passwords and/or encryption keys\n" +" --image-opts treat file as option string\n" " -c, --cmd STRING execute command with its arguments\n" " from the given string\n" " -f, --format FMT specifies the block driver to use\n" " -r, --read-only export read-only\n" " -s, --snapshot use snapshot file\n" -" -n, --nocache disable host cache\n" +" -n, --nocache disable host cache, short for -t none\n" " -m, --misalign misalign allocations for O_DIRECT\n" " -k, --native-aio use kernel AIO implementation (on Linux only)\n" " -t, --cache=MODE use the given cache mode for the image\n" +" -d, --discard=MODE use the given discard mode for the image\n" " -T, --trace FILE enable trace events listed in the given file\n" " -h, --help display this help and exit\n" " -V, --version output version information and exit\n" @@ -410,11 +433,10 @@ static QemuOptsList file_opts = { int main(int argc, char **argv) { int readonly = 0; - const char *sopt = "hVc:d:f:rsnmgkt:T:"; + const char *sopt = "hVc:d:f:rsnmkt:T:"; const struct option lopt[] = { { "help", no_argument, NULL, 'h' }, { "version", no_argument, NULL, 'V' }, - { "offset", required_argument, NULL, 'o' }, { "cmd", required_argument, NULL, 'c' }, { "format", required_argument, NULL, 'f' }, { "read-only", no_argument, NULL, 'r' }, diff --git a/qemu-nbd.c b/qemu-nbd.c index c55b40ffc8..3e541131f4 100644 --- a/qemu-nbd.c +++ b/qemu-nbd.c @@ -46,6 +46,8 @@ #define QEMU_NBD_OPT_TLSCREDS 261 #define QEMU_NBD_OPT_IMAGE_OPTS 262 +#define MBR_SIZE 512 + static NBDExport *exp; static bool newproto; static int verbose; @@ -159,12 +161,13 @@ static int find_partition(BlockBackend *blk, int partition, off_t *offset, off_t *size) { struct partition_record mbr[4]; - uint8_t data[512]; + uint8_t data[MBR_SIZE]; int i; int ext_partnum = 4; int ret; - if ((ret = blk_read(blk, 0, data, 1)) < 0) { + ret = blk_pread(blk, 0, data, sizeof(data)); + if (ret < 0) { error_report("error while reading: %s", strerror(-ret)); exit(EXIT_FAILURE); } @@ -182,10 +185,12 @@ static int find_partition(BlockBackend *blk, int partition, if (mbr[i].system == 0xF || mbr[i].system == 0x5) { struct partition_record ext[4]; - uint8_t data1[512]; + uint8_t data1[MBR_SIZE]; int j; - if ((ret = blk_read(blk, mbr[i].start_sector_abs, data1, 1)) < 0) { + ret = blk_pread(blk, mbr[i].start_sector_abs * MBR_SIZE, + data1, sizeof(data1)); + if (ret < 0) { error_report("error while reading: %s", strerror(-ret)); exit(EXIT_FAILURE); } diff --git a/qmp-commands.hx b/qmp-commands.hx index de896a5a31..94847e5b48 100644 --- a/qmp-commands.hx +++ b/qmp-commands.hx @@ -4398,6 +4398,59 @@ Example: EQMP { + .name = "x-blockdev-change", + .args_type = "parent:B,child:B?,node:B?", + .mhandler.cmd_new = qmp_marshal_x_blockdev_change, + }, + +SQMP +x-blockdev-change +----------------- + +Dynamically reconfigure the block driver state graph. It can be used +to add, remove, insert or replace a graph node. Currently only the +Quorum driver implements this feature to add or remove its child. This +is useful to fix a broken quorum child. + +If @node is specified, it will be inserted under @parent. @child +may not be specified in this case. If both @parent and @child are +specified but @node is not, @child will be detached from @parent. + +Arguments: +- "parent": the id or name of the parent node (json-string) +- "child": the name of a child under the given parent node (json-string, optional) +- "node": the name of the node that will be added (json-string, optional) + +Note: this command is experimental, and not a stable API. It doesn't +support all kinds of operations, all kinds of children, nor all block +drivers. + +Warning: The data in a new quorum child MUST be consistent with that of +the rest of the array. + +Example: + +Add a new node to a quorum +-> { "execute": "blockdev-add", + "arguments": { "options": { "driver": "raw", + "node-name": "new_node", + "file": { "driver": "file", + "filename": "test.raw" } } } } +<- { "return": {} } +-> { "execute": "x-blockdev-change", + "arguments": { "parent": "disk1", + "node": "new_node" } } +<- { "return": {} } + +Delete a quorum's node +-> { "execute": "x-blockdev-change", + "arguments": { "parent": "disk1", + "child": "children.1" } } +<- { "return": {} } + +EQMP + + { .name = "query-named-block-nodes", .args_type = "", .mhandler.cmd_new = qmp_marshal_query_named_block_nodes, diff --git a/tests/qemu-iotests/004 b/tests/qemu-iotests/004 index 67e1beb209..6f2aa3d9a2 100755 --- a/tests/qemu-iotests/004 +++ b/tests/qemu-iotests/004 @@ -37,7 +37,7 @@ trap "_cleanup; exit \$status" 0 1 2 3 15 . ./common.rc . ./common.filter -_supported_fmt raw qcow qcow2 qed vdi vmdk vhdx +_supported_fmt raw qcow qcow2 qed vdi vmdk vhdx luks _supported_proto generic _supported_os Linux diff --git a/tests/qemu-iotests/012 b/tests/qemu-iotests/012 index d1d3f22093..01a770d59c 100755 --- a/tests/qemu-iotests/012 +++ b/tests/qemu-iotests/012 @@ -43,13 +43,16 @@ _supported_fmt generic _supported_proto file _supported_os Linux +# Remove once all tests are fixed to use TEST_IMG_FILE +# correctly and common.rc sets it unconditionally +test -z "$TEST_IMG_FILE" && TEST_IMG_FILE=$TEST_IMG size=128M _make_test_img $size echo echo "== mark image read-only" -chmod a-w "$TEST_IMG" +chmod a-w "$TEST_IMG_FILE" echo echo "== read from read-only image" diff --git a/tests/qemu-iotests/023.out b/tests/qemu-iotests/023.out index d4e9be25e1..664871b30a 100644 --- a/tests/qemu-iotests/023.out +++ b/tests/qemu-iotests/023.out @@ -225,42 +225,78 @@ wrote 512/512 bytes at offset 108544 wrote 512/512 bytes at offset 109568 512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) === IO: pattern 216 -offset 110848 is not sector aligned -offset 111872 is not sector aligned -offset 112896 is not sector aligned -offset 113920 is not sector aligned -offset 114944 is not sector aligned -offset 115968 is not sector aligned -offset 116992 is not sector aligned -offset 118016 is not sector aligned -offset 119040 is not sector aligned -offset 120064 is not sector aligned -offset 121088 is not sector aligned -offset 122112 is not sector aligned -offset 123136 is not sector aligned -offset 124160 is not sector aligned -offset 125184 is not sector aligned -offset 126208 is not sector aligned -offset 127232 is not sector aligned -offset 128256 is not sector aligned -offset 129280 is not sector aligned -offset 130304 is not sector aligned -offset 131328 is not sector aligned -offset 132352 is not sector aligned -offset 133376 is not sector aligned -offset 134400 is not sector aligned -offset 135424 is not sector aligned -offset 136448 is not sector aligned -offset 137472 is not sector aligned -offset 138496 is not sector aligned -offset 139520 is not sector aligned -offset 140544 is not sector aligned -offset 141568 is not sector aligned -offset 142592 is not sector aligned -offset 143616 is not sector aligned -offset 144640 is not sector aligned -offset 145664 is not sector aligned -offset 146688 is not sector aligned +wrote 512/512 bytes at offset 110848 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +wrote 512/512 bytes at offset 111872 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +wrote 512/512 bytes at offset 112896 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +wrote 512/512 bytes at offset 113920 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +wrote 512/512 bytes at offset 114944 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +wrote 512/512 bytes at offset 115968 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +wrote 512/512 bytes at offset 116992 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +wrote 512/512 bytes at offset 118016 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +wrote 512/512 bytes at offset 119040 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +wrote 512/512 bytes at offset 120064 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +wrote 512/512 bytes at offset 121088 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +wrote 512/512 bytes at offset 122112 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +wrote 512/512 bytes at offset 123136 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +wrote 512/512 bytes at offset 124160 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +wrote 512/512 bytes at offset 125184 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +wrote 512/512 bytes at offset 126208 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +wrote 512/512 bytes at offset 127232 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +wrote 512/512 bytes at offset 128256 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +wrote 512/512 bytes at offset 129280 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +wrote 512/512 bytes at offset 130304 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +wrote 512/512 bytes at offset 131328 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +wrote 512/512 bytes at offset 132352 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +wrote 512/512 bytes at offset 133376 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +wrote 512/512 bytes at offset 134400 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +wrote 512/512 bytes at offset 135424 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +wrote 512/512 bytes at offset 136448 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +wrote 512/512 bytes at offset 137472 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +wrote 512/512 bytes at offset 138496 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +wrote 512/512 bytes at offset 139520 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +wrote 512/512 bytes at offset 140544 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +wrote 512/512 bytes at offset 141568 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +wrote 512/512 bytes at offset 142592 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +wrote 512/512 bytes at offset 143616 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +wrote 512/512 bytes at offset 144640 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +wrote 512/512 bytes at offset 145664 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +wrote 512/512 bytes at offset 146688 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) === IO: pattern 33 wrote 2048/2048 bytes at offset 147968 2 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) @@ -507,42 +543,78 @@ read 512/512 bytes at offset 108544 read 512/512 bytes at offset 109568 512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) === IO: pattern 216 -offset 110848 is not sector aligned -offset 111872 is not sector aligned -offset 112896 is not sector aligned -offset 113920 is not sector aligned -offset 114944 is not sector aligned -offset 115968 is not sector aligned -offset 116992 is not sector aligned -offset 118016 is not sector aligned -offset 119040 is not sector aligned -offset 120064 is not sector aligned -offset 121088 is not sector aligned -offset 122112 is not sector aligned -offset 123136 is not sector aligned -offset 124160 is not sector aligned -offset 125184 is not sector aligned -offset 126208 is not sector aligned -offset 127232 is not sector aligned -offset 128256 is not sector aligned -offset 129280 is not sector aligned -offset 130304 is not sector aligned -offset 131328 is not sector aligned -offset 132352 is not sector aligned -offset 133376 is not sector aligned -offset 134400 is not sector aligned -offset 135424 is not sector aligned -offset 136448 is not sector aligned -offset 137472 is not sector aligned -offset 138496 is not sector aligned -offset 139520 is not sector aligned -offset 140544 is not sector aligned -offset 141568 is not sector aligned -offset 142592 is not sector aligned -offset 143616 is not sector aligned -offset 144640 is not sector aligned -offset 145664 is not sector aligned -offset 146688 is not sector aligned +read 512/512 bytes at offset 110848 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 111872 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 112896 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 113920 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 114944 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 115968 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 116992 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 118016 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 119040 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 120064 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 121088 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 122112 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 123136 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 124160 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 125184 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 126208 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 127232 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 128256 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 129280 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 130304 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 131328 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 132352 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 133376 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 134400 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 135424 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 136448 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 137472 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 138496 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 139520 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 140544 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 141568 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 142592 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 143616 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 144640 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 145664 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 146688 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) === IO: pattern 33 read 2048/2048 bytes at offset 147968 2 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) @@ -789,42 +861,78 @@ wrote 512/512 bytes at offset 108544 wrote 512/512 bytes at offset 109568 512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) === IO: pattern 216 -offset 110848 is not sector aligned -offset 111872 is not sector aligned -offset 112896 is not sector aligned -offset 113920 is not sector aligned -offset 114944 is not sector aligned -offset 115968 is not sector aligned -offset 116992 is not sector aligned -offset 118016 is not sector aligned -offset 119040 is not sector aligned -offset 120064 is not sector aligned -offset 121088 is not sector aligned -offset 122112 is not sector aligned -offset 123136 is not sector aligned -offset 124160 is not sector aligned -offset 125184 is not sector aligned -offset 126208 is not sector aligned -offset 127232 is not sector aligned -offset 128256 is not sector aligned -offset 129280 is not sector aligned -offset 130304 is not sector aligned -offset 131328 is not sector aligned -offset 132352 is not sector aligned -offset 133376 is not sector aligned -offset 134400 is not sector aligned -offset 135424 is not sector aligned -offset 136448 is not sector aligned -offset 137472 is not sector aligned -offset 138496 is not sector aligned -offset 139520 is not sector aligned -offset 140544 is not sector aligned -offset 141568 is not sector aligned -offset 142592 is not sector aligned -offset 143616 is not sector aligned -offset 144640 is not sector aligned -offset 145664 is not sector aligned -offset 146688 is not sector aligned +wrote 512/512 bytes at offset 110848 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +wrote 512/512 bytes at offset 111872 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +wrote 512/512 bytes at offset 112896 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +wrote 512/512 bytes at offset 113920 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +wrote 512/512 bytes at offset 114944 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +wrote 512/512 bytes at offset 115968 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +wrote 512/512 bytes at offset 116992 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +wrote 512/512 bytes at offset 118016 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +wrote 512/512 bytes at offset 119040 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +wrote 512/512 bytes at offset 120064 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +wrote 512/512 bytes at offset 121088 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +wrote 512/512 bytes at offset 122112 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +wrote 512/512 bytes at offset 123136 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +wrote 512/512 bytes at offset 124160 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +wrote 512/512 bytes at offset 125184 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +wrote 512/512 bytes at offset 126208 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +wrote 512/512 bytes at offset 127232 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +wrote 512/512 bytes at offset 128256 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +wrote 512/512 bytes at offset 129280 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +wrote 512/512 bytes at offset 130304 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +wrote 512/512 bytes at offset 131328 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +wrote 512/512 bytes at offset 132352 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +wrote 512/512 bytes at offset 133376 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +wrote 512/512 bytes at offset 134400 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +wrote 512/512 bytes at offset 135424 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +wrote 512/512 bytes at offset 136448 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +wrote 512/512 bytes at offset 137472 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +wrote 512/512 bytes at offset 138496 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +wrote 512/512 bytes at offset 139520 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +wrote 512/512 bytes at offset 140544 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +wrote 512/512 bytes at offset 141568 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +wrote 512/512 bytes at offset 142592 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +wrote 512/512 bytes at offset 143616 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +wrote 512/512 bytes at offset 144640 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +wrote 512/512 bytes at offset 145664 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +wrote 512/512 bytes at offset 146688 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) === IO: pattern 33 wrote 2048/2048 bytes at offset 147968 2 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) @@ -1071,42 +1179,78 @@ read 512/512 bytes at offset 108544 read 512/512 bytes at offset 109568 512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) === IO: pattern 216 -offset 110848 is not sector aligned -offset 111872 is not sector aligned -offset 112896 is not sector aligned -offset 113920 is not sector aligned -offset 114944 is not sector aligned -offset 115968 is not sector aligned -offset 116992 is not sector aligned -offset 118016 is not sector aligned -offset 119040 is not sector aligned -offset 120064 is not sector aligned -offset 121088 is not sector aligned -offset 122112 is not sector aligned -offset 123136 is not sector aligned -offset 124160 is not sector aligned -offset 125184 is not sector aligned -offset 126208 is not sector aligned -offset 127232 is not sector aligned -offset 128256 is not sector aligned -offset 129280 is not sector aligned -offset 130304 is not sector aligned -offset 131328 is not sector aligned -offset 132352 is not sector aligned -offset 133376 is not sector aligned -offset 134400 is not sector aligned -offset 135424 is not sector aligned -offset 136448 is not sector aligned -offset 137472 is not sector aligned -offset 138496 is not sector aligned -offset 139520 is not sector aligned -offset 140544 is not sector aligned -offset 141568 is not sector aligned -offset 142592 is not sector aligned -offset 143616 is not sector aligned -offset 144640 is not sector aligned -offset 145664 is not sector aligned -offset 146688 is not sector aligned +read 512/512 bytes at offset 110848 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 111872 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 112896 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 113920 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 114944 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 115968 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 116992 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 118016 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 119040 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 120064 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 121088 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 122112 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 123136 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 124160 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 125184 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 126208 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 127232 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 128256 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 129280 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 130304 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 131328 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 132352 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 133376 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 134400 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 135424 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 136448 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 137472 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 138496 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 139520 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 140544 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 141568 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 142592 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 143616 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 144640 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 145664 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 146688 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) === IO: pattern 33 read 2048/2048 bytes at offset 147968 2 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) @@ -1355,42 +1499,78 @@ wrote 512/512 bytes at offset 4295075840 wrote 512/512 bytes at offset 4295076864 512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) === IO: pattern 216 -offset 4295078144 is not sector aligned -offset 4295079168 is not sector aligned -offset 4295080192 is not sector aligned -offset 4295081216 is not sector aligned -offset 4295082240 is not sector aligned -offset 4295083264 is not sector aligned -offset 4295084288 is not sector aligned -offset 4295085312 is not sector aligned -offset 4295086336 is not sector aligned -offset 4295087360 is not sector aligned -offset 4295088384 is not sector aligned -offset 4295089408 is not sector aligned -offset 4295090432 is not sector aligned -offset 4295091456 is not sector aligned -offset 4295092480 is not sector aligned -offset 4295093504 is not sector aligned -offset 4295094528 is not sector aligned -offset 4295095552 is not sector aligned -offset 4295096576 is not sector aligned -offset 4295097600 is not sector aligned -offset 4295098624 is not sector aligned -offset 4295099648 is not sector aligned -offset 4295100672 is not sector aligned -offset 4295101696 is not sector aligned -offset 4295102720 is not sector aligned -offset 4295103744 is not sector aligned -offset 4295104768 is not sector aligned -offset 4295105792 is not sector aligned -offset 4295106816 is not sector aligned -offset 4295107840 is not sector aligned -offset 4295108864 is not sector aligned -offset 4295109888 is not sector aligned -offset 4295110912 is not sector aligned -offset 4295111936 is not sector aligned -offset 4295112960 is not sector aligned -offset 4295113984 is not sector aligned +wrote 512/512 bytes at offset 4295078144 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +wrote 512/512 bytes at offset 4295079168 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +wrote 512/512 bytes at offset 4295080192 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +wrote 512/512 bytes at offset 4295081216 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +wrote 512/512 bytes at offset 4295082240 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +wrote 512/512 bytes at offset 4295083264 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +wrote 512/512 bytes at offset 4295084288 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +wrote 512/512 bytes at offset 4295085312 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +wrote 512/512 bytes at offset 4295086336 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +wrote 512/512 bytes at offset 4295087360 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +wrote 512/512 bytes at offset 4295088384 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +wrote 512/512 bytes at offset 4295089408 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +wrote 512/512 bytes at offset 4295090432 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +wrote 512/512 bytes at offset 4295091456 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +wrote 512/512 bytes at offset 4295092480 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +wrote 512/512 bytes at offset 4295093504 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +wrote 512/512 bytes at offset 4295094528 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +wrote 512/512 bytes at offset 4295095552 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +wrote 512/512 bytes at offset 4295096576 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +wrote 512/512 bytes at offset 4295097600 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +wrote 512/512 bytes at offset 4295098624 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +wrote 512/512 bytes at offset 4295099648 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +wrote 512/512 bytes at offset 4295100672 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +wrote 512/512 bytes at offset 4295101696 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +wrote 512/512 bytes at offset 4295102720 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +wrote 512/512 bytes at offset 4295103744 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +wrote 512/512 bytes at offset 4295104768 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +wrote 512/512 bytes at offset 4295105792 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +wrote 512/512 bytes at offset 4295106816 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +wrote 512/512 bytes at offset 4295107840 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +wrote 512/512 bytes at offset 4295108864 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +wrote 512/512 bytes at offset 4295109888 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +wrote 512/512 bytes at offset 4295110912 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +wrote 512/512 bytes at offset 4295111936 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +wrote 512/512 bytes at offset 4295112960 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +wrote 512/512 bytes at offset 4295113984 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) === IO: pattern 33 wrote 2048/2048 bytes at offset 4295115264 2 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) @@ -1637,42 +1817,78 @@ read 512/512 bytes at offset 4295075840 read 512/512 bytes at offset 4295076864 512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) === IO: pattern 216 -offset 4295078144 is not sector aligned -offset 4295079168 is not sector aligned -offset 4295080192 is not sector aligned -offset 4295081216 is not sector aligned -offset 4295082240 is not sector aligned -offset 4295083264 is not sector aligned -offset 4295084288 is not sector aligned -offset 4295085312 is not sector aligned -offset 4295086336 is not sector aligned -offset 4295087360 is not sector aligned -offset 4295088384 is not sector aligned -offset 4295089408 is not sector aligned -offset 4295090432 is not sector aligned -offset 4295091456 is not sector aligned -offset 4295092480 is not sector aligned -offset 4295093504 is not sector aligned -offset 4295094528 is not sector aligned -offset 4295095552 is not sector aligned -offset 4295096576 is not sector aligned -offset 4295097600 is not sector aligned -offset 4295098624 is not sector aligned -offset 4295099648 is not sector aligned -offset 4295100672 is not sector aligned -offset 4295101696 is not sector aligned -offset 4295102720 is not sector aligned -offset 4295103744 is not sector aligned -offset 4295104768 is not sector aligned -offset 4295105792 is not sector aligned -offset 4295106816 is not sector aligned -offset 4295107840 is not sector aligned -offset 4295108864 is not sector aligned -offset 4295109888 is not sector aligned -offset 4295110912 is not sector aligned -offset 4295111936 is not sector aligned -offset 4295112960 is not sector aligned -offset 4295113984 is not sector aligned +read 512/512 bytes at offset 4295078144 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 4295079168 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 4295080192 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 4295081216 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 4295082240 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 4295083264 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 4295084288 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 4295085312 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 4295086336 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 4295087360 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 4295088384 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 4295089408 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 4295090432 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 4295091456 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 4295092480 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 4295093504 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 4295094528 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 4295095552 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 4295096576 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 4295097600 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 4295098624 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 4295099648 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 4295100672 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 4295101696 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 4295102720 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 4295103744 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 4295104768 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 4295105792 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 4295106816 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 4295107840 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 4295108864 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 4295109888 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 4295110912 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 4295111936 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 4295112960 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 4295113984 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) === IO: pattern 33 read 2048/2048 bytes at offset 4295115264 2 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) @@ -1919,42 +2135,78 @@ wrote 512/512 bytes at offset 4295075840 wrote 512/512 bytes at offset 4295076864 512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) === IO: pattern 216 -offset 4295078144 is not sector aligned -offset 4295079168 is not sector aligned -offset 4295080192 is not sector aligned -offset 4295081216 is not sector aligned -offset 4295082240 is not sector aligned -offset 4295083264 is not sector aligned -offset 4295084288 is not sector aligned -offset 4295085312 is not sector aligned -offset 4295086336 is not sector aligned -offset 4295087360 is not sector aligned -offset 4295088384 is not sector aligned -offset 4295089408 is not sector aligned -offset 4295090432 is not sector aligned -offset 4295091456 is not sector aligned -offset 4295092480 is not sector aligned -offset 4295093504 is not sector aligned -offset 4295094528 is not sector aligned -offset 4295095552 is not sector aligned -offset 4295096576 is not sector aligned -offset 4295097600 is not sector aligned -offset 4295098624 is not sector aligned -offset 4295099648 is not sector aligned -offset 4295100672 is not sector aligned -offset 4295101696 is not sector aligned -offset 4295102720 is not sector aligned -offset 4295103744 is not sector aligned -offset 4295104768 is not sector aligned -offset 4295105792 is not sector aligned -offset 4295106816 is not sector aligned -offset 4295107840 is not sector aligned -offset 4295108864 is not sector aligned -offset 4295109888 is not sector aligned -offset 4295110912 is not sector aligned -offset 4295111936 is not sector aligned -offset 4295112960 is not sector aligned -offset 4295113984 is not sector aligned +wrote 512/512 bytes at offset 4295078144 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +wrote 512/512 bytes at offset 4295079168 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +wrote 512/512 bytes at offset 4295080192 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +wrote 512/512 bytes at offset 4295081216 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +wrote 512/512 bytes at offset 4295082240 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +wrote 512/512 bytes at offset 4295083264 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +wrote 512/512 bytes at offset 4295084288 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +wrote 512/512 bytes at offset 4295085312 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +wrote 512/512 bytes at offset 4295086336 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +wrote 512/512 bytes at offset 4295087360 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +wrote 512/512 bytes at offset 4295088384 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +wrote 512/512 bytes at offset 4295089408 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +wrote 512/512 bytes at offset 4295090432 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +wrote 512/512 bytes at offset 4295091456 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +wrote 512/512 bytes at offset 4295092480 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +wrote 512/512 bytes at offset 4295093504 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +wrote 512/512 bytes at offset 4295094528 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +wrote 512/512 bytes at offset 4295095552 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +wrote 512/512 bytes at offset 4295096576 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +wrote 512/512 bytes at offset 4295097600 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +wrote 512/512 bytes at offset 4295098624 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +wrote 512/512 bytes at offset 4295099648 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +wrote 512/512 bytes at offset 4295100672 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +wrote 512/512 bytes at offset 4295101696 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +wrote 512/512 bytes at offset 4295102720 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +wrote 512/512 bytes at offset 4295103744 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +wrote 512/512 bytes at offset 4295104768 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +wrote 512/512 bytes at offset 4295105792 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +wrote 512/512 bytes at offset 4295106816 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +wrote 512/512 bytes at offset 4295107840 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +wrote 512/512 bytes at offset 4295108864 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +wrote 512/512 bytes at offset 4295109888 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +wrote 512/512 bytes at offset 4295110912 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +wrote 512/512 bytes at offset 4295111936 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +wrote 512/512 bytes at offset 4295112960 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +wrote 512/512 bytes at offset 4295113984 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) === IO: pattern 33 wrote 2048/2048 bytes at offset 4295115264 2 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) @@ -2201,42 +2453,78 @@ read 512/512 bytes at offset 4295075840 read 512/512 bytes at offset 4295076864 512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) === IO: pattern 216 -offset 4295078144 is not sector aligned -offset 4295079168 is not sector aligned -offset 4295080192 is not sector aligned -offset 4295081216 is not sector aligned -offset 4295082240 is not sector aligned -offset 4295083264 is not sector aligned -offset 4295084288 is not sector aligned -offset 4295085312 is not sector aligned -offset 4295086336 is not sector aligned -offset 4295087360 is not sector aligned -offset 4295088384 is not sector aligned -offset 4295089408 is not sector aligned -offset 4295090432 is not sector aligned -offset 4295091456 is not sector aligned -offset 4295092480 is not sector aligned -offset 4295093504 is not sector aligned -offset 4295094528 is not sector aligned -offset 4295095552 is not sector aligned -offset 4295096576 is not sector aligned -offset 4295097600 is not sector aligned -offset 4295098624 is not sector aligned -offset 4295099648 is not sector aligned -offset 4295100672 is not sector aligned -offset 4295101696 is not sector aligned -offset 4295102720 is not sector aligned -offset 4295103744 is not sector aligned -offset 4295104768 is not sector aligned -offset 4295105792 is not sector aligned -offset 4295106816 is not sector aligned -offset 4295107840 is not sector aligned -offset 4295108864 is not sector aligned -offset 4295109888 is not sector aligned -offset 4295110912 is not sector aligned -offset 4295111936 is not sector aligned -offset 4295112960 is not sector aligned -offset 4295113984 is not sector aligned +read 512/512 bytes at offset 4295078144 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 4295079168 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 4295080192 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 4295081216 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 4295082240 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 4295083264 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 4295084288 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 4295085312 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 4295086336 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 4295087360 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 4295088384 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 4295089408 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 4295090432 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 4295091456 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 4295092480 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 4295093504 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 4295094528 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 4295095552 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 4295096576 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 4295097600 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 4295098624 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 4295099648 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 4295100672 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 4295101696 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 4295102720 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 4295103744 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 4295104768 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 4295105792 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 4295106816 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 4295107840 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 4295108864 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 4295109888 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 4295110912 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 4295111936 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 4295112960 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 4295113984 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) === IO: pattern 33 read 2048/2048 bytes at offset 4295115264 2 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) @@ -2489,42 +2777,78 @@ read 512/512 bytes at offset 108544 read 512/512 bytes at offset 109568 512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) === IO: pattern 216 -offset 110848 is not sector aligned -offset 111872 is not sector aligned -offset 112896 is not sector aligned -offset 113920 is not sector aligned -offset 114944 is not sector aligned -offset 115968 is not sector aligned -offset 116992 is not sector aligned -offset 118016 is not sector aligned -offset 119040 is not sector aligned -offset 120064 is not sector aligned -offset 121088 is not sector aligned -offset 122112 is not sector aligned -offset 123136 is not sector aligned -offset 124160 is not sector aligned -offset 125184 is not sector aligned -offset 126208 is not sector aligned -offset 127232 is not sector aligned -offset 128256 is not sector aligned -offset 129280 is not sector aligned -offset 130304 is not sector aligned -offset 131328 is not sector aligned -offset 132352 is not sector aligned -offset 133376 is not sector aligned -offset 134400 is not sector aligned -offset 135424 is not sector aligned -offset 136448 is not sector aligned -offset 137472 is not sector aligned -offset 138496 is not sector aligned -offset 139520 is not sector aligned -offset 140544 is not sector aligned -offset 141568 is not sector aligned -offset 142592 is not sector aligned -offset 143616 is not sector aligned -offset 144640 is not sector aligned -offset 145664 is not sector aligned -offset 146688 is not sector aligned +read 512/512 bytes at offset 110848 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 111872 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 112896 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 113920 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 114944 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 115968 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 116992 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 118016 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 119040 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 120064 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 121088 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 122112 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 123136 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 124160 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 125184 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 126208 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 127232 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 128256 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 129280 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 130304 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 131328 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 132352 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 133376 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 134400 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 135424 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 136448 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 137472 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 138496 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 139520 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 140544 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 141568 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 142592 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 143616 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 144640 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 145664 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 146688 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) === IO: pattern 33 read 2048/2048 bytes at offset 147968 2 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) @@ -2771,42 +3095,78 @@ read 512/512 bytes at offset 108544 read 512/512 bytes at offset 109568 512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) === IO: pattern 216 -offset 110848 is not sector aligned -offset 111872 is not sector aligned -offset 112896 is not sector aligned -offset 113920 is not sector aligned -offset 114944 is not sector aligned -offset 115968 is not sector aligned -offset 116992 is not sector aligned -offset 118016 is not sector aligned -offset 119040 is not sector aligned -offset 120064 is not sector aligned -offset 121088 is not sector aligned -offset 122112 is not sector aligned -offset 123136 is not sector aligned -offset 124160 is not sector aligned -offset 125184 is not sector aligned -offset 126208 is not sector aligned -offset 127232 is not sector aligned -offset 128256 is not sector aligned -offset 129280 is not sector aligned -offset 130304 is not sector aligned -offset 131328 is not sector aligned -offset 132352 is not sector aligned -offset 133376 is not sector aligned -offset 134400 is not sector aligned -offset 135424 is not sector aligned -offset 136448 is not sector aligned -offset 137472 is not sector aligned -offset 138496 is not sector aligned -offset 139520 is not sector aligned -offset 140544 is not sector aligned -offset 141568 is not sector aligned -offset 142592 is not sector aligned -offset 143616 is not sector aligned -offset 144640 is not sector aligned -offset 145664 is not sector aligned -offset 146688 is not sector aligned +read 512/512 bytes at offset 110848 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 111872 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 112896 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 113920 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 114944 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 115968 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 116992 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 118016 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 119040 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 120064 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 121088 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 122112 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 123136 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 124160 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 125184 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 126208 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 127232 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 128256 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 129280 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 130304 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 131328 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 132352 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 133376 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 134400 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 135424 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 136448 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 137472 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 138496 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 139520 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 140544 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 141568 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 142592 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 143616 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 144640 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 145664 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 146688 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) === IO: pattern 33 read 2048/2048 bytes at offset 147968 2 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) @@ -3055,42 +3415,78 @@ read 512/512 bytes at offset 4295075840 read 512/512 bytes at offset 4295076864 512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) === IO: pattern 216 -offset 4295078144 is not sector aligned -offset 4295079168 is not sector aligned -offset 4295080192 is not sector aligned -offset 4295081216 is not sector aligned -offset 4295082240 is not sector aligned -offset 4295083264 is not sector aligned -offset 4295084288 is not sector aligned -offset 4295085312 is not sector aligned -offset 4295086336 is not sector aligned -offset 4295087360 is not sector aligned -offset 4295088384 is not sector aligned -offset 4295089408 is not sector aligned -offset 4295090432 is not sector aligned -offset 4295091456 is not sector aligned -offset 4295092480 is not sector aligned -offset 4295093504 is not sector aligned -offset 4295094528 is not sector aligned -offset 4295095552 is not sector aligned -offset 4295096576 is not sector aligned -offset 4295097600 is not sector aligned -offset 4295098624 is not sector aligned -offset 4295099648 is not sector aligned -offset 4295100672 is not sector aligned -offset 4295101696 is not sector aligned -offset 4295102720 is not sector aligned -offset 4295103744 is not sector aligned -offset 4295104768 is not sector aligned -offset 4295105792 is not sector aligned -offset 4295106816 is not sector aligned -offset 4295107840 is not sector aligned -offset 4295108864 is not sector aligned -offset 4295109888 is not sector aligned -offset 4295110912 is not sector aligned -offset 4295111936 is not sector aligned -offset 4295112960 is not sector aligned -offset 4295113984 is not sector aligned +read 512/512 bytes at offset 4295078144 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 4295079168 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 4295080192 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 4295081216 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 4295082240 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 4295083264 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 4295084288 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 4295085312 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 4295086336 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 4295087360 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 4295088384 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 4295089408 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 4295090432 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 4295091456 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 4295092480 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 4295093504 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 4295094528 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 4295095552 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 4295096576 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 4295097600 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 4295098624 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 4295099648 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 4295100672 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 4295101696 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 4295102720 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 4295103744 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 4295104768 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 4295105792 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 4295106816 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 4295107840 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 4295108864 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 4295109888 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 4295110912 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 4295111936 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 4295112960 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 4295113984 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) === IO: pattern 33 read 2048/2048 bytes at offset 4295115264 2 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) @@ -3337,42 +3733,78 @@ read 512/512 bytes at offset 4295075840 read 512/512 bytes at offset 4295076864 512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) === IO: pattern 216 -offset 4295078144 is not sector aligned -offset 4295079168 is not sector aligned -offset 4295080192 is not sector aligned -offset 4295081216 is not sector aligned -offset 4295082240 is not sector aligned -offset 4295083264 is not sector aligned -offset 4295084288 is not sector aligned -offset 4295085312 is not sector aligned -offset 4295086336 is not sector aligned -offset 4295087360 is not sector aligned -offset 4295088384 is not sector aligned -offset 4295089408 is not sector aligned -offset 4295090432 is not sector aligned -offset 4295091456 is not sector aligned -offset 4295092480 is not sector aligned -offset 4295093504 is not sector aligned -offset 4295094528 is not sector aligned -offset 4295095552 is not sector aligned -offset 4295096576 is not sector aligned -offset 4295097600 is not sector aligned -offset 4295098624 is not sector aligned -offset 4295099648 is not sector aligned -offset 4295100672 is not sector aligned -offset 4295101696 is not sector aligned -offset 4295102720 is not sector aligned -offset 4295103744 is not sector aligned -offset 4295104768 is not sector aligned -offset 4295105792 is not sector aligned -offset 4295106816 is not sector aligned -offset 4295107840 is not sector aligned -offset 4295108864 is not sector aligned -offset 4295109888 is not sector aligned -offset 4295110912 is not sector aligned -offset 4295111936 is not sector aligned -offset 4295112960 is not sector aligned -offset 4295113984 is not sector aligned +read 512/512 bytes at offset 4295078144 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 4295079168 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 4295080192 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 4295081216 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 4295082240 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 4295083264 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 4295084288 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 4295085312 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 4295086336 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 4295087360 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 4295088384 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 4295089408 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 4295090432 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 4295091456 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 4295092480 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 4295093504 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 4295094528 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 4295095552 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 4295096576 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 4295097600 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 4295098624 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 4295099648 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 4295100672 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 4295101696 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 4295102720 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 4295103744 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 4295104768 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 4295105792 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 4295106816 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 4295107840 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 4295108864 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 4295109888 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 4295110912 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 4295111936 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 4295112960 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 4295113984 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) === IO: pattern 33 read 2048/2048 bytes at offset 4295115264 2 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) @@ -3623,42 +4055,78 @@ wrote 512/512 bytes at offset 109056 wrote 512/512 bytes at offset 110080 512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) === IO: pattern 217 -offset 111360 is not sector aligned -offset 112384 is not sector aligned -offset 113408 is not sector aligned -offset 114432 is not sector aligned -offset 115456 is not sector aligned -offset 116480 is not sector aligned -offset 117504 is not sector aligned -offset 118528 is not sector aligned -offset 119552 is not sector aligned -offset 120576 is not sector aligned -offset 121600 is not sector aligned -offset 122624 is not sector aligned -offset 123648 is not sector aligned -offset 124672 is not sector aligned -offset 125696 is not sector aligned -offset 126720 is not sector aligned -offset 127744 is not sector aligned -offset 128768 is not sector aligned -offset 129792 is not sector aligned -offset 130816 is not sector aligned -offset 131840 is not sector aligned -offset 132864 is not sector aligned -offset 133888 is not sector aligned -offset 134912 is not sector aligned -offset 135936 is not sector aligned -offset 136960 is not sector aligned -offset 137984 is not sector aligned -offset 139008 is not sector aligned -offset 140032 is not sector aligned -offset 141056 is not sector aligned -offset 142080 is not sector aligned -offset 143104 is not sector aligned -offset 144128 is not sector aligned -offset 145152 is not sector aligned -offset 146176 is not sector aligned -offset 147200 is not sector aligned +wrote 512/512 bytes at offset 111360 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +wrote 512/512 bytes at offset 112384 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +wrote 512/512 bytes at offset 113408 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +wrote 512/512 bytes at offset 114432 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +wrote 512/512 bytes at offset 115456 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +wrote 512/512 bytes at offset 116480 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +wrote 512/512 bytes at offset 117504 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +wrote 512/512 bytes at offset 118528 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +wrote 512/512 bytes at offset 119552 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +wrote 512/512 bytes at offset 120576 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +wrote 512/512 bytes at offset 121600 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +wrote 512/512 bytes at offset 122624 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +wrote 512/512 bytes at offset 123648 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +wrote 512/512 bytes at offset 124672 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +wrote 512/512 bytes at offset 125696 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +wrote 512/512 bytes at offset 126720 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +wrote 512/512 bytes at offset 127744 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +wrote 512/512 bytes at offset 128768 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +wrote 512/512 bytes at offset 129792 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +wrote 512/512 bytes at offset 130816 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +wrote 512/512 bytes at offset 131840 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +wrote 512/512 bytes at offset 132864 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +wrote 512/512 bytes at offset 133888 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +wrote 512/512 bytes at offset 134912 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +wrote 512/512 bytes at offset 135936 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +wrote 512/512 bytes at offset 136960 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +wrote 512/512 bytes at offset 137984 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +wrote 512/512 bytes at offset 139008 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +wrote 512/512 bytes at offset 140032 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +wrote 512/512 bytes at offset 141056 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +wrote 512/512 bytes at offset 142080 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +wrote 512/512 bytes at offset 143104 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +wrote 512/512 bytes at offset 144128 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +wrote 512/512 bytes at offset 145152 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +wrote 512/512 bytes at offset 146176 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +wrote 512/512 bytes at offset 147200 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) === IO: pattern 34 wrote 2048/2048 bytes at offset 148480 2 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) @@ -3905,42 +4373,78 @@ read 512/512 bytes at offset 109056 read 512/512 bytes at offset 110080 512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) === IO: pattern 217 -offset 111360 is not sector aligned -offset 112384 is not sector aligned -offset 113408 is not sector aligned -offset 114432 is not sector aligned -offset 115456 is not sector aligned -offset 116480 is not sector aligned -offset 117504 is not sector aligned -offset 118528 is not sector aligned -offset 119552 is not sector aligned -offset 120576 is not sector aligned -offset 121600 is not sector aligned -offset 122624 is not sector aligned -offset 123648 is not sector aligned -offset 124672 is not sector aligned -offset 125696 is not sector aligned -offset 126720 is not sector aligned -offset 127744 is not sector aligned -offset 128768 is not sector aligned -offset 129792 is not sector aligned -offset 130816 is not sector aligned -offset 131840 is not sector aligned -offset 132864 is not sector aligned -offset 133888 is not sector aligned -offset 134912 is not sector aligned -offset 135936 is not sector aligned -offset 136960 is not sector aligned -offset 137984 is not sector aligned -offset 139008 is not sector aligned -offset 140032 is not sector aligned -offset 141056 is not sector aligned -offset 142080 is not sector aligned -offset 143104 is not sector aligned -offset 144128 is not sector aligned -offset 145152 is not sector aligned -offset 146176 is not sector aligned -offset 147200 is not sector aligned +read 512/512 bytes at offset 111360 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 112384 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 113408 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 114432 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 115456 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 116480 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 117504 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 118528 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 119552 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 120576 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 121600 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 122624 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 123648 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 124672 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 125696 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 126720 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 127744 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 128768 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 129792 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 130816 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 131840 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 132864 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 133888 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 134912 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 135936 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 136960 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 137984 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 139008 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 140032 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 141056 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 142080 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 143104 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 144128 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 145152 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 146176 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 147200 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) === IO: pattern 34 read 2048/2048 bytes at offset 148480 2 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) @@ -4187,42 +4691,78 @@ wrote 512/512 bytes at offset 109056 wrote 512/512 bytes at offset 110080 512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) === IO: pattern 217 -offset 111360 is not sector aligned -offset 112384 is not sector aligned -offset 113408 is not sector aligned -offset 114432 is not sector aligned -offset 115456 is not sector aligned -offset 116480 is not sector aligned -offset 117504 is not sector aligned -offset 118528 is not sector aligned -offset 119552 is not sector aligned -offset 120576 is not sector aligned -offset 121600 is not sector aligned -offset 122624 is not sector aligned -offset 123648 is not sector aligned -offset 124672 is not sector aligned -offset 125696 is not sector aligned -offset 126720 is not sector aligned -offset 127744 is not sector aligned -offset 128768 is not sector aligned -offset 129792 is not sector aligned -offset 130816 is not sector aligned -offset 131840 is not sector aligned -offset 132864 is not sector aligned -offset 133888 is not sector aligned -offset 134912 is not sector aligned -offset 135936 is not sector aligned -offset 136960 is not sector aligned -offset 137984 is not sector aligned -offset 139008 is not sector aligned -offset 140032 is not sector aligned -offset 141056 is not sector aligned -offset 142080 is not sector aligned -offset 143104 is not sector aligned -offset 144128 is not sector aligned -offset 145152 is not sector aligned -offset 146176 is not sector aligned -offset 147200 is not sector aligned +wrote 512/512 bytes at offset 111360 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +wrote 512/512 bytes at offset 112384 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +wrote 512/512 bytes at offset 113408 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +wrote 512/512 bytes at offset 114432 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +wrote 512/512 bytes at offset 115456 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +wrote 512/512 bytes at offset 116480 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +wrote 512/512 bytes at offset 117504 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +wrote 512/512 bytes at offset 118528 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +wrote 512/512 bytes at offset 119552 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +wrote 512/512 bytes at offset 120576 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +wrote 512/512 bytes at offset 121600 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +wrote 512/512 bytes at offset 122624 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +wrote 512/512 bytes at offset 123648 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +wrote 512/512 bytes at offset 124672 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +wrote 512/512 bytes at offset 125696 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +wrote 512/512 bytes at offset 126720 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +wrote 512/512 bytes at offset 127744 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +wrote 512/512 bytes at offset 128768 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +wrote 512/512 bytes at offset 129792 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +wrote 512/512 bytes at offset 130816 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +wrote 512/512 bytes at offset 131840 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +wrote 512/512 bytes at offset 132864 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +wrote 512/512 bytes at offset 133888 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +wrote 512/512 bytes at offset 134912 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +wrote 512/512 bytes at offset 135936 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +wrote 512/512 bytes at offset 136960 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +wrote 512/512 bytes at offset 137984 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +wrote 512/512 bytes at offset 139008 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +wrote 512/512 bytes at offset 140032 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +wrote 512/512 bytes at offset 141056 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +wrote 512/512 bytes at offset 142080 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +wrote 512/512 bytes at offset 143104 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +wrote 512/512 bytes at offset 144128 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +wrote 512/512 bytes at offset 145152 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +wrote 512/512 bytes at offset 146176 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +wrote 512/512 bytes at offset 147200 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) === IO: pattern 34 wrote 2048/2048 bytes at offset 148480 2 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) @@ -4469,42 +5009,78 @@ read 512/512 bytes at offset 109056 read 512/512 bytes at offset 110080 512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) === IO: pattern 217 -offset 111360 is not sector aligned -offset 112384 is not sector aligned -offset 113408 is not sector aligned -offset 114432 is not sector aligned -offset 115456 is not sector aligned -offset 116480 is not sector aligned -offset 117504 is not sector aligned -offset 118528 is not sector aligned -offset 119552 is not sector aligned -offset 120576 is not sector aligned -offset 121600 is not sector aligned -offset 122624 is not sector aligned -offset 123648 is not sector aligned -offset 124672 is not sector aligned -offset 125696 is not sector aligned -offset 126720 is not sector aligned -offset 127744 is not sector aligned -offset 128768 is not sector aligned -offset 129792 is not sector aligned -offset 130816 is not sector aligned -offset 131840 is not sector aligned -offset 132864 is not sector aligned -offset 133888 is not sector aligned -offset 134912 is not sector aligned -offset 135936 is not sector aligned -offset 136960 is not sector aligned -offset 137984 is not sector aligned -offset 139008 is not sector aligned -offset 140032 is not sector aligned -offset 141056 is not sector aligned -offset 142080 is not sector aligned -offset 143104 is not sector aligned -offset 144128 is not sector aligned -offset 145152 is not sector aligned -offset 146176 is not sector aligned -offset 147200 is not sector aligned +read 512/512 bytes at offset 111360 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 112384 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 113408 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 114432 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 115456 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 116480 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 117504 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 118528 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 119552 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 120576 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 121600 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 122624 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 123648 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 124672 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 125696 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 126720 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 127744 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 128768 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 129792 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 130816 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 131840 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 132864 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 133888 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 134912 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 135936 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 136960 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 137984 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 139008 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 140032 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 141056 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 142080 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 143104 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 144128 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 145152 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 146176 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 147200 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) === IO: pattern 34 read 2048/2048 bytes at offset 148480 2 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) @@ -4753,42 +5329,78 @@ wrote 512/512 bytes at offset 4295076352 wrote 512/512 bytes at offset 4295077376 512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) === IO: pattern 217 -offset 4295078656 is not sector aligned -offset 4295079680 is not sector aligned -offset 4295080704 is not sector aligned -offset 4295081728 is not sector aligned -offset 4295082752 is not sector aligned -offset 4295083776 is not sector aligned -offset 4295084800 is not sector aligned -offset 4295085824 is not sector aligned -offset 4295086848 is not sector aligned -offset 4295087872 is not sector aligned -offset 4295088896 is not sector aligned -offset 4295089920 is not sector aligned -offset 4295090944 is not sector aligned -offset 4295091968 is not sector aligned -offset 4295092992 is not sector aligned -offset 4295094016 is not sector aligned -offset 4295095040 is not sector aligned -offset 4295096064 is not sector aligned -offset 4295097088 is not sector aligned -offset 4295098112 is not sector aligned -offset 4295099136 is not sector aligned -offset 4295100160 is not sector aligned -offset 4295101184 is not sector aligned -offset 4295102208 is not sector aligned -offset 4295103232 is not sector aligned -offset 4295104256 is not sector aligned -offset 4295105280 is not sector aligned -offset 4295106304 is not sector aligned -offset 4295107328 is not sector aligned -offset 4295108352 is not sector aligned -offset 4295109376 is not sector aligned -offset 4295110400 is not sector aligned -offset 4295111424 is not sector aligned -offset 4295112448 is not sector aligned -offset 4295113472 is not sector aligned -offset 4295114496 is not sector aligned +wrote 512/512 bytes at offset 4295078656 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +wrote 512/512 bytes at offset 4295079680 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +wrote 512/512 bytes at offset 4295080704 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +wrote 512/512 bytes at offset 4295081728 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +wrote 512/512 bytes at offset 4295082752 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +wrote 512/512 bytes at offset 4295083776 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +wrote 512/512 bytes at offset 4295084800 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +wrote 512/512 bytes at offset 4295085824 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +wrote 512/512 bytes at offset 4295086848 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +wrote 512/512 bytes at offset 4295087872 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +wrote 512/512 bytes at offset 4295088896 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +wrote 512/512 bytes at offset 4295089920 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +wrote 512/512 bytes at offset 4295090944 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +wrote 512/512 bytes at offset 4295091968 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +wrote 512/512 bytes at offset 4295092992 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +wrote 512/512 bytes at offset 4295094016 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +wrote 512/512 bytes at offset 4295095040 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +wrote 512/512 bytes at offset 4295096064 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +wrote 512/512 bytes at offset 4295097088 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +wrote 512/512 bytes at offset 4295098112 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +wrote 512/512 bytes at offset 4295099136 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +wrote 512/512 bytes at offset 4295100160 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +wrote 512/512 bytes at offset 4295101184 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +wrote 512/512 bytes at offset 4295102208 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +wrote 512/512 bytes at offset 4295103232 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +wrote 512/512 bytes at offset 4295104256 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +wrote 512/512 bytes at offset 4295105280 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +wrote 512/512 bytes at offset 4295106304 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +wrote 512/512 bytes at offset 4295107328 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +wrote 512/512 bytes at offset 4295108352 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +wrote 512/512 bytes at offset 4295109376 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +wrote 512/512 bytes at offset 4295110400 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +wrote 512/512 bytes at offset 4295111424 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +wrote 512/512 bytes at offset 4295112448 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +wrote 512/512 bytes at offset 4295113472 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +wrote 512/512 bytes at offset 4295114496 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) === IO: pattern 34 wrote 2048/2048 bytes at offset 4295115776 2 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) @@ -5035,42 +5647,78 @@ read 512/512 bytes at offset 4295076352 read 512/512 bytes at offset 4295077376 512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) === IO: pattern 217 -offset 4295078656 is not sector aligned -offset 4295079680 is not sector aligned -offset 4295080704 is not sector aligned -offset 4295081728 is not sector aligned -offset 4295082752 is not sector aligned -offset 4295083776 is not sector aligned -offset 4295084800 is not sector aligned -offset 4295085824 is not sector aligned -offset 4295086848 is not sector aligned -offset 4295087872 is not sector aligned -offset 4295088896 is not sector aligned -offset 4295089920 is not sector aligned -offset 4295090944 is not sector aligned -offset 4295091968 is not sector aligned -offset 4295092992 is not sector aligned -offset 4295094016 is not sector aligned -offset 4295095040 is not sector aligned -offset 4295096064 is not sector aligned -offset 4295097088 is not sector aligned -offset 4295098112 is not sector aligned -offset 4295099136 is not sector aligned -offset 4295100160 is not sector aligned -offset 4295101184 is not sector aligned -offset 4295102208 is not sector aligned -offset 4295103232 is not sector aligned -offset 4295104256 is not sector aligned -offset 4295105280 is not sector aligned -offset 4295106304 is not sector aligned -offset 4295107328 is not sector aligned -offset 4295108352 is not sector aligned -offset 4295109376 is not sector aligned -offset 4295110400 is not sector aligned -offset 4295111424 is not sector aligned -offset 4295112448 is not sector aligned -offset 4295113472 is not sector aligned -offset 4295114496 is not sector aligned +read 512/512 bytes at offset 4295078656 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 4295079680 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 4295080704 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 4295081728 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 4295082752 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 4295083776 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 4295084800 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 4295085824 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 4295086848 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 4295087872 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 4295088896 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 4295089920 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 4295090944 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 4295091968 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 4295092992 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 4295094016 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 4295095040 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 4295096064 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 4295097088 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 4295098112 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 4295099136 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 4295100160 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 4295101184 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 4295102208 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 4295103232 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 4295104256 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 4295105280 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 4295106304 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 4295107328 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 4295108352 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 4295109376 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 4295110400 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 4295111424 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 4295112448 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 4295113472 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 4295114496 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) === IO: pattern 34 read 2048/2048 bytes at offset 4295115776 2 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) @@ -5317,42 +5965,78 @@ wrote 512/512 bytes at offset 4295076352 wrote 512/512 bytes at offset 4295077376 512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) === IO: pattern 217 -offset 4295078656 is not sector aligned -offset 4295079680 is not sector aligned -offset 4295080704 is not sector aligned -offset 4295081728 is not sector aligned -offset 4295082752 is not sector aligned -offset 4295083776 is not sector aligned -offset 4295084800 is not sector aligned -offset 4295085824 is not sector aligned -offset 4295086848 is not sector aligned -offset 4295087872 is not sector aligned -offset 4295088896 is not sector aligned -offset 4295089920 is not sector aligned -offset 4295090944 is not sector aligned -offset 4295091968 is not sector aligned -offset 4295092992 is not sector aligned -offset 4295094016 is not sector aligned -offset 4295095040 is not sector aligned -offset 4295096064 is not sector aligned -offset 4295097088 is not sector aligned -offset 4295098112 is not sector aligned -offset 4295099136 is not sector aligned -offset 4295100160 is not sector aligned -offset 4295101184 is not sector aligned -offset 4295102208 is not sector aligned -offset 4295103232 is not sector aligned -offset 4295104256 is not sector aligned -offset 4295105280 is not sector aligned -offset 4295106304 is not sector aligned -offset 4295107328 is not sector aligned -offset 4295108352 is not sector aligned -offset 4295109376 is not sector aligned -offset 4295110400 is not sector aligned -offset 4295111424 is not sector aligned -offset 4295112448 is not sector aligned -offset 4295113472 is not sector aligned -offset 4295114496 is not sector aligned +wrote 512/512 bytes at offset 4295078656 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +wrote 512/512 bytes at offset 4295079680 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +wrote 512/512 bytes at offset 4295080704 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +wrote 512/512 bytes at offset 4295081728 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +wrote 512/512 bytes at offset 4295082752 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +wrote 512/512 bytes at offset 4295083776 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +wrote 512/512 bytes at offset 4295084800 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +wrote 512/512 bytes at offset 4295085824 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +wrote 512/512 bytes at offset 4295086848 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +wrote 512/512 bytes at offset 4295087872 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +wrote 512/512 bytes at offset 4295088896 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +wrote 512/512 bytes at offset 4295089920 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +wrote 512/512 bytes at offset 4295090944 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +wrote 512/512 bytes at offset 4295091968 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +wrote 512/512 bytes at offset 4295092992 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +wrote 512/512 bytes at offset 4295094016 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +wrote 512/512 bytes at offset 4295095040 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +wrote 512/512 bytes at offset 4295096064 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +wrote 512/512 bytes at offset 4295097088 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +wrote 512/512 bytes at offset 4295098112 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +wrote 512/512 bytes at offset 4295099136 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +wrote 512/512 bytes at offset 4295100160 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +wrote 512/512 bytes at offset 4295101184 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +wrote 512/512 bytes at offset 4295102208 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +wrote 512/512 bytes at offset 4295103232 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +wrote 512/512 bytes at offset 4295104256 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +wrote 512/512 bytes at offset 4295105280 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +wrote 512/512 bytes at offset 4295106304 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +wrote 512/512 bytes at offset 4295107328 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +wrote 512/512 bytes at offset 4295108352 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +wrote 512/512 bytes at offset 4295109376 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +wrote 512/512 bytes at offset 4295110400 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +wrote 512/512 bytes at offset 4295111424 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +wrote 512/512 bytes at offset 4295112448 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +wrote 512/512 bytes at offset 4295113472 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +wrote 512/512 bytes at offset 4295114496 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) === IO: pattern 34 wrote 2048/2048 bytes at offset 4295115776 2 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) @@ -5599,42 +6283,78 @@ read 512/512 bytes at offset 4295076352 read 512/512 bytes at offset 4295077376 512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) === IO: pattern 217 -offset 4295078656 is not sector aligned -offset 4295079680 is not sector aligned -offset 4295080704 is not sector aligned -offset 4295081728 is not sector aligned -offset 4295082752 is not sector aligned -offset 4295083776 is not sector aligned -offset 4295084800 is not sector aligned -offset 4295085824 is not sector aligned -offset 4295086848 is not sector aligned -offset 4295087872 is not sector aligned -offset 4295088896 is not sector aligned -offset 4295089920 is not sector aligned -offset 4295090944 is not sector aligned -offset 4295091968 is not sector aligned -offset 4295092992 is not sector aligned -offset 4295094016 is not sector aligned -offset 4295095040 is not sector aligned -offset 4295096064 is not sector aligned -offset 4295097088 is not sector aligned -offset 4295098112 is not sector aligned -offset 4295099136 is not sector aligned -offset 4295100160 is not sector aligned -offset 4295101184 is not sector aligned -offset 4295102208 is not sector aligned -offset 4295103232 is not sector aligned -offset 4295104256 is not sector aligned -offset 4295105280 is not sector aligned -offset 4295106304 is not sector aligned -offset 4295107328 is not sector aligned -offset 4295108352 is not sector aligned -offset 4295109376 is not sector aligned -offset 4295110400 is not sector aligned -offset 4295111424 is not sector aligned -offset 4295112448 is not sector aligned -offset 4295113472 is not sector aligned -offset 4295114496 is not sector aligned +read 512/512 bytes at offset 4295078656 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 4295079680 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 4295080704 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 4295081728 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 4295082752 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 4295083776 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 4295084800 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 4295085824 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 4295086848 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 4295087872 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 4295088896 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 4295089920 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 4295090944 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 4295091968 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 4295092992 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 4295094016 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 4295095040 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 4295096064 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 4295097088 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 4295098112 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 4295099136 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 4295100160 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 4295101184 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 4295102208 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 4295103232 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 4295104256 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 4295105280 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 4295106304 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 4295107328 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 4295108352 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 4295109376 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 4295110400 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 4295111424 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 4295112448 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 4295113472 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 4295114496 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) === IO: pattern 34 read 2048/2048 bytes at offset 4295115776 2 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) diff --git a/tests/qemu-iotests/039.out b/tests/qemu-iotests/039.out index 32c884694c..c6e0ac2da3 100644 --- a/tests/qemu-iotests/039.out +++ b/tests/qemu-iotests/039.out @@ -12,9 +12,9 @@ Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728 wrote 512/512 bytes at offset 0 512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) ./common.config: Killed ( if [ "${VALGRIND_QEMU}" == "y" ]; then - exec valgrind --log-file="${VALGRIND_LOGFILE}" --error-exitcode=99 "$QEMU_IO_PROG" $QEMU_IO_OPTIONS "$@"; + exec valgrind --log-file="${VALGRIND_LOGFILE}" --error-exitcode=99 "$QEMU_IO_PROG" $QEMU_IO_ARGS "$@"; else - exec "$QEMU_IO_PROG" $QEMU_IO_OPTIONS "$@"; + exec "$QEMU_IO_PROG" $QEMU_IO_ARGS "$@"; fi ) incompatible_features 0x1 ERROR cluster 5 refcount=0 reference=1 @@ -51,9 +51,9 @@ Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728 wrote 512/512 bytes at offset 0 512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) ./common.config: Killed ( if [ "${VALGRIND_QEMU}" == "y" ]; then - exec valgrind --log-file="${VALGRIND_LOGFILE}" --error-exitcode=99 "$QEMU_IO_PROG" $QEMU_IO_OPTIONS "$@"; + exec valgrind --log-file="${VALGRIND_LOGFILE}" --error-exitcode=99 "$QEMU_IO_PROG" $QEMU_IO_ARGS "$@"; else - exec "$QEMU_IO_PROG" $QEMU_IO_OPTIONS "$@"; + exec "$QEMU_IO_PROG" $QEMU_IO_ARGS "$@"; fi ) incompatible_features 0x1 ERROR cluster 5 refcount=0 reference=1 @@ -69,9 +69,9 @@ Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728 wrote 512/512 bytes at offset 0 512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) ./common.config: Killed ( if [ "${VALGRIND_QEMU}" == "y" ]; then - exec valgrind --log-file="${VALGRIND_LOGFILE}" --error-exitcode=99 "$QEMU_IO_PROG" $QEMU_IO_OPTIONS "$@"; + exec valgrind --log-file="${VALGRIND_LOGFILE}" --error-exitcode=99 "$QEMU_IO_PROG" $QEMU_IO_ARGS "$@"; else - exec "$QEMU_IO_PROG" $QEMU_IO_OPTIONS "$@"; + exec "$QEMU_IO_PROG" $QEMU_IO_ARGS "$@"; fi ) incompatible_features 0x0 No errors were found on the image. @@ -92,9 +92,9 @@ Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728 wrote 512/512 bytes at offset 0 512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) ./common.config: Killed ( if [ "${VALGRIND_QEMU}" == "y" ]; then - exec valgrind --log-file="${VALGRIND_LOGFILE}" --error-exitcode=99 "$QEMU_IO_PROG" $QEMU_IO_OPTIONS "$@"; + exec valgrind --log-file="${VALGRIND_LOGFILE}" --error-exitcode=99 "$QEMU_IO_PROG" $QEMU_IO_ARGS "$@"; else - exec "$QEMU_IO_PROG" $QEMU_IO_OPTIONS "$@"; + exec "$QEMU_IO_PROG" $QEMU_IO_ARGS "$@"; fi ) incompatible_features 0x1 ERROR cluster 5 refcount=0 reference=1 @@ -106,9 +106,9 @@ Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728 wrote 512/512 bytes at offset 0 512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) ./common.config: Killed ( if [ "${VALGRIND_QEMU}" == "y" ]; then - exec valgrind --log-file="${VALGRIND_LOGFILE}" --error-exitcode=99 "$QEMU_IO_PROG" $QEMU_IO_OPTIONS "$@"; + exec valgrind --log-file="${VALGRIND_LOGFILE}" --error-exitcode=99 "$QEMU_IO_PROG" $QEMU_IO_ARGS "$@"; else - exec "$QEMU_IO_PROG" $QEMU_IO_OPTIONS "$@"; + exec "$QEMU_IO_PROG" $QEMU_IO_ARGS "$@"; fi ) incompatible_features 0x0 No errors were found on the image. diff --git a/tests/qemu-iotests/048 b/tests/qemu-iotests/048 index e1eeac2a31..203c04fc7f 100755 --- a/tests/qemu-iotests/048 +++ b/tests/qemu-iotests/048 @@ -31,13 +31,13 @@ _cleanup() { echo "Cleanup" _cleanup_test_img - rm "${TEST_IMG2}" + rm "${TEST_IMG_FILE2}" } trap "_cleanup; exit \$status" 0 1 2 3 15 _compare() { - $QEMU_IMG compare "$@" "$TEST_IMG" "${TEST_IMG2}" + $QEMU_IMG compare $QEMU_IMG_EXTRA_ARGS "$@" "$TEST_IMG" "${TEST_IMG2}" echo $? } @@ -46,25 +46,37 @@ _compare() . ./common.filter . ./common.pattern -_supported_fmt raw qcow qcow2 qed +_supported_fmt raw qcow qcow2 qed luks _supported_proto file _supported_os Linux +# Remove once all tests are fixed to use TEST_IMG_FILE +# correctly and common.rc sets it unconditionally +test -z "$TEST_IMG_FILE" && TEST_IMG_FILE=$TEST_IMG + # Setup test basic parameters TEST_IMG2=$TEST_IMG.2 +TEST_IMG_FILE2=$TEST_IMG_FILE.2 CLUSTER_SIZE=4096 -size=1024M +size=128M _make_test_img $size io_pattern write 524288 $CLUSTER_SIZE $CLUSTER_SIZE 4 45 # Compare identical images -cp "$TEST_IMG" "${TEST_IMG2}" +cp "$TEST_IMG_FILE" "${TEST_IMG_FILE2}" _compare _compare -q # Compare images with different size -$QEMU_IMG resize -f $IMGFMT "$TEST_IMG" +512M +if [ "$IMGOPTSSYNTAX" = "true" ]; then + $QEMU_IMG resize $QEMU_IMG_EXTRA_ARGS "$TEST_IMG" +32M +else + $QEMU_IMG resize -f $IMGFMT "$TEST_IMG" +32M +fi +# Ensure extended space is zero-initialized +$QEMU_IO "$TEST_IMG" -c "write -z $size 32M" | _filter_qemu_io + _compare _compare -s @@ -77,7 +89,7 @@ _compare # Test unaligned case of mismatch offsets in allocated clusters _make_test_img $size io_pattern write 0 512 0 1 100 -cp "$TEST_IMG" "$TEST_IMG2" +cp "$TEST_IMG_FILE" "$TEST_IMG_FILE2" io_pattern write 512 512 0 1 101 _compare diff --git a/tests/qemu-iotests/048.out b/tests/qemu-iotests/048.out index 57100dc453..0bcf6635a1 100644 --- a/tests/qemu-iotests/048.out +++ b/tests/qemu-iotests/048.out @@ -1,5 +1,5 @@ QA output created by 048 -Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824 +Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728 === IO: pattern 45 wrote 4096/4096 bytes at offset 524288 4 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) @@ -13,6 +13,8 @@ Images are identical. 0 0 Image resized. +wrote 33554432/33554432 bytes at offset 134217728 +32 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) Warning: Image size mismatch! Images are identical. 0 @@ -28,7 +30,7 @@ wrote 4096/4096 bytes at offset 0 4 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) Content mismatch at offset 0! 1 -Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824 +Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728 === IO: pattern 100 wrote 512/512 bytes at offset 0 512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) diff --git a/tests/qemu-iotests/052 b/tests/qemu-iotests/052 index 4b647242d2..842eaced3b 100755 --- a/tests/qemu-iotests/052 +++ b/tests/qemu-iotests/052 @@ -48,6 +48,10 @@ size=128M _make_test_img $size echo +echo "== initializing whole image ==" +$QEMU_IO -c "write -z 0 $size" "$TEST_IMG" | _filter_qemu_io + +echo echo "== reading whole image ==" $QEMU_IO -s -c "read 0 $size" "$TEST_IMG" | _filter_qemu_io diff --git a/tests/qemu-iotests/052.out b/tests/qemu-iotests/052.out index 9dab51c0e8..a377d3028d 100644 --- a/tests/qemu-iotests/052.out +++ b/tests/qemu-iotests/052.out @@ -1,6 +1,10 @@ QA output created by 052 Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728 +== initializing whole image == +wrote 134217728/134217728 bytes at offset 0 +128 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) + == reading whole image == read 134217728/134217728 bytes at offset 0 128 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) diff --git a/tests/qemu-iotests/061.out b/tests/qemu-iotests/061.out index a03732e19c..a431b7f305 100644 --- a/tests/qemu-iotests/061.out +++ b/tests/qemu-iotests/061.out @@ -58,9 +58,9 @@ Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864 wrote 131072/131072 bytes at offset 0 128 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) ./common.config: Killed ( if [ "${VALGRIND_QEMU}" == "y" ]; then - exec valgrind --log-file="${VALGRIND_LOGFILE}" --error-exitcode=99 "$QEMU_IO_PROG" $QEMU_IO_OPTIONS "$@"; + exec valgrind --log-file="${VALGRIND_LOGFILE}" --error-exitcode=99 "$QEMU_IO_PROG" $QEMU_IO_ARGS "$@"; else - exec "$QEMU_IO_PROG" $QEMU_IO_OPTIONS "$@"; + exec "$QEMU_IO_PROG" $QEMU_IO_ARGS "$@"; fi ) magic 0x514649fb version 3 @@ -220,9 +220,9 @@ Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864 wrote 131072/131072 bytes at offset 0 128 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) ./common.config: Killed ( if [ "${VALGRIND_QEMU}" == "y" ]; then - exec valgrind --log-file="${VALGRIND_LOGFILE}" --error-exitcode=99 "$QEMU_IO_PROG" $QEMU_IO_OPTIONS "$@"; + exec valgrind --log-file="${VALGRIND_LOGFILE}" --error-exitcode=99 "$QEMU_IO_PROG" $QEMU_IO_ARGS "$@"; else - exec "$QEMU_IO_PROG" $QEMU_IO_OPTIONS "$@"; + exec "$QEMU_IO_PROG" $QEMU_IO_ARGS "$@"; fi ) magic 0x514649fb version 3 diff --git a/tests/qemu-iotests/083 b/tests/qemu-iotests/083 index bc724ae058..bff9360048 100755 --- a/tests/qemu-iotests/083 +++ b/tests/qemu-iotests/083 @@ -43,7 +43,7 @@ choose_tcp_port() { wait_for_tcp_port() { while ! (netstat --tcp --listening --numeric | \ - grep "$1.*0\\.0\\.0\\.0:\\*.*LISTEN") 2>&1 >/dev/null; do + grep "$1.*0\\.0\\.0\\.0:\\*.*LISTEN") >/dev/null 2>&1; do sleep 0.1 done } @@ -70,7 +70,7 @@ EOF nbd_url="nbd:127.0.0.1:$port:exportname=foo" fi - $PYTHON nbd-fault-injector.py $extra_args "127.0.0.1:$port" "$TEST_DIR/nbd-fault-injector.conf" 2>&1 >/dev/null & + $PYTHON nbd-fault-injector.py $extra_args "127.0.0.1:$port" "$TEST_DIR/nbd-fault-injector.conf" >/dev/null 2>&1 & wait_for_tcp_port "127\\.0\\.0\\.1:$port" $QEMU_IO -c "read 0 512" "$nbd_url" 2>&1 | _filter_qemu_io | _filter_nbd diff --git a/tests/qemu-iotests/100 b/tests/qemu-iotests/100 index 5b2fb33330..e66db07982 100755 --- a/tests/qemu-iotests/100 +++ b/tests/qemu-iotests/100 @@ -47,6 +47,7 @@ size=128M echo echo "== Single request ==" _make_test_img $size +$QEMU_IO -c "write -z 0 8k" "$TEST_IMG" | _filter_qemu_io $QEMU_IO -c "multiwrite 0 4k" "$TEST_IMG" | _filter_qemu_io echo @@ -59,6 +60,7 @@ _cleanup_test_img echo echo "== Sequential requests ==" _make_test_img $size +$QEMU_IO -c "write -z 0 12k" "$TEST_IMG" | _filter_qemu_io $QEMU_IO -c "multiwrite 0 4k ; 4k 4k" "$TEST_IMG" | _filter_qemu_io echo @@ -72,6 +74,7 @@ _cleanup_test_img echo echo "== Superset overlapping requests ==" _make_test_img $size +$QEMU_IO -c "write -z 0 8k" "$TEST_IMG" | _filter_qemu_io $QEMU_IO -c "multiwrite 0 4k ; 1k 2k" "$TEST_IMG" | _filter_qemu_io echo @@ -87,6 +90,7 @@ _cleanup_test_img echo echo "== Subset overlapping requests ==" _make_test_img $size +$QEMU_IO -c "write -z 0 8k" "$TEST_IMG" | _filter_qemu_io $QEMU_IO -c "multiwrite 1k 2k ; 0k 4k" "$TEST_IMG" | _filter_qemu_io echo @@ -102,6 +106,7 @@ _cleanup_test_img echo echo "== Head overlapping requests ==" _make_test_img $size +$QEMU_IO -c "write -z 0 8k" "$TEST_IMG" | _filter_qemu_io $QEMU_IO -c "multiwrite 0k 2k ; 0k 4k" "$TEST_IMG" | _filter_qemu_io echo @@ -116,6 +121,7 @@ _cleanup_test_img echo echo "== Tail overlapping requests ==" _make_test_img $size +$QEMU_IO -c "write -z 0 8k" "$TEST_IMG" | _filter_qemu_io $QEMU_IO -c "multiwrite 2k 2k ; 0k 4k" "$TEST_IMG" | _filter_qemu_io echo @@ -130,6 +136,7 @@ _cleanup_test_img echo echo "== Disjoint requests ==" _make_test_img $size +$QEMU_IO -c "write -z 0 72k" "$TEST_IMG" | _filter_qemu_io $QEMU_IO -c "multiwrite 0 4k ; 64k 4k" "$TEST_IMG" | _filter_qemu_io echo diff --git a/tests/qemu-iotests/100.out b/tests/qemu-iotests/100.out index 05649038d9..a44cae40db 100644 --- a/tests/qemu-iotests/100.out +++ b/tests/qemu-iotests/100.out @@ -2,6 +2,8 @@ QA output created by 100 == Single request == Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728 +wrote 8192/8192 bytes at offset 0 +8 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) wrote 4096/4096 bytes at offset 0 4 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) @@ -13,6 +15,8 @@ read 4096/4096 bytes at offset 4096 == Sequential requests == Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728 +wrote 12288/12288 bytes at offset 0 +12 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) wrote 8192/8192 bytes at offset 0 8 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) @@ -26,6 +30,8 @@ read 4096/4096 bytes at offset 8192 == Superset overlapping requests == Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728 +wrote 8192/8192 bytes at offset 0 +8 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) wrote 6144/6144 bytes at offset 0 6 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) @@ -39,6 +45,8 @@ read 4096/4096 bytes at offset 4096 == Subset overlapping requests == Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728 +wrote 8192/8192 bytes at offset 0 +8 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) wrote 6144/6144 bytes at offset 1024 6 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) @@ -52,6 +60,8 @@ read 4096/4096 bytes at offset 4096 == Head overlapping requests == Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728 +wrote 8192/8192 bytes at offset 0 +8 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) wrote 6144/6144 bytes at offset 0 6 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) @@ -63,6 +73,8 @@ read 4096/4096 bytes at offset 4096 == Tail overlapping requests == Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728 +wrote 8192/8192 bytes at offset 0 +8 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) wrote 6144/6144 bytes at offset 2048 6 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) @@ -74,6 +86,8 @@ read 4096/4096 bytes at offset 4096 == Disjoint requests == Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728 +wrote 73728/73728 bytes at offset 0 +72 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) wrote 8192/8192 bytes at offset 0 8 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) diff --git a/tests/qemu-iotests/137.out b/tests/qemu-iotests/137.out index 88c702cf77..c0e753483b 100644 --- a/tests/qemu-iotests/137.out +++ b/tests/qemu-iotests/137.out @@ -32,9 +32,9 @@ Unsupported value 'blubb' for qcow2 option 'overlap-check'. Allowed are any of t wrote 512/512 bytes at offset 0 512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) ./common.config: Killed ( if [ "${VALGRIND_QEMU}" == "y" ]; then - exec valgrind --log-file="${VALGRIND_LOGFILE}" --error-exitcode=99 "$QEMU_IO_PROG" $QEMU_IO_OPTIONS "$@"; + exec valgrind --log-file="${VALGRIND_LOGFILE}" --error-exitcode=99 "$QEMU_IO_PROG" $QEMU_IO_ARGS "$@"; else - exec "$QEMU_IO_PROG" $QEMU_IO_OPTIONS "$@"; + exec "$QEMU_IO_PROG" $QEMU_IO_ARGS "$@"; fi ) incompatible_features 0x0 Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864 diff --git a/tests/qemu-iotests/common b/tests/qemu-iotests/common index 49e1931129..d60ea2ce3c 100644 --- a/tests/qemu-iotests/common +++ b/tests/qemu-iotests/common @@ -53,6 +53,8 @@ export QEMU_IO_OPTIONS="" export CACHEMODE_IS_DEFAULT=true export QEMU_OPTIONS="-nodefaults" export VALGRIND_QEMU= +export IMGKEYSECRET= +export IMGOPTSSYNTAX=false for r do @@ -207,6 +209,13 @@ testlist options xpand=false ;; + -luks) + IMGOPTSSYNTAX=true + IMGFMT=luks + IMGKEYSECRET=123456 + xpand=false + ;; + -qed) IMGFMT=qed xpand=false @@ -399,7 +408,11 @@ BEGIN { for (t='$start'; t<='$end'; t++) printf "%03d\n",t }' \ done # Set qemu-io cache mode with $CACHEMODE we have -QEMU_IO_OPTIONS="$QEMU_IO_OPTIONS -f $IMGFMT --cache $CACHEMODE" +if [ "$IMGOPTSSYNTAX" = "true" ]; then + QEMU_IO_OPTIONS="$QEMU_IO_OPTIONS --cache $CACHEMODE" +else + QEMU_IO_OPTIONS="$QEMU_IO_OPTIONS -f $IMGFMT --cache $CACHEMODE" +fi # Set default options for qemu-img create -o if they were not specified _set_default_imgopts diff --git a/tests/qemu-iotests/common.config b/tests/qemu-iotests/common.config index f824651bac..f6384fbae7 100644 --- a/tests/qemu-iotests/common.config +++ b/tests/qemu-iotests/common.config @@ -123,12 +123,19 @@ _qemu_img_wrapper() _qemu_io_wrapper() { local VALGRIND_LOGFILE="${TEST_DIR}"/$$.valgrind + local QEMU_IO_ARGS="$QEMU_IO_OPTIONS" + if [ "$IMGOPTSSYNTAX" = "true" ]; then + QEMU_IO_ARGS="--image-opts $QEMU_IO_ARGS" + if [ -n "$IMGKEYSECRET" ]; then + QEMU_IO_ARGS="--object secret,id=keysec0,data=$IMGKEYSECRET $QEMU_IO_ARGS" + fi + fi local RETVAL ( if [ "${VALGRIND_QEMU}" == "y" ]; then - exec valgrind --log-file="${VALGRIND_LOGFILE}" --error-exitcode=99 "$QEMU_IO_PROG" $QEMU_IO_OPTIONS "$@" + exec valgrind --log-file="${VALGRIND_LOGFILE}" --error-exitcode=99 "$QEMU_IO_PROG" $QEMU_IO_ARGS "$@" else - exec "$QEMU_IO_PROG" $QEMU_IO_OPTIONS "$@" + exec "$QEMU_IO_PROG" $QEMU_IO_ARGS "$@" fi ) RETVAL=$? @@ -154,6 +161,16 @@ export QEMU_IMG=_qemu_img_wrapper export QEMU_IO=_qemu_io_wrapper export QEMU_NBD=_qemu_nbd_wrapper +QEMU_IMG_EXTRA_ARGS= +if [ "$IMGOPTSSYNTAX" = "true" ]; then + QEMU_IMG_EXTRA_ARGS="--image-opts $QEMU_IMG_EXTRA_ARGS" + if [ -n "$IMGKEYSECRET" ]; then + QEMU_IMG_EXTRA_ARGS="--object secret,id=keysec0,data=$IMGKEYSECRET $QEMU_IMG_EXTRA_ARGS" + fi +fi +export QEMU_IMG_EXTRA_ARGS + + default_machine=$($QEMU -machine help | sed -n '/(default)/ s/ .*//p') default_alias_machine=$($QEMU -machine help | \ sed -n "/(alias of $default_machine)/ { s/ .*//p; q; }") diff --git a/tests/qemu-iotests/common.filter b/tests/qemu-iotests/common.filter index 8a6e1b57c1..7853dbbfdc 100644 --- a/tests/qemu-iotests/common.filter +++ b/tests/qemu-iotests/common.filter @@ -92,12 +92,14 @@ _filter_img_create() -e "s# zeroed_grain=\\(on\\|off\\)##g" \ -e "s# subformat='[^']*'##g" \ -e "s# adapter_type='[^']*'##g" \ + -e "s# hwversion=[^ ]*##g" \ -e "s# lazy_refcounts=\\(on\\|off\\)##g" \ -e "s# block_size=[0-9]\\+##g" \ -e "s# block_state_zero=\\(on\\|off\\)##g" \ -e "s# log_size=[0-9]\\+##g" \ -e "s/archipelago:a/TEST_DIR\//g" \ - -e "s# refcount_bits=[0-9]\\+##g" + -e "s# refcount_bits=[0-9]\\+##g" \ + -e "s# key-secret=[a-zA-Z0-9]\\+##g" } _filter_img_info() @@ -115,6 +117,7 @@ _filter_img_info() -e "/zeroed_grain: \\(on\\|off\\)/d" \ -e "/subformat: '[^']*'/d" \ -e "/adapter_type: '[^']*'/d" \ + -e "/hwversion: '[^']*'/d" \ -e "/lazy_refcounts: \\(on\\|off\\)/d" \ -e "/block_size: [0-9]\\+/d" \ -e "/block_state_zero: \\(on\\|off\\)/d" \ diff --git a/tests/qemu-iotests/common.rc b/tests/qemu-iotests/common.rc index 5249ec5922..306b00c210 100644 --- a/tests/qemu-iotests/common.rc +++ b/tests/qemu-iotests/common.rc @@ -53,21 +53,45 @@ fi # make sure we have a standard umask umask 022 -if [ "$IMGPROTO" = "file" ]; then - TEST_IMG=$TEST_DIR/t.$IMGFMT -elif [ "$IMGPROTO" = "nbd" ]; then - TEST_IMG_FILE=$TEST_DIR/t.$IMGFMT - TEST_IMG="nbd:127.0.0.1:10810" -elif [ "$IMGPROTO" = "ssh" ]; then - TEST_IMG_FILE=$TEST_DIR/t.$IMGFMT - TEST_IMG="ssh://127.0.0.1$TEST_IMG_FILE" -elif [ "$IMGPROTO" = "nfs" ]; then - TEST_DIR="nfs://127.0.0.1/$TEST_DIR" - TEST_IMG=$TEST_DIR/t.$IMGFMT -elif [ "$IMGPROTO" = "archipelago" ]; then - TEST_IMG="archipelago:at.$IMGFMT" +if [ "$IMGOPTSSYNTAX" = "true" ]; then + DRIVER="driver=$IMGFMT" + if [ "$IMGFMT" = "luks" ]; then + DRIVER="$DRIVER,key-secret=keysec0" + fi + if [ "$IMGPROTO" = "file" ]; then + TEST_IMG_FILE=$TEST_DIR/t.$IMGFMT + TEST_IMG="$DRIVER,file.filename=$TEST_DIR/t.$IMGFMT" + elif [ "$IMGPROTO" = "nbd" ]; then + TEST_IMG_FILE=$TEST_DIR/t.$IMGFMT + TEST_IMG="$DRIVER,file.driver=nbd,file.host=127.0.0.1,file.port=10810" + elif [ "$IMGPROTO" = "ssh" ]; then + TEST_IMG_FILE=$TEST_DIR/t.$IMGFMT + TEST_IMG="$DRIVER,file.driver=ssh,file.host=127.0.0.1,file.path=$TEST_IMG_FILE" + elif [ "$IMGPROTO" = "nfs" ]; then + TEST_DIR="$DRIVER,file.driver=nfs,file.filename=nfs://127.0.0.1/$TEST_DIR" + TEST_IMG=$TEST_DIR_OPTS/t.$IMGFMT + elif [ "$IMGPROTO" = "archipelago" ]; then + TEST_IMG="$DRIVER,file.driver=archipelago,file.volume=:at.$IMGFMT" + else + TEST_IMG="$DRIVER,file.driver=$IMGPROTO,file.filename=$TEST_DIR/t.$IMGFMT" + fi else - TEST_IMG=$IMGPROTO:$TEST_DIR/t.$IMGFMT + if [ "$IMGPROTO" = "file" ]; then + TEST_IMG=$TEST_DIR/t.$IMGFMT + elif [ "$IMGPROTO" = "nbd" ]; then + TEST_IMG_FILE=$TEST_DIR/t.$IMGFMT + TEST_IMG="nbd:127.0.0.1:10810" + elif [ "$IMGPROTO" = "ssh" ]; then + TEST_IMG_FILE=$TEST_DIR/t.$IMGFMT + TEST_IMG="ssh://127.0.0.1$TEST_IMG_FILE" + elif [ "$IMGPROTO" = "nfs" ]; then + TEST_DIR="nfs://127.0.0.1/$TEST_DIR" + TEST_IMG=$TEST_DIR/t.$IMGFMT + elif [ "$IMGPROTO" = "archipelago" ]; then + TEST_IMG="archipelago:at.$IMGFMT" + else + TEST_IMG=$IMGPROTO:$TEST_DIR/t.$IMGFMT + fi fi _optstr_add() @@ -108,6 +132,7 @@ _make_test_img() local img_name="" local use_backing=0 local backing_file="" + local object_options="" if [ -n "$TEST_IMG_FILE" ]; then img_name=$TEST_IMG_FILE @@ -118,6 +143,10 @@ _make_test_img() if [ -n "$IMGOPTS" ]; then optstr=$(_optstr_add "$optstr" "$IMGOPTS") fi + if [ -n "$IMGKEYSECRET" ]; then + object_options="--object secret,id=keysec0,data=$IMGKEYSECRET" + optstr=$(_optstr_add "$optstr" "key-secret=keysec0") + fi if [ "$1" = "-b" ]; then use_backing=1 @@ -135,9 +164,9 @@ _make_test_img() # XXX(hch): have global image options? ( if [ $use_backing = 1 ]; then - $QEMU_IMG create -f $IMGFMT $extra_img_options -b "$backing_file" "$img_name" $image_size 2>&1 + $QEMU_IMG create $object_options -f $IMGFMT $extra_img_options -b "$backing_file" "$img_name" $image_size 2>&1 else - $QEMU_IMG create -f $IMGFMT $extra_img_options "$img_name" $image_size 2>&1 + $QEMU_IMG create $object_options -f $IMGFMT $extra_img_options "$img_name" $image_size 2>&1 fi ) | _filter_img_create @@ -199,7 +228,13 @@ _cleanup_test_img() _check_test_img() { - $QEMU_IMG check "$@" -f $IMGFMT "$TEST_IMG" 2>&1 | _filter_testdir | \ + ( + if [ "$IMGOPTSSYNTAX" = "true" ]; then + $QEMU_IMG check $QEMU_IMG_EXTRA_ARGS "$@" "$TEST_IMG" 2>&1 + else + $QEMU_IMG check "$@" -f $IMGFMT "$TEST_IMG" 2>&1 + fi + ) | _filter_testdir | \ sed -e '/allocated.*fragmented.*compressed clusters/d' \ -e 's/qemu-img: This image format does not support checks/No errors were found on the image./' \ -e '/Image end offset: [0-9]\+/d' diff --git a/tests/qemu-iotests/iotests.py b/tests/qemu-iotests/iotests.py index 56f988ab3d..1687c33efd 100644 --- a/tests/qemu-iotests/iotests.py +++ b/tests/qemu-iotests/iotests.py @@ -47,7 +47,7 @@ if os.environ.get('QEMU_OPTIONS'): imgfmt = os.environ.get('IMGFMT', 'raw') imgproto = os.environ.get('IMGPROTO', 'file') -test_dir = os.environ.get('TEST_DIR', '/var/tmp') +test_dir = os.environ.get('TEST_DIR') output_dir = os.environ.get('OUTPUT_DIR', '.') cachemode = os.environ.get('CACHEMODE') qemu_default_machine = os.environ.get('QEMU_DEFAULT_MACHINE') @@ -461,6 +461,14 @@ def verify_quorum(): def main(supported_fmts=[], supported_oses=['linux']): '''Run tests''' + # We are using TEST_DIR and QEMU_DEFAULT_MACHINE as proxies to + # indicate that we're not being run via "check". There may be + # other things set up by "check" that individual test cases rely + # on. + if test_dir is None or qemu_default_machine is None: + sys.stderr.write('Please run this test via the "check" script\n') + sys.exit(os.EX_USAGE) + debug = '-d' in sys.argv verbosity = 1 verify_image_format(supported_fmts) diff --git a/trace-events b/trace-events index 8350743878..b588091b6c 100644 --- a/trace-events +++ b/trace-events @@ -74,7 +74,6 @@ bdrv_co_copy_on_readv(void *bs, int64_t sector_num, int nb_sector) "bs %p sector bdrv_co_readv_no_serialising(void *bs, int64_t sector_num, int nb_sector) "bs %p sector_num %"PRId64" nb_sectors %d" bdrv_co_writev(void *bs, int64_t sector_num, int nb_sector) "bs %p sector_num %"PRId64" nb_sectors %d" bdrv_co_write_zeroes(void *bs, int64_t sector_num, int nb_sector, int flags) "bs %p sector_num %"PRId64" nb_sectors %d flags %#x" -bdrv_co_io_em(void *bs, int64_t sector_num, int nb_sectors, int is_write, void *acb) "bs %p sector_num %"PRId64" nb_sectors %d is_write %d acb %p" bdrv_co_do_copy_on_readv(void *bs, int64_t sector_num, int nb_sectors, int64_t cluster_sector_num, int cluster_nb_sectors) "bs %p sector_num %"PRId64" nb_sectors %d cluster_sector_num %"PRId64" cluster_nb_sectors %d" # block/stream.c @@ -119,7 +118,7 @@ virtio_blk_req_complete(void *req, int status) "req %p status %d" virtio_blk_rw_complete(void *req, int ret) "req %p ret %d" virtio_blk_handle_write(void *req, uint64_t sector, size_t nsectors) "req %p sector %"PRIu64" nsectors %zu" virtio_blk_handle_read(void *req, uint64_t sector, size_t nsectors) "req %p sector %"PRIu64" nsectors %zu" -virtio_blk_submit_multireq(void *mrb, int start, int num_reqs, uint64_t sector, size_t nsectors, bool is_write) "mrb %p start %d num_reqs %d sector %"PRIu64" nsectors %zu is_write %d" +virtio_blk_submit_multireq(void *mrb, int start, int num_reqs, uint64_t offset, size_t size, bool is_write) "mrb %p start %d num_reqs %d offset %"PRIu64" size %zu is_write %d" # hw/block/dataplane/virtio-blk.c virtio_blk_data_plane_start(void *s) "dataplane %p" |