Block layer patches

-----BEGIN PGP SIGNATURE-----
 
 iQIcBAABAgAGBQJZ8dz+AAoJEH8JsnLIjy/WuxUP/Rt4LpvwO8d22z0EOAbXkE4z
 9KD9AdFvr5lLc+ZkwE29txsN6paZ9LGFpO5Nd1XnkbbAMLHarC0H+chioF861pei
 WZ38PLRWvTM8FCP3/pGAwcHYQ4rOMdYWqx3EQNPS+wfypl6nrBnXMJhmia4C2Yu7
 6+jhJ6xh49SvjgixvMVuhwdL3DWyX2t/qdAif3It6CWY3BgQWltSmIlpKO/6OqE4
 7KIaTSHwz7Fi3oWKZLIXiuJ/W4hruMb3J+beAHS/yKPSX3yQ5PwlMz8NI86SF8JR
 e3veiXHrNLySfVLi34A9AsLL/KLxyXk8we/PHGB0MEzTkFU8FiRPaEPoZW9Balle
 /2Xp4w4DSQXgWnfNa2Yn5ShwHVgEbvmRxwFT1LoYch+9k0FREoueiPHrlWKFkA1p
 Rgg12h2C1fJlMMMkg2fr6JQ09fkINnMTHJgQ+T235affTTPFLoZKlBYYeU2VjANP
 G41MLzHUuoGMxcZgQ/nyzVrvI3muI8fPU8karUwFGmpQoF0XWuD/HlS0GRY5xVnZ
 Cmo4oTNJK3DJHgDDoYp7/SFy95VGF0Ui1Zp+PtV/HeLKwxjmaj2wdJFpAb7k61c1
 /Ss3K+pF6Qkn1x5SlI8U9U1So9BOkjqE0F2TjS04UYzlpFPk1Bm+tfuL6sGMn8AJ
 et4jgueuBzux/cszMS/g
 =4jsy
 -----END PGP SIGNATURE-----

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

Block layer patches

# gpg: Signature made Thu 26 Oct 2017 14:02:54 BST
# gpg:                using RSA key 0x7F09B272C88F2FD6
# gpg: Good signature from "Kevin Wolf <kwolf@redhat.com>"
# Primary key fingerprint: DC3D EB15 9A9A F95D 3D74  56FE 7F09 B272 C88F 2FD6

* remotes/kevin/tags/for-upstream: (35 commits)
  iotests: Add cluster_size=64k to 125
  qcow2: Always execute preallocate() in a coroutine
  qcow2: Fix unaligned preallocated truncation
  qcow2: Emit errp when truncating the image tail
  iotests: Filter actual image size in 184 and 191
  iotests: Pull _filter_actual_image_size from 67/87
  iotests: Add test for dataplane mirroring
  qcow2: Use BDRV_SECTOR_BITS instead of its literal value
  qemu-img.1: Image invalidation on qemu-img commit
  qemu-io: Relax 'alloc' now that block-status doesn't assert
  qcow2: Reduce is_zero() rounding
  block: Reduce bdrv_aligned_preadv() rounding
  block: Align block status requests
  qemu-img: Change img_compare() to be byte-based
  qemu-img: Change img_rebase() to be byte-based
  qemu-img: Change compare_sectors() to be byte-based
  qemu-img: Change check_empty_sectors() to byte-based
  qemu-img: Drop redundant error message in compare
  qemu-img: Add find_nonzero()
  qemu-img: Speed up compare on pre-allocated larger file
  ...

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
master
Peter Maydell 2017-10-27 09:29:05 +01:00
commit 46f63e5b88
27 changed files with 1103 additions and 544 deletions

View File

@ -2245,7 +2245,8 @@ int bdrv_open_backing_file(BlockDriverState *bs, QDict *parent_options,
goto free_exit;
}
if (bs->backing_format[0] != '\0' && !qdict_haskey(options, "driver")) {
if (!reference &&
bs->backing_format[0] != '\0' && !qdict_haskey(options, "driver")) {
qdict_put_str(options, "driver", bs->backing_format);
}

View File

@ -627,6 +627,17 @@ static int coroutine_fn blkdebug_co_pdiscard(BlockDriverState *bs,
return bdrv_co_pdiscard(bs->file->bs, offset, bytes);
}
static int64_t coroutine_fn blkdebug_co_get_block_status(
BlockDriverState *bs, int64_t sector_num, int nb_sectors, int *pnum,
BlockDriverState **file)
{
assert(QEMU_IS_ALIGNED(sector_num | nb_sectors,
DIV_ROUND_UP(bs->bl.request_alignment,
BDRV_SECTOR_SIZE)));
return bdrv_co_get_block_status_from_file(bs, sector_num, nb_sectors,
pnum, file);
}
static void blkdebug_close(BlockDriverState *bs)
{
BDRVBlkdebugState *s = bs->opaque;
@ -896,7 +907,7 @@ static BlockDriver bdrv_blkdebug = {
.bdrv_co_flush_to_disk = blkdebug_co_flush,
.bdrv_co_pwrite_zeroes = blkdebug_co_pwrite_zeroes,
.bdrv_co_pdiscard = blkdebug_co_pdiscard,
.bdrv_co_get_block_status = bdrv_co_get_block_status_from_file,
.bdrv_co_get_block_status = blkdebug_co_get_block_status,
.bdrv_debug_event = blkdebug_debug_event,
.bdrv_debug_breakpoint = blkdebug_debug_breakpoint,

View File

@ -469,9 +469,9 @@ static void mark_request_serialising(BdrvTrackedRequest *req, uint64_t align)
* Round a region to cluster boundaries
*/
void bdrv_round_to_clusters(BlockDriverState *bs,
int64_t offset, unsigned int bytes,
int64_t offset, int64_t bytes,
int64_t *cluster_offset,
unsigned int *cluster_bytes)
int64_t *cluster_bytes)
{
BlockDriverInfo bdi;
@ -716,39 +716,37 @@ int bdrv_pwrite_zeroes(BdrvChild *child, int64_t offset,
*/
int bdrv_make_zero(BdrvChild *child, BdrvRequestFlags flags)
{
int64_t target_sectors, ret, nb_sectors, sector_num = 0;
int ret;
int64_t target_size, bytes, offset = 0;
BlockDriverState *bs = child->bs;
BlockDriverState *file;
int n;
target_sectors = bdrv_nb_sectors(bs);
if (target_sectors < 0) {
return target_sectors;
target_size = bdrv_getlength(bs);
if (target_size < 0) {
return target_size;
}
for (;;) {
nb_sectors = MIN(target_sectors - sector_num, BDRV_REQUEST_MAX_SECTORS);
if (nb_sectors <= 0) {
bytes = MIN(target_size - offset, BDRV_REQUEST_MAX_BYTES);
if (bytes <= 0) {
return 0;
}
ret = bdrv_get_block_status(bs, sector_num, nb_sectors, &n, &file);
ret = bdrv_block_status(bs, offset, bytes, &bytes, NULL, NULL);
if (ret < 0) {
error_report("error getting block status at sector %" PRId64 ": %s",
sector_num, strerror(-ret));
error_report("error getting block status at offset %" PRId64 ": %s",
offset, strerror(-ret));
return ret;
}
if (ret & BDRV_BLOCK_ZERO) {
sector_num += n;
offset += bytes;
continue;
}
ret = bdrv_pwrite_zeroes(child, sector_num << BDRV_SECTOR_BITS,
n << BDRV_SECTOR_BITS, flags);
ret = bdrv_pwrite_zeroes(child, offset, bytes, flags);
if (ret < 0) {
error_report("error writing zeroes at sector %" PRId64 ": %s",
sector_num, strerror(-ret));
error_report("error writing zeroes at offset %" PRId64 ": %s",
offset, strerror(-ret));
return ret;
}
sector_num += n;
offset += bytes;
}
}
@ -970,7 +968,7 @@ static int coroutine_fn bdrv_co_do_copy_on_readv(BdrvChild *child,
struct iovec iov;
QEMUIOVector local_qiov;
int64_t cluster_offset;
unsigned int cluster_bytes;
int64_t cluster_bytes;
size_t skip_bytes;
int ret;
int max_transfer = MIN_NON_ZERO(bs->bl.max_transfer,
@ -1126,18 +1124,14 @@ static int coroutine_fn bdrv_aligned_preadv(BdrvChild *child,
}
if (flags & BDRV_REQ_COPY_ON_READ) {
/* TODO: Simplify further once bdrv_is_allocated no longer
* requires sector alignment */
int64_t start = QEMU_ALIGN_DOWN(offset, BDRV_SECTOR_SIZE);
int64_t end = QEMU_ALIGN_UP(offset + bytes, BDRV_SECTOR_SIZE);
int64_t pnum;
ret = bdrv_is_allocated(bs, start, end - start, &pnum);
ret = bdrv_is_allocated(bs, offset, bytes, &pnum);
if (ret < 0) {
goto out;
}
if (!ret || pnum != end - start) {
if (!ret || pnum != bytes) {
ret = bdrv_co_do_copy_on_readv(child, offset, bytes, qiov);
goto out;
}
@ -1767,16 +1761,18 @@ int bdrv_flush_all(void)
}
typedef struct BdrvCoGetBlockStatusData {
typedef struct BdrvCoBlockStatusData {
BlockDriverState *bs;
BlockDriverState *base;
bool want_zero;
int64_t offset;
int64_t bytes;
int64_t *pnum;
int64_t *map;
BlockDriverState **file;
int64_t sector_num;
int nb_sectors;
int *pnum;
int64_t ret;
int ret;
bool done;
} BdrvCoGetBlockStatusData;
} BdrvCoBlockStatusData;
int64_t coroutine_fn bdrv_co_get_block_status_from_file(BlockDriverState *bs,
int64_t sector_num,
@ -1809,99 +1805,157 @@ int64_t coroutine_fn bdrv_co_get_block_status_from_backing(BlockDriverState *bs,
* Drivers not implementing the functionality are assumed to not support
* backing files, hence all their sectors are reported as allocated.
*
* If 'sector_num' is beyond the end of the disk image the return value is
* If 'want_zero' is true, the caller is querying for mapping purposes,
* and the result should include BDRV_BLOCK_OFFSET_VALID and
* BDRV_BLOCK_ZERO where possible; otherwise, the result may omit those
* bits particularly if it allows for a larger value in 'pnum'.
*
* If 'offset' is beyond the end of the disk image the return value is
* BDRV_BLOCK_EOF and 'pnum' is set to 0.
*
* 'pnum' is set to the number of sectors (including and immediately following
* the specified sector) that are known to be in the same
* allocated/unallocated state.
*
* 'nb_sectors' is the max value 'pnum' should be set to. If nb_sectors goes
* 'bytes' is the max value 'pnum' should be set to. If bytes goes
* beyond the end of the disk image it will be clamped; if 'pnum' is set to
* the end of the image, then the returned value will include BDRV_BLOCK_EOF.
*
* If returned value is positive and BDRV_BLOCK_OFFSET_VALID bit is set, 'file'
* points to the BDS which the sector range is allocated in.
* 'pnum' is set to the number of bytes (including and immediately
* following the specified offset) that are easily known to be in the
* same allocated/unallocated state. Note that a second call starting
* at the original offset plus returned pnum may have the same status.
* The returned value is non-zero on success except at end-of-file.
*
* Returns negative errno on failure. Otherwise, if the
* BDRV_BLOCK_OFFSET_VALID bit is set, 'map' and 'file' (if non-NULL) are
* set to the host mapping and BDS corresponding to the guest offset.
*/
static int64_t coroutine_fn bdrv_co_get_block_status(BlockDriverState *bs,
int64_t sector_num,
int nb_sectors, int *pnum,
BlockDriverState **file)
static int coroutine_fn bdrv_co_block_status(BlockDriverState *bs,
bool want_zero,
int64_t offset, int64_t bytes,
int64_t *pnum, int64_t *map,
BlockDriverState **file)
{
int64_t total_sectors;
int64_t n;
int64_t ret, ret2;
int64_t total_size;
int64_t n; /* bytes */
int ret;
int64_t local_map = 0;
BlockDriverState *local_file = NULL;
int64_t aligned_offset, aligned_bytes;
uint32_t align;
*file = NULL;
total_sectors = bdrv_nb_sectors(bs);
if (total_sectors < 0) {
return total_sectors;
assert(pnum);
*pnum = 0;
total_size = bdrv_getlength(bs);
if (total_size < 0) {
ret = total_size;
goto early_out;
}
if (sector_num >= total_sectors) {
*pnum = 0;
return BDRV_BLOCK_EOF;
if (offset >= total_size) {
ret = BDRV_BLOCK_EOF;
goto early_out;
}
if (!nb_sectors) {
*pnum = 0;
return 0;
if (!bytes) {
ret = 0;
goto early_out;
}
n = total_sectors - sector_num;
if (n < nb_sectors) {
nb_sectors = n;
n = total_size - offset;
if (n < bytes) {
bytes = n;
}
if (!bs->drv->bdrv_co_get_block_status) {
*pnum = nb_sectors;
*pnum = bytes;
ret = BDRV_BLOCK_DATA | BDRV_BLOCK_ALLOCATED;
if (sector_num + nb_sectors == total_sectors) {
if (offset + bytes == total_size) {
ret |= BDRV_BLOCK_EOF;
}
if (bs->drv->protocol_name) {
ret |= BDRV_BLOCK_OFFSET_VALID | (sector_num * BDRV_SECTOR_SIZE);
*file = bs;
ret |= BDRV_BLOCK_OFFSET_VALID;
local_map = offset;
local_file = bs;
}
return ret;
goto early_out;
}
bdrv_inc_in_flight(bs);
ret = bs->drv->bdrv_co_get_block_status(bs, sector_num, nb_sectors, pnum,
file);
if (ret < 0) {
*pnum = 0;
goto out;
/* Round out to request_alignment boundaries */
/* TODO: until we have a byte-based driver callback, we also have to
* round out to sectors, even if that is bigger than request_alignment */
align = MAX(bs->bl.request_alignment, BDRV_SECTOR_SIZE);
aligned_offset = QEMU_ALIGN_DOWN(offset, align);
aligned_bytes = ROUND_UP(offset + bytes, align) - aligned_offset;
{
int count; /* sectors */
int64_t longret;
assert(QEMU_IS_ALIGNED(aligned_offset | aligned_bytes,
BDRV_SECTOR_SIZE));
/*
* The contract allows us to return pnum smaller than bytes, even
* if the next query would see the same status; we truncate the
* request to avoid overflowing the driver's 32-bit interface.
*/
longret = bs->drv->bdrv_co_get_block_status(
bs, aligned_offset >> BDRV_SECTOR_BITS,
MIN(INT_MAX, aligned_bytes) >> BDRV_SECTOR_BITS, &count,
&local_file);
if (longret < 0) {
assert(INT_MIN <= longret);
ret = longret;
goto out;
}
if (longret & BDRV_BLOCK_OFFSET_VALID) {
local_map = longret & BDRV_BLOCK_OFFSET_MASK;
}
ret = longret & ~BDRV_BLOCK_OFFSET_MASK;
*pnum = count * BDRV_SECTOR_SIZE;
}
/*
* The driver's result must be a multiple of request_alignment.
* Clamp pnum and adjust map to original request.
*/
assert(QEMU_IS_ALIGNED(*pnum, align) && align > offset - aligned_offset);
*pnum -= offset - aligned_offset;
if (*pnum > bytes) {
*pnum = bytes;
}
if (ret & BDRV_BLOCK_OFFSET_VALID) {
local_map += offset - aligned_offset;
}
if (ret & BDRV_BLOCK_RAW) {
assert(ret & BDRV_BLOCK_OFFSET_VALID && *file);
ret = bdrv_co_get_block_status(*file, ret >> BDRV_SECTOR_BITS,
*pnum, pnum, file);
assert(ret & BDRV_BLOCK_OFFSET_VALID && local_file);
ret = bdrv_co_block_status(local_file, want_zero, local_map,
*pnum, pnum, &local_map, &local_file);
goto out;
}
if (ret & (BDRV_BLOCK_DATA | BDRV_BLOCK_ZERO)) {
ret |= BDRV_BLOCK_ALLOCATED;
} else {
} else if (want_zero) {
if (bdrv_unallocated_blocks_are_zero(bs)) {
ret |= BDRV_BLOCK_ZERO;
} else if (bs->backing) {
BlockDriverState *bs2 = bs->backing->bs;
int64_t nb_sectors2 = bdrv_nb_sectors(bs2);
if (nb_sectors2 >= 0 && sector_num >= nb_sectors2) {
int64_t size2 = bdrv_getlength(bs2);
if (size2 >= 0 && offset >= size2) {
ret |= BDRV_BLOCK_ZERO;
}
}
}
if (*file && *file != bs &&
if (want_zero && local_file && local_file != bs &&
(ret & BDRV_BLOCK_DATA) && !(ret & BDRV_BLOCK_ZERO) &&
(ret & BDRV_BLOCK_OFFSET_VALID)) {
BlockDriverState *file2;
int file_pnum;
int64_t file_pnum;
int ret2;
ret2 = bdrv_co_get_block_status(*file, ret >> BDRV_SECTOR_BITS,
*pnum, &file_pnum, &file2);
ret2 = bdrv_co_block_status(local_file, want_zero, local_map,
*pnum, &file_pnum, NULL, NULL);
if (ret2 >= 0) {
/* Ignore errors. This is just providing extra information, it
* is useful but not necessary.
@ -1924,26 +1978,36 @@ static int64_t coroutine_fn bdrv_co_get_block_status(BlockDriverState *bs,
out:
bdrv_dec_in_flight(bs);
if (ret >= 0 && sector_num + *pnum == total_sectors) {
if (ret >= 0 && offset + *pnum == total_size) {
ret |= BDRV_BLOCK_EOF;
}
early_out:
if (file) {
*file = local_file;
}
if (map) {
*map = local_map;
}
return ret;
}
static int64_t coroutine_fn bdrv_co_get_block_status_above(BlockDriverState *bs,
BlockDriverState *base,
int64_t sector_num,
int nb_sectors,
int *pnum,
BlockDriverState **file)
static int coroutine_fn bdrv_co_block_status_above(BlockDriverState *bs,
BlockDriverState *base,
bool want_zero,
int64_t offset,
int64_t bytes,
int64_t *pnum,
int64_t *map,
BlockDriverState **file)
{
BlockDriverState *p;
int64_t ret = 0;
int ret = 0;
bool first = true;
assert(bs != base);
for (p = bs; p != base; p = backing_bs(p)) {
ret = bdrv_co_get_block_status(p, sector_num, nb_sectors, pnum, file);
ret = bdrv_co_block_status(p, want_zero, offset, bytes, pnum, map,
file);
if (ret < 0) {
break;
}
@ -1954,94 +2018,94 @@ static int64_t coroutine_fn bdrv_co_get_block_status_above(BlockDriverState *bs,
* unallocated length we learned from an earlier
* iteration.
*/
*pnum = nb_sectors;
*pnum = bytes;
}
if (ret & (BDRV_BLOCK_ZERO | BDRV_BLOCK_DATA)) {
break;
}
/* [sector_num, pnum] unallocated on this layer, which could be only
* the first part of [sector_num, nb_sectors]. */
nb_sectors = MIN(nb_sectors, *pnum);
/* [offset, pnum] unallocated on this layer, which could be only
* the first part of [offset, bytes]. */
bytes = MIN(bytes, *pnum);
first = false;
}
return ret;
}
/* Coroutine wrapper for bdrv_get_block_status_above() */
static void coroutine_fn bdrv_get_block_status_above_co_entry(void *opaque)
/* Coroutine wrapper for bdrv_block_status_above() */
static void coroutine_fn bdrv_block_status_above_co_entry(void *opaque)
{
BdrvCoGetBlockStatusData *data = opaque;
BdrvCoBlockStatusData *data = opaque;
data->ret = bdrv_co_get_block_status_above(data->bs, data->base,
data->sector_num,
data->nb_sectors,
data->pnum,
data->file);
data->ret = bdrv_co_block_status_above(data->bs, data->base,
data->want_zero,
data->offset, data->bytes,
data->pnum, data->map, data->file);
data->done = true;
}
/*
* Synchronous wrapper around bdrv_co_get_block_status_above().
* Synchronous wrapper around bdrv_co_block_status_above().
*
* See bdrv_co_get_block_status_above() for details.
* See bdrv_co_block_status_above() for details.
*/
int64_t bdrv_get_block_status_above(BlockDriverState *bs,
BlockDriverState *base,
int64_t sector_num,
int nb_sectors, int *pnum,
BlockDriverState **file)
static int bdrv_common_block_status_above(BlockDriverState *bs,
BlockDriverState *base,
bool want_zero, int64_t offset,
int64_t bytes, int64_t *pnum,
int64_t *map,
BlockDriverState **file)
{
Coroutine *co;
BdrvCoGetBlockStatusData data = {
BdrvCoBlockStatusData data = {
.bs = bs,
.base = base,
.file = file,
.sector_num = sector_num,
.nb_sectors = nb_sectors,
.want_zero = want_zero,
.offset = offset,
.bytes = bytes,
.pnum = pnum,
.map = map,
.file = file,
.done = false,
};
if (qemu_in_coroutine()) {
/* Fast-path if already in coroutine context */
bdrv_get_block_status_above_co_entry(&data);
bdrv_block_status_above_co_entry(&data);
} else {
co = qemu_coroutine_create(bdrv_get_block_status_above_co_entry,
&data);
co = qemu_coroutine_create(bdrv_block_status_above_co_entry, &data);
bdrv_coroutine_enter(bs, co);
BDRV_POLL_WHILE(bs, !data.done);
}
return data.ret;
}
int64_t bdrv_get_block_status(BlockDriverState *bs,
int64_t sector_num,
int nb_sectors, int *pnum,
BlockDriverState **file)
int bdrv_block_status_above(BlockDriverState *bs, BlockDriverState *base,
int64_t offset, int64_t bytes, int64_t *pnum,
int64_t *map, BlockDriverState **file)
{
return bdrv_get_block_status_above(bs, backing_bs(bs),
sector_num, nb_sectors, pnum, file);
return bdrv_common_block_status_above(bs, base, true, offset, bytes,
pnum, map, file);
}
int bdrv_block_status(BlockDriverState *bs, int64_t offset, int64_t bytes,
int64_t *pnum, int64_t *map, BlockDriverState **file)
{
return bdrv_block_status_above(bs, backing_bs(bs),
offset, bytes, pnum, map, file);
}
int coroutine_fn bdrv_is_allocated(BlockDriverState *bs, int64_t offset,
int64_t bytes, int64_t *pnum)
{
BlockDriverState *file;
int64_t sector_num = offset >> BDRV_SECTOR_BITS;
int nb_sectors = bytes >> BDRV_SECTOR_BITS;
int64_t ret;
int psectors;
int ret;
int64_t dummy;
assert(QEMU_IS_ALIGNED(offset, BDRV_SECTOR_SIZE));
assert(QEMU_IS_ALIGNED(bytes, BDRV_SECTOR_SIZE) && bytes < INT_MAX);
ret = bdrv_get_block_status(bs, sector_num, nb_sectors, &psectors,
&file);
ret = bdrv_common_block_status_above(bs, backing_bs(bs), false, offset,
bytes, pnum ? pnum : &dummy, NULL,
NULL);
if (ret < 0) {
return ret;
}
if (pnum) {
*pnum = psectors * BDRV_SECTOR_SIZE;
}
return !!(ret & BDRV_BLOCK_ALLOCATED);
}

View File

@ -190,10 +190,9 @@ static int mirror_cow_align(MirrorBlockJob *s, int64_t *offset,
bool need_cow;
int ret = 0;
int64_t align_offset = *offset;
unsigned int align_bytes = *bytes;
int64_t align_bytes = *bytes;
int max_bytes = s->granularity * s->max_iov;
assert(*bytes < INT_MAX);
need_cow = !test_bit(*offset / s->granularity, s->cow_bitmap);
need_cow |= !test_bit((*offset + *bytes - 1) / s->granularity,
s->cow_bitmap);
@ -329,7 +328,6 @@ static uint64_t coroutine_fn mirror_iteration(MirrorBlockJob *s)
uint64_t delay_ns = 0;
/* At least the first dirty chunk is mirrored in one iteration. */
int nb_chunks = 1;
int sectors_per_chunk = s->granularity >> BDRV_SECTOR_BITS;
bool write_zeroes_ok = bdrv_can_write_zeroes_with_unmap(blk_bs(s->target));
int max_io_bytes = MAX(s->buf_size / MAX_IN_FLIGHT, MAX_IO_BYTES);
@ -377,7 +375,7 @@ static uint64_t coroutine_fn mirror_iteration(MirrorBlockJob *s)
}
/* Clear dirty bits before querying the block status, because
* calling bdrv_get_block_status_above could yield - if some blocks are
* calling bdrv_block_status_above could yield - if some blocks are
* marked dirty in this window, we need to know.
*/
bdrv_reset_dirty_bitmap_locked(s->dirty_bitmap, offset,
@ -386,11 +384,9 @@ static uint64_t coroutine_fn mirror_iteration(MirrorBlockJob *s)
bitmap_set(s->in_flight_bitmap, offset / s->granularity, nb_chunks);
while (nb_chunks > 0 && offset < s->bdev_length) {
int64_t ret;
int io_sectors;
unsigned int io_bytes;
int ret;
int64_t io_bytes;
int64_t io_bytes_acct;
BlockDriverState *file;
enum MirrorMethod {
MIRROR_METHOD_COPY,
MIRROR_METHOD_ZERO,
@ -398,11 +394,9 @@ static uint64_t coroutine_fn mirror_iteration(MirrorBlockJob *s)
} mirror_method = MIRROR_METHOD_COPY;
assert(!(offset % s->granularity));
ret = bdrv_get_block_status_above(source, NULL,
offset >> BDRV_SECTOR_BITS,
nb_chunks * sectors_per_chunk,
&io_sectors, &file);
io_bytes = io_sectors * BDRV_SECTOR_SIZE;
ret = bdrv_block_status_above(source, NULL, offset,
nb_chunks * s->granularity,
&io_bytes, NULL, NULL);
if (ret < 0) {
io_bytes = MIN(nb_chunks * s->granularity, max_io_bytes);
} else if (ret & BDRV_BLOCK_DATA) {
@ -414,7 +408,7 @@ static uint64_t coroutine_fn mirror_iteration(MirrorBlockJob *s)
io_bytes = s->granularity;
} else if (ret >= 0 && !(ret & BDRV_BLOCK_DATA)) {
int64_t target_offset;
unsigned int target_bytes;
int64_t target_bytes;
bdrv_round_to_clusters(blk_bs(s->target), offset, io_bytes,
&target_offset, &target_bytes);
if (target_offset == offset &&
@ -1133,9 +1127,7 @@ static void mirror_start_job(const char *job_id, BlockDriverState *bs,
granularity = bdrv_get_default_bitmap_granularity(target);
}
assert ((granularity & (granularity - 1)) == 0);
/* Granularity must be large enough for sector-based dirty bitmap */
assert(granularity >= BDRV_SECTOR_SIZE);
assert(is_power_of_2(granularity));
if (buf_size < 0) {
error_setg(errp, "Invalid parameter 'buf-size'");

View File

@ -1632,7 +1632,7 @@ static int discard_single_l2(BlockDriverState *bs, uint64_t offset,
* cluster is already marked as zero, or if it's unallocated and we
* don't have a backing file.
*
* TODO We might want to use bdrv_get_block_status(bs) here, but we're
* TODO We might want to use bdrv_block_status(bs) here, but we're
* holding s->lock, so that doesn't work today.
*
* If full_discard is true, the sector should not read back as zeroes,

View File

@ -1139,7 +1139,7 @@ static int qcow2_do_open(BlockDriverState *bs, QDict *options, int flags,
s->cluster_bits = header.cluster_bits;
s->cluster_size = 1 << s->cluster_bits;
s->cluster_sectors = 1 << (s->cluster_bits - 9);
s->cluster_sectors = 1 << (s->cluster_bits - BDRV_SECTOR_BITS);
/* Initialise version 3 header fields */
if (header.version == 2) {
@ -1636,7 +1636,7 @@ static int64_t coroutine_fn qcow2_co_get_block_status(BlockDriverState *bs,
bytes = MIN(INT_MAX, nb_sectors * BDRV_SECTOR_SIZE);
qemu_co_mutex_lock(&s->lock);
ret = qcow2_get_cluster_offset(bs, sector_num << 9, &bytes,
ret = qcow2_get_cluster_offset(bs, sector_num << BDRV_SECTOR_BITS, &bytes,
&cluster_offset);
qemu_co_mutex_unlock(&s->lock);
if (ret < 0) {
@ -2460,6 +2460,14 @@ static int qcow2_set_up_encryption(BlockDriverState *bs, const char *encryptfmt,
}
typedef struct PreallocCo {
BlockDriverState *bs;
uint64_t offset;
uint64_t new_length;
int ret;
} PreallocCo;
/**
* Preallocates metadata structures for data clusters between @offset (in the
* guest disk) and @new_length (which is thus generally the new guest disk
@ -2467,9 +2475,12 @@ static int qcow2_set_up_encryption(BlockDriverState *bs, const char *encryptfmt,
*
* Returns: 0 on success, -errno on failure.
*/
static int preallocate(BlockDriverState *bs,
uint64_t offset, uint64_t new_length)
static void coroutine_fn preallocate_co(void *opaque)
{
PreallocCo *params = opaque;
BlockDriverState *bs = params->bs;
uint64_t offset = params->offset;
uint64_t new_length = params->new_length;
BDRVQcow2State *s = bs->opaque;
uint64_t bytes;
uint64_t host_offset = 0;
@ -2477,9 +2488,7 @@ static int preallocate(BlockDriverState *bs,
int ret;
QCowL2Meta *meta;
if (qemu_in_coroutine()) {
qemu_co_mutex_lock(&s->lock);
}
qemu_co_mutex_lock(&s->lock);
assert(offset <= new_length);
bytes = new_length - offset;
@ -2533,10 +2542,28 @@ static int preallocate(BlockDriverState *bs,
ret = 0;
done:
qemu_co_mutex_unlock(&s->lock);
params->ret = ret;
}
static int preallocate(BlockDriverState *bs,
uint64_t offset, uint64_t new_length)
{
PreallocCo params = {
.bs = bs,
.offset = offset,
.new_length = new_length,
.ret = -EINPROGRESS,
};
if (qemu_in_coroutine()) {
qemu_co_mutex_unlock(&s->lock);
preallocate_co(&params);
} else {
Coroutine *co = qemu_coroutine_create(preallocate_co, &params);
bdrv_coroutine_enter(bs, co);
BDRV_POLL_WHILE(bs, params.ret == -EINPROGRESS);
}
return ret;
return params.ret;
}
/* qcow2_refcount_metadata_size:
@ -2972,23 +2999,21 @@ finish:
}
static bool is_zero_sectors(BlockDriverState *bs, int64_t start,
uint32_t count)
static bool is_zero(BlockDriverState *bs, int64_t offset, int64_t bytes)
{
int nr;
BlockDriverState *file;
int64_t res;
int64_t nr;
int res;
if (start + count > bs->total_sectors) {
count = bs->total_sectors - start;
/* Clamp to image length, before checking status of underlying sectors */
if (offset + bytes > bs->total_sectors * BDRV_SECTOR_SIZE) {
bytes = bs->total_sectors * BDRV_SECTOR_SIZE - offset;
}
if (!count) {
if (!bytes) {
return true;
}
res = bdrv_get_block_status_above(bs, NULL, start, count,
&nr, &file);
return res >= 0 && (res & BDRV_BLOCK_ZERO) && nr == count;
res = bdrv_block_status_above(bs, NULL, offset, bytes, &nr, NULL, NULL);
return res >= 0 && (res & BDRV_BLOCK_ZERO) && nr == bytes;
}
static coroutine_fn int qcow2_co_pwrite_zeroes(BlockDriverState *bs,
@ -3006,24 +3031,21 @@ static coroutine_fn int qcow2_co_pwrite_zeroes(BlockDriverState *bs,
}
if (head || tail) {
int64_t cl_start = (offset - head) >> BDRV_SECTOR_BITS;
uint64_t off;
unsigned int nr;
assert(head + bytes <= s->cluster_size);
/* check whether remainder of cluster already reads as zero */
if (!(is_zero_sectors(bs, cl_start,
DIV_ROUND_UP(head, BDRV_SECTOR_SIZE)) &&
is_zero_sectors(bs, (offset + bytes) >> BDRV_SECTOR_BITS,
DIV_ROUND_UP(-tail & (s->cluster_size - 1),
BDRV_SECTOR_SIZE)))) {
if (!(is_zero(bs, offset - head, head) &&
is_zero(bs, offset + bytes,
tail ? s->cluster_size - tail : 0))) {
return -ENOTSUP;
}
qemu_co_mutex_lock(&s->lock);
/* We can have new write after previous check */
offset = cl_start << BDRV_SECTOR_BITS;
offset = QEMU_ALIGN_DOWN(offset, s->cluster_size);
bytes = s->cluster_size;
nr = s->cluster_size;
ret = qcow2_get_cluster_offset(bs, offset, &nr, &off);
@ -3150,12 +3172,13 @@ static int qcow2_truncate(BlockDriverState *bs, int64_t offset,
return last_cluster;
}
if ((last_cluster + 1) * s->cluster_size < old_file_size) {
ret = bdrv_truncate(bs->file, (last_cluster + 1) * s->cluster_size,
PREALLOC_MODE_OFF, NULL);
if (ret < 0) {
warn_report("Failed to truncate the tail of the image: %s",
strerror(-ret));
ret = 0;
Error *local_err = NULL;
bdrv_truncate(bs->file, (last_cluster + 1) * s->cluster_size,
PREALLOC_MODE_OFF, &local_err);
if (local_err) {
warn_reportf_err(local_err,
"Failed to truncate the tail of the image: ");
}
}
} else {
@ -3192,6 +3215,7 @@ static int qcow2_truncate(BlockDriverState *bs, int64_t offset,
"Failed to inquire current file length");
return old_file_size;
}
old_file_size = ROUND_UP(old_file_size, s->cluster_size);
nb_new_data_clusters = DIV_ROUND_UP(offset - old_length,
s->cluster_size);
@ -3697,19 +3721,14 @@ static BlockMeasureInfo *qcow2_measure(QemuOpts *opts, BlockDriverState *in_bs,
required = virtual_size;
} else {
int64_t offset;
int pnum = 0;
int64_t pnum = 0;
for (offset = 0; offset < ssize;
offset += pnum * BDRV_SECTOR_SIZE) {
int nb_sectors = MIN(ssize - offset,
BDRV_REQUEST_MAX_BYTES) / BDRV_SECTOR_SIZE;
BlockDriverState *file;
int64_t ret;
for (offset = 0; offset < ssize; offset += pnum) {
int ret;
ret = bdrv_get_block_status_above(in_bs, NULL,
offset >> BDRV_SECTOR_BITS,
nb_sectors,
&pnum, &file);
ret = bdrv_block_status_above(in_bs, NULL, offset,
ssize - offset, &pnum, NULL,
NULL);
if (ret < 0) {
error_setg_errno(&local_err, -ret,
"Unable to get block status");
@ -3721,11 +3740,10 @@ static BlockMeasureInfo *qcow2_measure(QemuOpts *opts, BlockDriverState *in_bs,
} else if ((ret & (BDRV_BLOCK_DATA | BDRV_BLOCK_ALLOCATED)) ==
(BDRV_BLOCK_DATA | BDRV_BLOCK_ALLOCATED)) {
/* Extend pnum to end of cluster for next iteration */
pnum = (ROUND_UP(offset + pnum * BDRV_SECTOR_SIZE,
cluster_size) - offset) >> BDRV_SECTOR_BITS;
pnum = ROUND_UP(offset + pnum, cluster_size) - offset;
/* Count clusters we've seen */
required += offset % cluster_size + pnum * BDRV_SECTOR_SIZE;
required += offset % cluster_size + pnum;
}
}
}

View File

@ -12,7 +12,7 @@ blk_co_pwritev(void *blk, void *bs, int64_t offset, unsigned int bytes, int flag
bdrv_co_preadv(void *bs, int64_t offset, int64_t nbytes, unsigned int flags) "bs %p offset %"PRId64" nbytes %"PRId64" flags 0x%x"
bdrv_co_pwritev(void *bs, int64_t offset, int64_t nbytes, unsigned int flags) "bs %p offset %"PRId64" nbytes %"PRId64" flags 0x%x"
bdrv_co_pwrite_zeroes(void *bs, int64_t offset, int count, int flags) "bs %p offset %"PRId64" count %d flags 0x%x"
bdrv_co_do_copy_on_readv(void *bs, int64_t offset, unsigned int bytes, int64_t cluster_offset, unsigned int cluster_bytes) "bs %p offset %"PRId64" bytes %u cluster_offset %"PRId64" cluster_bytes %u"
bdrv_co_do_copy_on_readv(void *bs, int64_t offset, unsigned int bytes, int64_t cluster_offset, int64_t cluster_bytes) "bs %p offset %"PRId64" bytes %u cluster_offset %"PRId64" cluster_bytes %"PRId64
# block/stream.c
stream_one_iteration(void *s, int64_t offset, uint64_t bytes, int is_allocated) "s %p offset %" PRId64 " bytes %" PRIu64 " is_allocated %d"

View File

@ -121,7 +121,7 @@ typedef struct HDGeometry {
#define BDRV_REQUEST_MAX_BYTES (BDRV_REQUEST_MAX_SECTORS << BDRV_SECTOR_BITS)
/*
* Allocation status flags for bdrv_get_block_status() and friends.
* Allocation status flags for bdrv_block_status() and friends.
*
* Public flags:
* BDRV_BLOCK_DATA: allocation for data at offset is tied to this layer
@ -136,10 +136,11 @@ typedef struct HDGeometry {
* that the block layer recompute the answer from the returned
* BDS; must be accompanied by just BDRV_BLOCK_OFFSET_VALID.
*
* If BDRV_BLOCK_OFFSET_VALID is set, bits 9-62 (BDRV_BLOCK_OFFSET_MASK)
* represent the offset in the returned BDS that is allocated for the
* corresponding raw data; however, whether that offset actually contains
* data also depends on BDRV_BLOCK_DATA and BDRV_BLOCK_ZERO, as follows:
* If BDRV_BLOCK_OFFSET_VALID is set, bits 9-62 (BDRV_BLOCK_OFFSET_MASK) of
* the return value (old interface) or the entire map parameter (new
* interface) represent the offset in the returned BDS that is allocated for
* the corresponding raw data. However, whether that offset actually
* contains data also depends on BDRV_BLOCK_DATA, as follows:
*
* DATA ZERO OFFSET_VALID
* t t t sectors read as zero, returned file is zero at offset
@ -421,14 +422,12 @@ int bdrv_has_zero_init_1(BlockDriverState *bs);
int bdrv_has_zero_init(BlockDriverState *bs);
bool bdrv_unallocated_blocks_are_zero(BlockDriverState *bs);
bool bdrv_can_write_zeroes_with_unmap(BlockDriverState *bs);
int64_t bdrv_get_block_status(BlockDriverState *bs, int64_t sector_num,
int nb_sectors, int *pnum,
BlockDriverState **file);
int64_t bdrv_get_block_status_above(BlockDriverState *bs,
BlockDriverState *base,
int64_t sector_num,
int nb_sectors, int *pnum,
BlockDriverState **file);
int bdrv_block_status(BlockDriverState *bs, int64_t offset,
int64_t bytes, int64_t *pnum, int64_t *map,
BlockDriverState **file);
int bdrv_block_status_above(BlockDriverState *bs, BlockDriverState *base,
int64_t offset, int64_t bytes, int64_t *pnum,
int64_t *map, BlockDriverState **file);
int bdrv_is_allocated(BlockDriverState *bs, int64_t offset, int64_t bytes,
int64_t *pnum);
int bdrv_is_allocated_above(BlockDriverState *top, BlockDriverState *base,
@ -474,9 +473,9 @@ int bdrv_get_flags(BlockDriverState *bs);
int bdrv_get_info(BlockDriverState *bs, BlockDriverInfo *bdi);
ImageInfoSpecific *bdrv_get_specific_info(BlockDriverState *bs);
void bdrv_round_to_clusters(BlockDriverState *bs,
int64_t offset, unsigned int bytes,
int64_t offset, int64_t bytes,
int64_t *cluster_offset,
unsigned int *cluster_bytes);
int64_t *cluster_bytes);
const char *bdrv_get_encrypted_filename(BlockDriverState *bs);
void bdrv_get_backing_filename(BlockDriverState *bs,

View File

@ -202,10 +202,13 @@ struct BlockDriver {
int64_t offset, int bytes);
/*
* Building block for bdrv_block_status[_above]. The driver should
* answer only according to the current layer, and should not
* set BDRV_BLOCK_ALLOCATED, but may set BDRV_BLOCK_RAW. See block.h
* for the meaning of _DATA, _ZERO, and _OFFSET_VALID.
* Building block for bdrv_block_status[_above] and
* bdrv_is_allocated[_above]. The driver should answer only
* according to the current layer, and should not set
* BDRV_BLOCK_ALLOCATED, but may set BDRV_BLOCK_RAW. See block.h
* for the meaning of _DATA, _ZERO, and _OFFSET_VALID. The block
* layer guarantees input aligned to request_alignment, as well as
* non-NULL pnum and file.
*/
int64_t coroutine_fn (*bdrv_co_get_block_status)(BlockDriverState *bs,
int64_t sector_num, int nb_sectors, int *pnum,

View File

@ -1064,6 +1064,28 @@ done:
return 0;
}
/*
* Returns -1 if 'buf' contains only zeroes, otherwise the byte index
* of the first sector boundary within buf where the sector contains a
* non-zero byte. This function is robust to a buffer that is not
* sector-aligned.
*/
static int64_t find_nonzero(const uint8_t *buf, int64_t n)
{
int64_t i;
int64_t end = QEMU_ALIGN_DOWN(n, BDRV_SECTOR_SIZE);
for (i = 0; i < end; i += BDRV_SECTOR_SIZE) {
if (!buffer_is_zero(buf + i, BDRV_SECTOR_SIZE)) {
return i;
}
}
if (i < n && !buffer_is_zero(buf + i, n - end)) {
return i;
}
return -1;
}
/*
* Returns true iff the first sector pointed to by 'buf' contains at least
* a non-NUL byte.
@ -1134,31 +1156,28 @@ static int is_allocated_sectors_min(const uint8_t *buf, int n, int *pnum,
}
/*
* Compares two buffers sector by sector. Returns 0 if the first sector of both
* buffers matches, non-zero otherwise.
* Compares two buffers sector by sector. Returns 0 if the first
* sector of each buffer matches, non-zero otherwise.
*
* pnum is set to the number of sectors (including and immediately following
* the first one) that are known to have the same comparison result
* pnum is set to the sector-aligned size of the buffer prefix that
* has the same matching status as the first sector.
*/
static int compare_sectors(const uint8_t *buf1, const uint8_t *buf2, int n,
int *pnum)
static int compare_buffers(const uint8_t *buf1, const uint8_t *buf2,
int64_t bytes, int64_t *pnum)
{
bool res;
int i;
int64_t i = MIN(bytes, BDRV_SECTOR_SIZE);
if (n <= 0) {
*pnum = 0;
return 0;
}
assert(bytes > 0);
res = !!memcmp(buf1, buf2, 512);
for(i = 1; i < n; i++) {
buf1 += 512;
buf2 += 512;
res = !!memcmp(buf1, buf2, i);
while (i < bytes) {
int64_t len = MIN(bytes - i, BDRV_SECTOR_SIZE);
if (!!memcmp(buf1, buf2, 512) != res) {
if (!!memcmp(buf1 + i, buf2 + i, len) != res) {
break;
}
i += len;
}
*pnum = i;
@ -1167,45 +1186,38 @@ static int compare_sectors(const uint8_t *buf1, const uint8_t *buf2, int n,
#define IO_BUF_SIZE (2 * 1024 * 1024)
static int64_t sectors_to_bytes(int64_t sectors)
{
return sectors << BDRV_SECTOR_BITS;
}
static int64_t sectors_to_process(int64_t total, int64_t from)
{
return MIN(total - from, IO_BUF_SIZE >> BDRV_SECTOR_BITS);
}
/*
* Check if passed sectors are empty (not allocated or contain only 0 bytes)
*
* Returns 0 in case sectors are filled with 0, 1 if sectors contain non-zero
* data and negative value on error.
* Intended for use by 'qemu-img compare': Returns 0 in case sectors are
* filled with 0, 1 if sectors contain non-zero data (this is a comparison
* failure), and 4 on error (the exit status for read errors), after emitting
* an error message.
*
* @param blk: BlockBackend for the image
* @param sect_num: Number of first sector to check
* @param sect_count: Number of sectors to check
* @param offset: Starting offset to check
* @param bytes: Number of bytes to check
* @param filename: Name of disk file we are checking (logging purpose)
* @param buffer: Allocated buffer for storing read data
* @param quiet: Flag for quiet mode
*/
static int check_empty_sectors(BlockBackend *blk, int64_t sect_num,
int sect_count, const char *filename,
static int check_empty_sectors(BlockBackend *blk, int64_t offset,
int64_t bytes, const char *filename,
uint8_t *buffer, bool quiet)
{
int pnum, ret = 0;
ret = blk_pread(blk, sect_num << BDRV_SECTOR_BITS, buffer,
sect_count << BDRV_SECTOR_BITS);
int ret = 0;
int64_t idx;
ret = blk_pread(blk, offset, buffer, bytes);
if (ret < 0) {
error_report("Error while reading offset %" PRId64 " of %s: %s",
sectors_to_bytes(sect_num), filename, strerror(-ret));
return ret;
offset, filename, strerror(-ret));
return 4;
}
ret = is_allocated_sectors(buffer, sect_count, &pnum);
if (ret || pnum != sect_count) {
idx = find_nonzero(buffer, bytes);
if (idx >= 0) {
qprintf(quiet, "Content mismatch at offset %" PRId64 "!\n",
sectors_to_bytes(ret ? sect_num : sect_num + pnum));
offset + idx);
return 1;
}
@ -1224,18 +1236,18 @@ static int img_compare(int argc, char **argv)
const char *fmt1 = NULL, *fmt2 = NULL, *cache, *filename1, *filename2;
BlockBackend *blk1, *blk2;
BlockDriverState *bs1, *bs2;
int64_t total_sectors1, total_sectors2;
int64_t total_size1, total_size2;
uint8_t *buf1 = NULL, *buf2 = NULL;
int pnum1, pnum2;
int64_t pnum1, pnum2;
int allocated1, allocated2;
int ret = 0; /* return value - 0 Ident, 1 Different, >1 Error */
bool progress = false, quiet = false, strict = false;
int flags;
bool writethrough;
int64_t total_sectors;
int64_t sector_num = 0;
int64_t nb_sectors;
int c, pnum;
int64_t total_size;
int64_t offset = 0;
int64_t chunk;
int c;
uint64_t progress_base;
bool image_opts = false;
bool force_share = false;
@ -1348,42 +1360,37 @@ static int img_compare(int argc, char **argv)
buf1 = blk_blockalign(blk1, IO_BUF_SIZE);
buf2 = blk_blockalign(blk2, IO_BUF_SIZE);
total_sectors1 = blk_nb_sectors(blk1);
if (total_sectors1 < 0) {
total_size1 = blk_getlength(blk1);
if (total_size1 < 0) {
error_report("Can't get size of %s: %s",
filename1, strerror(-total_sectors1));
filename1, strerror(-total_size1));
ret = 4;
goto out;
}
total_sectors2 = blk_nb_sectors(blk2);
if (total_sectors2 < 0) {
total_size2 = blk_getlength(blk2);
if (total_size2 < 0) {
error_report("Can't get size of %s: %s",
filename2, strerror(-total_sectors2));
filename2, strerror(-total_size2));
ret = 4;
goto out;
}
total_sectors = MIN(total_sectors1, total_sectors2);
progress_base = MAX(total_sectors1, total_sectors2);
total_size = MIN(total_size1, total_size2);
progress_base = MAX(total_size1, total_size2);
qemu_progress_print(0, 100);
if (strict && total_sectors1 != total_sectors2) {
if (strict && total_size1 != total_size2) {
ret = 1;
qprintf(quiet, "Strict mode: Image size mismatch!\n");
goto out;
}
for (;;) {
int64_t status1, status2;
BlockDriverState *file;
while (offset < total_size) {
int status1, status2;
nb_sectors = sectors_to_process(total_sectors, sector_num);
if (nb_sectors <= 0) {
break;
}
status1 = bdrv_get_block_status_above(bs1, NULL, sector_num,
total_sectors1 - sector_num,
&pnum1, &file);
status1 = bdrv_block_status_above(bs1, NULL, offset,
total_size1 - offset, &pnum1, NULL,
NULL);
if (status1 < 0) {
ret = 3;
error_report("Sector allocation test failed for %s", filename1);
@ -1391,112 +1398,92 @@ static int img_compare(int argc, char **argv)
}
allocated1 = status1 & BDRV_BLOCK_ALLOCATED;
status2 = bdrv_get_block_status_above(bs2, NULL, sector_num,
total_sectors2 - sector_num,
&pnum2, &file);
status2 = bdrv_block_status_above(bs2, NULL, offset,
total_size2 - offset, &pnum2, NULL,
NULL);
if (status2 < 0) {
ret = 3;
error_report("Sector allocation test failed for %s", filename2);
goto out;
}
allocated2 = status2 & BDRV_BLOCK_ALLOCATED;
if (pnum1) {
nb_sectors = MIN(nb_sectors, pnum1);
}
if (pnum2) {
nb_sectors = MIN(nb_sectors, pnum2);
}
assert(pnum1 && pnum2);
chunk = MIN(pnum1, pnum2);
if (strict) {
if ((status1 & ~BDRV_BLOCK_OFFSET_MASK) !=
(status2 & ~BDRV_BLOCK_OFFSET_MASK)) {
if (status1 != status2) {
ret = 1;
qprintf(quiet, "Strict mode: Offset %" PRId64
" block status mismatch!\n",
sectors_to_bytes(sector_num));
" block status mismatch!\n", offset);
goto out;
}
}
if ((status1 & BDRV_BLOCK_ZERO) && (status2 & BDRV_BLOCK_ZERO)) {
nb_sectors = MIN(pnum1, pnum2);
/* nothing to do */
} else if (allocated1 == allocated2) {
if (allocated1) {
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,
strerror(-ret));
ret = 4;
goto out;
}
ret = blk_pread(blk2, sector_num << BDRV_SECTOR_BITS, buf2,
nb_sectors << BDRV_SECTOR_BITS);
int64_t pnum;
chunk = MIN(chunk, IO_BUF_SIZE);
ret = blk_pread(blk1, offset, buf1, chunk);
if (ret < 0) {
error_report("Error while reading offset %" PRId64
" of %s: %s", sectors_to_bytes(sector_num),
filename2, strerror(-ret));
" of %s: %s",
offset, filename1, strerror(-ret));
ret = 4;
goto out;
}
ret = compare_sectors(buf1, buf2, nb_sectors, &pnum);
if (ret || pnum != nb_sectors) {
ret = blk_pread(blk2, offset, buf2, chunk);
if (ret < 0) {
error_report("Error while reading offset %" PRId64
" of %s: %s",
offset, filename2, strerror(-ret));
ret = 4;
goto out;
}
ret = compare_buffers(buf1, buf2, chunk, &pnum);
if (ret || pnum != chunk) {
qprintf(quiet, "Content mismatch at offset %" PRId64 "!\n",
sectors_to_bytes(
ret ? sector_num : sector_num + pnum));
offset + (ret ? 0 : pnum));
ret = 1;
goto out;
}
}
} else {
chunk = MIN(chunk, IO_BUF_SIZE);
if (allocated1) {
ret = check_empty_sectors(blk1, sector_num, nb_sectors,
ret = check_empty_sectors(blk1, offset, chunk,
filename1, buf1, quiet);
} else {
ret = check_empty_sectors(blk2, sector_num, nb_sectors,
ret = check_empty_sectors(blk2, offset, chunk,
filename2, buf1, quiet);
}
if (ret) {
if (ret < 0) {
error_report("Error while reading offset %" PRId64 ": %s",
sectors_to_bytes(sector_num), strerror(-ret));
ret = 4;
}
goto out;
}
}
sector_num += nb_sectors;
qemu_progress_print(((float) nb_sectors / progress_base)*100, 100);
offset += chunk;
qemu_progress_print(((float) chunk / progress_base) * 100, 100);
}
if (total_sectors1 != total_sectors2) {
if (total_size1 != total_size2) {
BlockBackend *blk_over;
int64_t total_sectors_over;
const char *filename_over;
qprintf(quiet, "Warning: Image size mismatch!\n");
if (total_sectors1 > total_sectors2) {
total_sectors_over = total_sectors1;
if (total_size1 > total_size2) {
blk_over = blk1;
filename_over = filename1;
} else {
total_sectors_over = total_sectors2;
blk_over = blk2;
filename_over = filename2;
}
for (;;) {
int64_t count;
nb_sectors = sectors_to_process(total_sectors_over, sector_num);
if (nb_sectors <= 0) {
break;
}
ret = bdrv_is_allocated_above(blk_bs(blk_over), NULL,
sector_num * BDRV_SECTOR_SIZE,
nb_sectors * BDRV_SECTOR_SIZE,
&count);
while (offset < progress_base) {
ret = bdrv_block_status_above(blk_bs(blk_over), NULL, offset,
progress_base - offset, &chunk,
NULL, NULL);
if (ret < 0) {
ret = 3;
error_report("Sector allocation test failed for %s",
@ -1504,25 +1491,16 @@ static int img_compare(int argc, char **argv)
goto out;
}
/* TODO relax this once bdrv_is_allocated_above does not enforce
* sector alignment */
assert(QEMU_IS_ALIGNED(count, BDRV_SECTOR_SIZE));
nb_sectors = count >> BDRV_SECTOR_BITS;
if (ret) {
ret = check_empty_sectors(blk_over, sector_num, nb_sectors,
if (ret & BDRV_BLOCK_ALLOCATED && !(ret & BDRV_BLOCK_ZERO)) {
chunk = MIN(chunk, IO_BUF_SIZE);
ret = check_empty_sectors(blk_over, offset, chunk,
filename_over, buf1, quiet);
if (ret) {
if (ret < 0) {
error_report("Error while reading offset %" PRId64
" of %s: %s", sectors_to_bytes(sector_num),
filename_over, strerror(-ret));
ret = 4;
}
goto out;
}
}
sector_num += nb_sectors;
qemu_progress_print(((float) nb_sectors / progress_base)*100, 100);
offset += chunk;
qemu_progress_print(((float) chunk / progress_base) * 100, 100);
}
}
@ -1590,8 +1568,8 @@ static void convert_select_part(ImgConvertState *s, int64_t sector_num,
static int convert_iteration_sectors(ImgConvertState *s, int64_t sector_num)
{
int64_t ret, src_cur_offset;
int n, src_cur;
int64_t src_cur_offset;
int ret, n, src_cur;
convert_select_part(s, sector_num, &src_cur, &src_cur_offset);
@ -1599,19 +1577,24 @@ static int convert_iteration_sectors(ImgConvertState *s, int64_t sector_num)
n = MIN(s->total_sectors - sector_num, BDRV_REQUEST_MAX_SECTORS);
if (s->sector_next_status <= sector_num) {
BlockDriverState *file;
int64_t count = n * BDRV_SECTOR_SIZE;
if (s->target_has_backing) {
ret = bdrv_get_block_status(blk_bs(s->src[src_cur]),
sector_num - src_cur_offset,
n, &n, &file);
ret = bdrv_block_status(blk_bs(s->src[src_cur]),
(sector_num - src_cur_offset) *
BDRV_SECTOR_SIZE,
count, &count, NULL, NULL);
} else {
ret = bdrv_get_block_status_above(blk_bs(s->src[src_cur]), NULL,
sector_num - src_cur_offset,
n, &n, &file);
ret = bdrv_block_status_above(blk_bs(s->src[src_cur]), NULL,
(sector_num - src_cur_offset) *
BDRV_SECTOR_SIZE,
count, &count, NULL, NULL);
}
if (ret < 0) {
return ret;
}
n = DIV_ROUND_UP(count, BDRV_SECTOR_SIZE);
if (ret & BDRV_BLOCK_ZERO) {
s->status = BLK_ZERO;
@ -2673,13 +2656,14 @@ static void dump_map_entry(OutputFormat output_format, MapEntry *e,
}
}
static int get_block_status(BlockDriverState *bs, int64_t sector_num,
int nb_sectors, MapEntry *e)
static int get_block_status(BlockDriverState *bs, int64_t offset,
int64_t bytes, MapEntry *e)
{
int64_t ret;
int ret;
int depth;
BlockDriverState *file;
bool has_offset;
int64_t map;
/* As an optimization, we could cache the current range of unallocated
* clusters in each file of the chain, and avoid querying the same
@ -2688,12 +2672,11 @@ static int get_block_status(BlockDriverState *bs, int64_t sector_num,
depth = 0;
for (;;) {
ret = bdrv_get_block_status(bs, sector_num, nb_sectors, &nb_sectors,
&file);
ret = bdrv_block_status(bs, offset, bytes, &bytes, &map, &file);
if (ret < 0) {
return ret;
}
assert(nb_sectors);
assert(bytes);
if (ret & (BDRV_BLOCK_ZERO|BDRV_BLOCK_DATA)) {
break;
}
@ -2709,11 +2692,11 @@ static int get_block_status(BlockDriverState *bs, int64_t sector_num,
has_offset = !!(ret & BDRV_BLOCK_OFFSET_VALID);
*e = (MapEntry) {
.start = sector_num * BDRV_SECTOR_SIZE,
.length = nb_sectors * BDRV_SECTOR_SIZE,
.start = offset,
.length = bytes,
.data = !!(ret & BDRV_BLOCK_DATA),
.zero = !!(ret & BDRV_BLOCK_ZERO),
.offset = ret & BDRV_BLOCK_OFFSET_MASK,
.offset = map,
.has_offset = has_offset,
.depth = depth,
.has_filename = file && has_offset,
@ -2839,16 +2822,12 @@ static int img_map(int argc, char **argv)
length = blk_getlength(blk);
while (curr.start + curr.length < length) {
int64_t nsectors_left;
int64_t sector_num;
int n;
sector_num = (curr.start + curr.length) >> BDRV_SECTOR_BITS;
int64_t offset = curr.start + curr.length;
int64_t n;
/* Probe up to 1 GiB at a time. */
nsectors_left = DIV_ROUND_UP(length, BDRV_SECTOR_SIZE) - sector_num;
n = MIN(1 << (30 - BDRV_SECTOR_BITS), nsectors_left);
ret = get_block_status(bs, sector_num, n, &next);
n = QEMU_ALIGN_DOWN(MIN(1 << 30, length - offset), BDRV_SECTOR_SIZE);
ret = get_block_status(bs, offset, n, &next);
if (ret < 0) {
error_report("Could not read file metadata: %s", strerror(-ret));
@ -3241,70 +3220,58 @@ static int img_rebase(int argc, char **argv)
* the image is the same as the original one at any time.
*/
if (!unsafe) {
int64_t num_sectors;
int64_t old_backing_num_sectors;
int64_t new_backing_num_sectors = 0;
uint64_t sector;
int n;
int64_t count;
int64_t size;
int64_t old_backing_size;
int64_t new_backing_size = 0;
uint64_t offset;
int64_t n;
float local_progress = 0;
buf_old = blk_blockalign(blk, IO_BUF_SIZE);
buf_new = blk_blockalign(blk, IO_BUF_SIZE);
num_sectors = blk_nb_sectors(blk);
if (num_sectors < 0) {
size = blk_getlength(blk);
if (size < 0) {
error_report("Could not get size of '%s': %s",
filename, strerror(-num_sectors));
filename, strerror(-size));
ret = -1;
goto out;
}
old_backing_num_sectors = blk_nb_sectors(blk_old_backing);
if (old_backing_num_sectors < 0) {
old_backing_size = blk_getlength(blk_old_backing);
if (old_backing_size < 0) {
char backing_name[PATH_MAX];
bdrv_get_backing_filename(bs, backing_name, sizeof(backing_name));
error_report("Could not get size of '%s': %s",
backing_name, strerror(-old_backing_num_sectors));
backing_name, strerror(-old_backing_size));
ret = -1;
goto out;
}
if (blk_new_backing) {
new_backing_num_sectors = blk_nb_sectors(blk_new_backing);
if (new_backing_num_sectors < 0) {
new_backing_size = blk_getlength(blk_new_backing);
if (new_backing_size < 0) {
error_report("Could not get size of '%s': %s",
out_baseimg, strerror(-new_backing_num_sectors));
out_baseimg, strerror(-new_backing_size));
ret = -1;
goto out;
}
}
if (num_sectors != 0) {
local_progress = (float)100 /
(num_sectors / MIN(num_sectors, IO_BUF_SIZE / 512));
if (size != 0) {
local_progress = (float)100 / (size / MIN(size, IO_BUF_SIZE));
}
for (sector = 0; sector < num_sectors; sector += n) {
/* How many sectors can we handle with the next read? */
if (sector + (IO_BUF_SIZE / 512) <= num_sectors) {
n = (IO_BUF_SIZE / 512);
} else {
n = num_sectors - sector;
}
for (offset = 0; offset < size; offset += n) {
/* How many bytes can we handle with the next read? */
n = MIN(IO_BUF_SIZE, size - offset);
/* If the cluster is allocated, we don't need to take action */
ret = bdrv_is_allocated(bs, sector << BDRV_SECTOR_BITS,
n << BDRV_SECTOR_BITS, &count);
ret = bdrv_is_allocated(bs, offset, n, &n);
if (ret < 0) {
error_report("error while reading image metadata: %s",
strerror(-ret));
goto out;
}
/* TODO relax this once bdrv_is_allocated does not enforce
* sector alignment */
assert(QEMU_IS_ALIGNED(count, BDRV_SECTOR_SIZE));
n = count >> BDRV_SECTOR_BITS;
if (ret) {
continue;
}
@ -3313,30 +3280,28 @@ static int img_rebase(int argc, char **argv)
* Read old and new backing file and take into consideration that
* backing files may be smaller than the COW image.
*/
if (sector >= old_backing_num_sectors) {
memset(buf_old, 0, n * BDRV_SECTOR_SIZE);
if (offset >= old_backing_size) {
memset(buf_old, 0, n);
} else {
if (sector + n > old_backing_num_sectors) {
n = old_backing_num_sectors - sector;
if (offset + n > old_backing_size) {
n = old_backing_size - offset;
}
ret = blk_pread(blk_old_backing, sector << BDRV_SECTOR_BITS,
buf_old, n << BDRV_SECTOR_BITS);
ret = blk_pread(blk_old_backing, offset, buf_old, n);
if (ret < 0) {
error_report("error while reading from old backing file");
goto out;
}
}
if (sector >= new_backing_num_sectors || !blk_new_backing) {
memset(buf_new, 0, n * BDRV_SECTOR_SIZE);
if (offset >= new_backing_size || !blk_new_backing) {
memset(buf_new, 0, n);
} else {
if (sector + n > new_backing_num_sectors) {
n = new_backing_num_sectors - sector;
if (offset + n > new_backing_size) {
n = new_backing_size - offset;
}
ret = blk_pread(blk_new_backing, sector << BDRV_SECTOR_BITS,
buf_new, n << BDRV_SECTOR_BITS);
ret = blk_pread(blk_new_backing, offset, buf_new, n);
if (ret < 0) {
error_report("error while reading from new backing file");
goto out;
@ -3347,15 +3312,13 @@ static int img_rebase(int argc, char **argv)
uint64_t written = 0;
while (written < n) {
int pnum;
int64_t pnum;
if (compare_sectors(buf_old + written * 512,
buf_new + written * 512, n - written, &pnum))
if (compare_buffers(buf_old + written, buf_new + written,
n - written, &pnum))
{
ret = blk_pwrite(blk,
(sector + written) << BDRV_SECTOR_BITS,
buf_old + written * 512,
pnum << BDRV_SECTOR_BITS, 0);
ret = blk_pwrite(blk, offset + written,
buf_old + written, pnum, 0);
if (ret < 0) {
error_report("Error while writing to COW image: %s",
strerror(-ret));

View File

@ -274,11 +274,10 @@ If the backing chain of the given image file @var{filename} has more than one
layer, the backing file into which the changes will be committed may be
specified as @var{base} (which has to be part of @var{filename}'s backing
chain). If @var{base} is not specified, the immediate backing file of the top
image (which is @var{filename}) will be used. For reasons of consistency,
explicitly specifying @var{base} will always imply @code{-d} (since emptying an
image after committing to an indirect backing file would lead to different data
being read from the image due to content in the intermediate backing chain
overruling the commit target).
image (which is @var{filename}) will be used. Note that after a commit operation
all images between @var{base} and the top image will be invalid and may return
garbage data when read. For this reason, @code{-b} implies @code{-d} (so that
the top image stays valid).
@item compare [-f @var{fmt}] [-F @var{fmt}] [-T @var{src_cache}] [-p] [-s] [-q] @var{filename1} @var{filename2}

View File

@ -1769,10 +1769,6 @@ static int alloc_f(BlockBackend *blk, int argc, char **argv)
if (offset < 0) {
print_cvtnum_err(offset, argv[1]);
return 0;
} else if (!QEMU_IS_ALIGNED(offset, BDRV_SECTOR_SIZE)) {
printf("%" PRId64 " is not a sector-aligned value for 'offset'\n",
offset);
return 0;
}
if (argc == 3) {
@ -1780,19 +1776,10 @@ static int alloc_f(BlockBackend *blk, int argc, char **argv)
if (count < 0) {
print_cvtnum_err(count, argv[2]);
return 0;
} else if (count > INT_MAX * BDRV_SECTOR_SIZE) {
printf("length argument cannot exceed %llu, given %s\n",
INT_MAX * BDRV_SECTOR_SIZE, argv[2]);
return 0;
}
} else {
count = BDRV_SECTOR_SIZE;
}
if (!QEMU_IS_ALIGNED(count, BDRV_SECTOR_SIZE)) {
printf("%" PRId64 " is not a sector-aligned value for 'count'\n",
count);
return 0;
}
remaining = count;
sum_alloc = 0;

View File

@ -56,7 +56,7 @@ _filter_qmp_events()
function run_qemu()
{
do_run_qemu "$@" 2>&1 | _filter_testdir | _filter_qmp | _filter_qemu \
| sed -e 's/\("actual-size":\s*\)[0-9]\+/\1SIZE/g' \
| _filter_actual_image_size \
| _filter_generated_node_ids | _filter_qmp_events
}

View File

@ -4,7 +4,6 @@ Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
wrote 512/512 bytes at offset 512
512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
qemu-img: Error while reading offset 0 of blkdebug:TEST_DIR/blkdebug.conf:TEST_DIR/t.IMGFMT: Input/output error
qemu-img: Error while reading offset 0: Input/output error
4
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
Formatting 'TEST_DIR/t.IMGFMT.2', fmt=IMGFMT size=0
@ -12,7 +11,6 @@ Formatting 'TEST_DIR/t.IMGFMT.2', fmt=IMGFMT size=0
wrote 512/512 bytes at offset 512
512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
qemu-img: Error while reading offset 0 of blkdebug:TEST_DIR/blkdebug.conf:TEST_DIR/t.IMGFMT: Input/output error
qemu-img: Error while reading offset 0 of blkdebug:TEST_DIR/blkdebug.conf:TEST_DIR/t.IMGFMT: Input/output error
Warning: Image size mismatch!
4
Cleanup

View File

@ -46,7 +46,7 @@ function run_qemu()
{
do_run_qemu "$@" 2>&1 | _filter_testdir | _filter_qmp \
| _filter_qemu | _filter_imgfmt \
| sed -e 's/\("actual-size":\s*\)[0-9]\+/\1SIZE/g'
| _filter_actual_image_size
}
size=128M

View File

@ -69,13 +69,15 @@ fi
# in B
CREATION_SIZE=$((2 * 1024 * 1024 - 48 * 1024))
# 512 is the actual test -- but it's good to test 64k as well, just to be sure.
for cluster_size in 512 64k; do
# in kB
for GROWTH_SIZE in 16 48 80; do
for create_mode in off metadata falloc full; do
for growth_mode in off metadata falloc full; do
echo "--- growth_size=$GROWTH_SIZE create_mode=$create_mode growth_mode=$growth_mode ---"
echo "--- cluster_size=$cluster_size growth_size=$GROWTH_SIZE create_mode=$create_mode growth_mode=$growth_mode ---"
IMGOPTS="preallocation=$create_mode,cluster_size=512" _make_test_img ${CREATION_SIZE}
IMGOPTS="preallocation=$create_mode,cluster_size=$cluster_size" _make_test_img ${CREATION_SIZE}
$QEMU_IMG resize -f "$IMGFMT" --preallocation=$growth_mode "$TEST_IMG" +${GROWTH_SIZE}K
host_size_0=$(get_image_size_on_host)
@ -123,6 +125,7 @@ for GROWTH_SIZE in 16 48 80; do
done
done
done
done
# success, all done
echo '*** done'

View File

@ -1,5 +1,5 @@
QA output created by 125
--- growth_size=16 create_mode=off growth_mode=off ---
--- cluster_size=512 growth_size=16 create_mode=off growth_mode=off ---
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=2048000 preallocation=off
Image resized.
wrote 2048000/2048000 bytes at offset 0
@ -7,7 +7,7 @@ wrote 2048000/2048000 bytes at offset 0
wrote 16384/16384 bytes at offset 2048000
16 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
--- growth_size=16 create_mode=off growth_mode=metadata ---
--- cluster_size=512 growth_size=16 create_mode=off growth_mode=metadata ---
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=2048000 preallocation=off
Image resized.
wrote 2048000/2048000 bytes at offset 0
@ -15,7 +15,7 @@ wrote 2048000/2048000 bytes at offset 0
wrote 16384/16384 bytes at offset 2048000
16 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
--- growth_size=16 create_mode=off growth_mode=falloc ---
--- cluster_size=512 growth_size=16 create_mode=off growth_mode=falloc ---
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=2048000 preallocation=off
Image resized.
wrote 2048000/2048000 bytes at offset 0
@ -23,7 +23,7 @@ wrote 2048000/2048000 bytes at offset 0
wrote 16384/16384 bytes at offset 2048000
16 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
--- growth_size=16 create_mode=off growth_mode=full ---
--- cluster_size=512 growth_size=16 create_mode=off growth_mode=full ---
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=2048000 preallocation=off
Image resized.
wrote 2048000/2048000 bytes at offset 0
@ -31,7 +31,7 @@ wrote 2048000/2048000 bytes at offset 0
wrote 16384/16384 bytes at offset 2048000
16 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
--- growth_size=16 create_mode=metadata growth_mode=off ---
--- cluster_size=512 growth_size=16 create_mode=metadata growth_mode=off ---
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=2048000 preallocation=metadata
Image resized.
wrote 2048000/2048000 bytes at offset 0
@ -39,7 +39,7 @@ wrote 2048000/2048000 bytes at offset 0
wrote 16384/16384 bytes at offset 2048000
16 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
--- growth_size=16 create_mode=metadata growth_mode=metadata ---
--- cluster_size=512 growth_size=16 create_mode=metadata growth_mode=metadata ---
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=2048000 preallocation=metadata
Image resized.
wrote 2048000/2048000 bytes at offset 0
@ -47,7 +47,7 @@ wrote 2048000/2048000 bytes at offset 0
wrote 16384/16384 bytes at offset 2048000
16 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
--- growth_size=16 create_mode=metadata growth_mode=falloc ---
--- cluster_size=512 growth_size=16 create_mode=metadata growth_mode=falloc ---
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=2048000 preallocation=metadata
Image resized.
wrote 2048000/2048000 bytes at offset 0
@ -55,7 +55,7 @@ wrote 2048000/2048000 bytes at offset 0
wrote 16384/16384 bytes at offset 2048000
16 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
--- growth_size=16 create_mode=metadata growth_mode=full ---
--- cluster_size=512 growth_size=16 create_mode=metadata growth_mode=full ---
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=2048000 preallocation=metadata
Image resized.
wrote 2048000/2048000 bytes at offset 0
@ -63,7 +63,7 @@ wrote 2048000/2048000 bytes at offset 0
wrote 16384/16384 bytes at offset 2048000
16 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
--- growth_size=16 create_mode=falloc growth_mode=off ---
--- cluster_size=512 growth_size=16 create_mode=falloc growth_mode=off ---
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=2048000 preallocation=falloc
Image resized.
wrote 2048000/2048000 bytes at offset 0
@ -71,7 +71,7 @@ wrote 2048000/2048000 bytes at offset 0
wrote 16384/16384 bytes at offset 2048000
16 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
--- growth_size=16 create_mode=falloc growth_mode=metadata ---
--- cluster_size=512 growth_size=16 create_mode=falloc growth_mode=metadata ---
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=2048000 preallocation=falloc
Image resized.
wrote 2048000/2048000 bytes at offset 0
@ -79,7 +79,7 @@ wrote 2048000/2048000 bytes at offset 0
wrote 16384/16384 bytes at offset 2048000
16 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
--- growth_size=16 create_mode=falloc growth_mode=falloc ---
--- cluster_size=512 growth_size=16 create_mode=falloc growth_mode=falloc ---
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=2048000 preallocation=falloc
Image resized.
wrote 2048000/2048000 bytes at offset 0
@ -87,7 +87,7 @@ wrote 2048000/2048000 bytes at offset 0
wrote 16384/16384 bytes at offset 2048000
16 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
--- growth_size=16 create_mode=falloc growth_mode=full ---
--- cluster_size=512 growth_size=16 create_mode=falloc growth_mode=full ---
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=2048000 preallocation=falloc
Image resized.
wrote 2048000/2048000 bytes at offset 0
@ -95,7 +95,7 @@ wrote 2048000/2048000 bytes at offset 0
wrote 16384/16384 bytes at offset 2048000
16 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
--- growth_size=16 create_mode=full growth_mode=off ---
--- cluster_size=512 growth_size=16 create_mode=full growth_mode=off ---
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=2048000 preallocation=full
Image resized.
wrote 2048000/2048000 bytes at offset 0
@ -103,7 +103,7 @@ wrote 2048000/2048000 bytes at offset 0
wrote 16384/16384 bytes at offset 2048000
16 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
--- growth_size=16 create_mode=full growth_mode=metadata ---
--- cluster_size=512 growth_size=16 create_mode=full growth_mode=metadata ---
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=2048000 preallocation=full
Image resized.
wrote 2048000/2048000 bytes at offset 0
@ -111,7 +111,7 @@ wrote 2048000/2048000 bytes at offset 0
wrote 16384/16384 bytes at offset 2048000
16 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
--- growth_size=16 create_mode=full growth_mode=falloc ---
--- cluster_size=512 growth_size=16 create_mode=full growth_mode=falloc ---
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=2048000 preallocation=full
Image resized.
wrote 2048000/2048000 bytes at offset 0
@ -119,7 +119,7 @@ wrote 2048000/2048000 bytes at offset 0
wrote 16384/16384 bytes at offset 2048000
16 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
--- growth_size=16 create_mode=full growth_mode=full ---
--- cluster_size=512 growth_size=16 create_mode=full growth_mode=full ---
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=2048000 preallocation=full
Image resized.
wrote 2048000/2048000 bytes at offset 0
@ -127,7 +127,7 @@ wrote 2048000/2048000 bytes at offset 0
wrote 16384/16384 bytes at offset 2048000
16 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
--- growth_size=48 create_mode=off growth_mode=off ---
--- cluster_size=512 growth_size=48 create_mode=off growth_mode=off ---
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=2048000 preallocation=off
Image resized.
wrote 2048000/2048000 bytes at offset 0
@ -135,7 +135,7 @@ wrote 2048000/2048000 bytes at offset 0
wrote 49152/49152 bytes at offset 2048000
48 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
--- growth_size=48 create_mode=off growth_mode=metadata ---
--- cluster_size=512 growth_size=48 create_mode=off growth_mode=metadata ---
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=2048000 preallocation=off
Image resized.
wrote 2048000/2048000 bytes at offset 0
@ -143,7 +143,7 @@ wrote 2048000/2048000 bytes at offset 0
wrote 49152/49152 bytes at offset 2048000
48 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
--- growth_size=48 create_mode=off growth_mode=falloc ---
--- cluster_size=512 growth_size=48 create_mode=off growth_mode=falloc ---
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=2048000 preallocation=off
Image resized.
wrote 2048000/2048000 bytes at offset 0
@ -151,7 +151,7 @@ wrote 2048000/2048000 bytes at offset 0
wrote 49152/49152 bytes at offset 2048000
48 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
--- growth_size=48 create_mode=off growth_mode=full ---
--- cluster_size=512 growth_size=48 create_mode=off growth_mode=full ---
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=2048000 preallocation=off
Image resized.
wrote 2048000/2048000 bytes at offset 0
@ -159,7 +159,7 @@ wrote 2048000/2048000 bytes at offset 0
wrote 49152/49152 bytes at offset 2048000
48 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
--- growth_size=48 create_mode=metadata growth_mode=off ---
--- cluster_size=512 growth_size=48 create_mode=metadata growth_mode=off ---
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=2048000 preallocation=metadata
Image resized.
wrote 2048000/2048000 bytes at offset 0
@ -167,7 +167,7 @@ wrote 2048000/2048000 bytes at offset 0
wrote 49152/49152 bytes at offset 2048000
48 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
--- growth_size=48 create_mode=metadata growth_mode=metadata ---
--- cluster_size=512 growth_size=48 create_mode=metadata growth_mode=metadata ---
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=2048000 preallocation=metadata
Image resized.
wrote 2048000/2048000 bytes at offset 0
@ -175,7 +175,7 @@ wrote 2048000/2048000 bytes at offset 0
wrote 49152/49152 bytes at offset 2048000
48 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
--- growth_size=48 create_mode=metadata growth_mode=falloc ---
--- cluster_size=512 growth_size=48 create_mode=metadata growth_mode=falloc ---
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=2048000 preallocation=metadata
Image resized.
wrote 2048000/2048000 bytes at offset 0
@ -183,7 +183,7 @@ wrote 2048000/2048000 bytes at offset 0
wrote 49152/49152 bytes at offset 2048000
48 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
--- growth_size=48 create_mode=metadata growth_mode=full ---
--- cluster_size=512 growth_size=48 create_mode=metadata growth_mode=full ---
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=2048000 preallocation=metadata
Image resized.
wrote 2048000/2048000 bytes at offset 0
@ -191,7 +191,7 @@ wrote 2048000/2048000 bytes at offset 0
wrote 49152/49152 bytes at offset 2048000
48 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
--- growth_size=48 create_mode=falloc growth_mode=off ---
--- cluster_size=512 growth_size=48 create_mode=falloc growth_mode=off ---
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=2048000 preallocation=falloc
Image resized.
wrote 2048000/2048000 bytes at offset 0
@ -199,7 +199,7 @@ wrote 2048000/2048000 bytes at offset 0
wrote 49152/49152 bytes at offset 2048000
48 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
--- growth_size=48 create_mode=falloc growth_mode=metadata ---
--- cluster_size=512 growth_size=48 create_mode=falloc growth_mode=metadata ---
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=2048000 preallocation=falloc
Image resized.
wrote 2048000/2048000 bytes at offset 0
@ -207,7 +207,7 @@ wrote 2048000/2048000 bytes at offset 0
wrote 49152/49152 bytes at offset 2048000
48 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
--- growth_size=48 create_mode=falloc growth_mode=falloc ---
--- cluster_size=512 growth_size=48 create_mode=falloc growth_mode=falloc ---
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=2048000 preallocation=falloc
Image resized.
wrote 2048000/2048000 bytes at offset 0
@ -215,7 +215,7 @@ wrote 2048000/2048000 bytes at offset 0
wrote 49152/49152 bytes at offset 2048000
48 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
--- growth_size=48 create_mode=falloc growth_mode=full ---
--- cluster_size=512 growth_size=48 create_mode=falloc growth_mode=full ---
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=2048000 preallocation=falloc
Image resized.
wrote 2048000/2048000 bytes at offset 0
@ -223,7 +223,7 @@ wrote 2048000/2048000 bytes at offset 0
wrote 49152/49152 bytes at offset 2048000
48 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
--- growth_size=48 create_mode=full growth_mode=off ---
--- cluster_size=512 growth_size=48 create_mode=full growth_mode=off ---
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=2048000 preallocation=full
Image resized.
wrote 2048000/2048000 bytes at offset 0
@ -231,7 +231,7 @@ wrote 2048000/2048000 bytes at offset 0
wrote 49152/49152 bytes at offset 2048000
48 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
--- growth_size=48 create_mode=full growth_mode=metadata ---
--- cluster_size=512 growth_size=48 create_mode=full growth_mode=metadata ---
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=2048000 preallocation=full
Image resized.
wrote 2048000/2048000 bytes at offset 0
@ -239,7 +239,7 @@ wrote 2048000/2048000 bytes at offset 0
wrote 49152/49152 bytes at offset 2048000
48 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
--- growth_size=48 create_mode=full growth_mode=falloc ---
--- cluster_size=512 growth_size=48 create_mode=full growth_mode=falloc ---
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=2048000 preallocation=full
Image resized.
wrote 2048000/2048000 bytes at offset 0
@ -247,7 +247,7 @@ wrote 2048000/2048000 bytes at offset 0
wrote 49152/49152 bytes at offset 2048000
48 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
--- growth_size=48 create_mode=full growth_mode=full ---
--- cluster_size=512 growth_size=48 create_mode=full growth_mode=full ---
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=2048000 preallocation=full
Image resized.
wrote 2048000/2048000 bytes at offset 0
@ -255,7 +255,7 @@ wrote 2048000/2048000 bytes at offset 0
wrote 49152/49152 bytes at offset 2048000
48 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
--- growth_size=80 create_mode=off growth_mode=off ---
--- cluster_size=512 growth_size=80 create_mode=off growth_mode=off ---
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=2048000 preallocation=off
Image resized.
wrote 2048000/2048000 bytes at offset 0
@ -263,7 +263,7 @@ wrote 2048000/2048000 bytes at offset 0
wrote 81920/81920 bytes at offset 2048000
80 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
--- growth_size=80 create_mode=off growth_mode=metadata ---
--- cluster_size=512 growth_size=80 create_mode=off growth_mode=metadata ---
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=2048000 preallocation=off
Image resized.
wrote 2048000/2048000 bytes at offset 0
@ -271,7 +271,7 @@ wrote 2048000/2048000 bytes at offset 0
wrote 81920/81920 bytes at offset 2048000
80 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
--- growth_size=80 create_mode=off growth_mode=falloc ---
--- cluster_size=512 growth_size=80 create_mode=off growth_mode=falloc ---
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=2048000 preallocation=off
Image resized.
wrote 2048000/2048000 bytes at offset 0
@ -279,7 +279,7 @@ wrote 2048000/2048000 bytes at offset 0
wrote 81920/81920 bytes at offset 2048000
80 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
--- growth_size=80 create_mode=off growth_mode=full ---
--- cluster_size=512 growth_size=80 create_mode=off growth_mode=full ---
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=2048000 preallocation=off
Image resized.
wrote 2048000/2048000 bytes at offset 0
@ -287,7 +287,7 @@ wrote 2048000/2048000 bytes at offset 0
wrote 81920/81920 bytes at offset 2048000
80 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
--- growth_size=80 create_mode=metadata growth_mode=off ---
--- cluster_size=512 growth_size=80 create_mode=metadata growth_mode=off ---
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=2048000 preallocation=metadata
Image resized.
wrote 2048000/2048000 bytes at offset 0
@ -295,7 +295,7 @@ wrote 2048000/2048000 bytes at offset 0
wrote 81920/81920 bytes at offset 2048000
80 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
--- growth_size=80 create_mode=metadata growth_mode=metadata ---
--- cluster_size=512 growth_size=80 create_mode=metadata growth_mode=metadata ---
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=2048000 preallocation=metadata
Image resized.
wrote 2048000/2048000 bytes at offset 0
@ -303,7 +303,7 @@ wrote 2048000/2048000 bytes at offset 0
wrote 81920/81920 bytes at offset 2048000
80 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
--- growth_size=80 create_mode=metadata growth_mode=falloc ---
--- cluster_size=512 growth_size=80 create_mode=metadata growth_mode=falloc ---
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=2048000 preallocation=metadata
Image resized.
wrote 2048000/2048000 bytes at offset 0
@ -311,7 +311,7 @@ wrote 2048000/2048000 bytes at offset 0
wrote 81920/81920 bytes at offset 2048000
80 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
--- growth_size=80 create_mode=metadata growth_mode=full ---
--- cluster_size=512 growth_size=80 create_mode=metadata growth_mode=full ---
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=2048000 preallocation=metadata
Image resized.
wrote 2048000/2048000 bytes at offset 0
@ -319,7 +319,7 @@ wrote 2048000/2048000 bytes at offset 0
wrote 81920/81920 bytes at offset 2048000
80 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
--- growth_size=80 create_mode=falloc growth_mode=off ---
--- cluster_size=512 growth_size=80 create_mode=falloc growth_mode=off ---
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=2048000 preallocation=falloc
Image resized.
wrote 2048000/2048000 bytes at offset 0
@ -327,7 +327,7 @@ wrote 2048000/2048000 bytes at offset 0
wrote 81920/81920 bytes at offset 2048000
80 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
--- growth_size=80 create_mode=falloc growth_mode=metadata ---
--- cluster_size=512 growth_size=80 create_mode=falloc growth_mode=metadata ---
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=2048000 preallocation=falloc
Image resized.
wrote 2048000/2048000 bytes at offset 0
@ -335,7 +335,7 @@ wrote 2048000/2048000 bytes at offset 0
wrote 81920/81920 bytes at offset 2048000
80 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
--- growth_size=80 create_mode=falloc growth_mode=falloc ---
--- cluster_size=512 growth_size=80 create_mode=falloc growth_mode=falloc ---
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=2048000 preallocation=falloc
Image resized.
wrote 2048000/2048000 bytes at offset 0
@ -343,7 +343,7 @@ wrote 2048000/2048000 bytes at offset 0
wrote 81920/81920 bytes at offset 2048000
80 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
--- growth_size=80 create_mode=falloc growth_mode=full ---
--- cluster_size=512 growth_size=80 create_mode=falloc growth_mode=full ---
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=2048000 preallocation=falloc
Image resized.
wrote 2048000/2048000 bytes at offset 0
@ -351,7 +351,7 @@ wrote 2048000/2048000 bytes at offset 0
wrote 81920/81920 bytes at offset 2048000
80 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
--- growth_size=80 create_mode=full growth_mode=off ---
--- cluster_size=512 growth_size=80 create_mode=full growth_mode=off ---
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=2048000 preallocation=full
Image resized.
wrote 2048000/2048000 bytes at offset 0
@ -359,7 +359,7 @@ wrote 2048000/2048000 bytes at offset 0
wrote 81920/81920 bytes at offset 2048000
80 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
--- growth_size=80 create_mode=full growth_mode=metadata ---
--- cluster_size=512 growth_size=80 create_mode=full growth_mode=metadata ---
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=2048000 preallocation=full
Image resized.
wrote 2048000/2048000 bytes at offset 0
@ -367,7 +367,7 @@ wrote 2048000/2048000 bytes at offset 0
wrote 81920/81920 bytes at offset 2048000
80 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
--- growth_size=80 create_mode=full growth_mode=falloc ---
--- cluster_size=512 growth_size=80 create_mode=full growth_mode=falloc ---
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=2048000 preallocation=full
Image resized.
wrote 2048000/2048000 bytes at offset 0
@ -375,7 +375,391 @@ wrote 2048000/2048000 bytes at offset 0
wrote 81920/81920 bytes at offset 2048000
80 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
--- growth_size=80 create_mode=full growth_mode=full ---
--- cluster_size=512 growth_size=80 create_mode=full growth_mode=full ---
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=2048000 preallocation=full
Image resized.
wrote 2048000/2048000 bytes at offset 0
1.953 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
wrote 81920/81920 bytes at offset 2048000
80 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
--- cluster_size=64k growth_size=16 create_mode=off growth_mode=off ---
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=2048000 preallocation=off
Image resized.
wrote 2048000/2048000 bytes at offset 0
1.953 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
wrote 16384/16384 bytes at offset 2048000
16 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
--- cluster_size=64k growth_size=16 create_mode=off growth_mode=metadata ---
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=2048000 preallocation=off
Image resized.
wrote 2048000/2048000 bytes at offset 0
1.953 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
wrote 16384/16384 bytes at offset 2048000
16 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
--- cluster_size=64k growth_size=16 create_mode=off growth_mode=falloc ---
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=2048000 preallocation=off
Image resized.
wrote 2048000/2048000 bytes at offset 0
1.953 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
wrote 16384/16384 bytes at offset 2048000
16 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
--- cluster_size=64k growth_size=16 create_mode=off growth_mode=full ---
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=2048000 preallocation=off
Image resized.
wrote 2048000/2048000 bytes at offset 0
1.953 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
wrote 16384/16384 bytes at offset 2048000
16 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
--- cluster_size=64k growth_size=16 create_mode=metadata growth_mode=off ---
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=2048000 preallocation=metadata
Image resized.
wrote 2048000/2048000 bytes at offset 0
1.953 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
wrote 16384/16384 bytes at offset 2048000
16 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
--- cluster_size=64k growth_size=16 create_mode=metadata growth_mode=metadata ---
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=2048000 preallocation=metadata
Image resized.
wrote 2048000/2048000 bytes at offset 0
1.953 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
wrote 16384/16384 bytes at offset 2048000
16 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
--- cluster_size=64k growth_size=16 create_mode=metadata growth_mode=falloc ---
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=2048000 preallocation=metadata
Image resized.
wrote 2048000/2048000 bytes at offset 0
1.953 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
wrote 16384/16384 bytes at offset 2048000
16 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
--- cluster_size=64k growth_size=16 create_mode=metadata growth_mode=full ---
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=2048000 preallocation=metadata
Image resized.
wrote 2048000/2048000 bytes at offset 0
1.953 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
wrote 16384/16384 bytes at offset 2048000
16 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
--- cluster_size=64k growth_size=16 create_mode=falloc growth_mode=off ---
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=2048000 preallocation=falloc
Image resized.
wrote 2048000/2048000 bytes at offset 0
1.953 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
wrote 16384/16384 bytes at offset 2048000
16 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
--- cluster_size=64k growth_size=16 create_mode=falloc growth_mode=metadata ---
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=2048000 preallocation=falloc
Image resized.
wrote 2048000/2048000 bytes at offset 0
1.953 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
wrote 16384/16384 bytes at offset 2048000
16 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
--- cluster_size=64k growth_size=16 create_mode=falloc growth_mode=falloc ---
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=2048000 preallocation=falloc
Image resized.
wrote 2048000/2048000 bytes at offset 0
1.953 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
wrote 16384/16384 bytes at offset 2048000
16 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
--- cluster_size=64k growth_size=16 create_mode=falloc growth_mode=full ---
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=2048000 preallocation=falloc
Image resized.
wrote 2048000/2048000 bytes at offset 0
1.953 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
wrote 16384/16384 bytes at offset 2048000
16 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
--- cluster_size=64k growth_size=16 create_mode=full growth_mode=off ---
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=2048000 preallocation=full
Image resized.
wrote 2048000/2048000 bytes at offset 0
1.953 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
wrote 16384/16384 bytes at offset 2048000
16 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
--- cluster_size=64k growth_size=16 create_mode=full growth_mode=metadata ---
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=2048000 preallocation=full
Image resized.
wrote 2048000/2048000 bytes at offset 0
1.953 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
wrote 16384/16384 bytes at offset 2048000
16 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
--- cluster_size=64k growth_size=16 create_mode=full growth_mode=falloc ---
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=2048000 preallocation=full
Image resized.
wrote 2048000/2048000 bytes at offset 0
1.953 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
wrote 16384/16384 bytes at offset 2048000
16 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
--- cluster_size=64k growth_size=16 create_mode=full growth_mode=full ---
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=2048000 preallocation=full
Image resized.
wrote 2048000/2048000 bytes at offset 0
1.953 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
wrote 16384/16384 bytes at offset 2048000
16 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
--- cluster_size=64k growth_size=48 create_mode=off growth_mode=off ---
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=2048000 preallocation=off
Image resized.
wrote 2048000/2048000 bytes at offset 0
1.953 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
wrote 49152/49152 bytes at offset 2048000
48 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
--- cluster_size=64k growth_size=48 create_mode=off growth_mode=metadata ---
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=2048000 preallocation=off
Image resized.
wrote 2048000/2048000 bytes at offset 0
1.953 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
wrote 49152/49152 bytes at offset 2048000
48 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
--- cluster_size=64k growth_size=48 create_mode=off growth_mode=falloc ---
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=2048000 preallocation=off
Image resized.
wrote 2048000/2048000 bytes at offset 0
1.953 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
wrote 49152/49152 bytes at offset 2048000
48 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
--- cluster_size=64k growth_size=48 create_mode=off growth_mode=full ---
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=2048000 preallocation=off
Image resized.
wrote 2048000/2048000 bytes at offset 0
1.953 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
wrote 49152/49152 bytes at offset 2048000
48 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
--- cluster_size=64k growth_size=48 create_mode=metadata growth_mode=off ---
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=2048000 preallocation=metadata
Image resized.
wrote 2048000/2048000 bytes at offset 0
1.953 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
wrote 49152/49152 bytes at offset 2048000
48 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
--- cluster_size=64k growth_size=48 create_mode=metadata growth_mode=metadata ---
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=2048000 preallocation=metadata
Image resized.
wrote 2048000/2048000 bytes at offset 0
1.953 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
wrote 49152/49152 bytes at offset 2048000
48 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
--- cluster_size=64k growth_size=48 create_mode=metadata growth_mode=falloc ---
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=2048000 preallocation=metadata
Image resized.
wrote 2048000/2048000 bytes at offset 0
1.953 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
wrote 49152/49152 bytes at offset 2048000
48 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
--- cluster_size=64k growth_size=48 create_mode=metadata growth_mode=full ---
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=2048000 preallocation=metadata
Image resized.
wrote 2048000/2048000 bytes at offset 0
1.953 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
wrote 49152/49152 bytes at offset 2048000
48 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
--- cluster_size=64k growth_size=48 create_mode=falloc growth_mode=off ---
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=2048000 preallocation=falloc
Image resized.
wrote 2048000/2048000 bytes at offset 0
1.953 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
wrote 49152/49152 bytes at offset 2048000
48 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
--- cluster_size=64k growth_size=48 create_mode=falloc growth_mode=metadata ---
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=2048000 preallocation=falloc
Image resized.
wrote 2048000/2048000 bytes at offset 0
1.953 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
wrote 49152/49152 bytes at offset 2048000
48 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
--- cluster_size=64k growth_size=48 create_mode=falloc growth_mode=falloc ---
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=2048000 preallocation=falloc
Image resized.
wrote 2048000/2048000 bytes at offset 0
1.953 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
wrote 49152/49152 bytes at offset 2048000
48 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
--- cluster_size=64k growth_size=48 create_mode=falloc growth_mode=full ---
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=2048000 preallocation=falloc
Image resized.
wrote 2048000/2048000 bytes at offset 0
1.953 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
wrote 49152/49152 bytes at offset 2048000
48 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
--- cluster_size=64k growth_size=48 create_mode=full growth_mode=off ---
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=2048000 preallocation=full
Image resized.
wrote 2048000/2048000 bytes at offset 0
1.953 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
wrote 49152/49152 bytes at offset 2048000
48 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
--- cluster_size=64k growth_size=48 create_mode=full growth_mode=metadata ---
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=2048000 preallocation=full
Image resized.
wrote 2048000/2048000 bytes at offset 0
1.953 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
wrote 49152/49152 bytes at offset 2048000
48 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
--- cluster_size=64k growth_size=48 create_mode=full growth_mode=falloc ---
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=2048000 preallocation=full
Image resized.
wrote 2048000/2048000 bytes at offset 0
1.953 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
wrote 49152/49152 bytes at offset 2048000
48 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
--- cluster_size=64k growth_size=48 create_mode=full growth_mode=full ---
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=2048000 preallocation=full
Image resized.
wrote 2048000/2048000 bytes at offset 0
1.953 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
wrote 49152/49152 bytes at offset 2048000
48 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
--- cluster_size=64k growth_size=80 create_mode=off growth_mode=off ---
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=2048000 preallocation=off
Image resized.
wrote 2048000/2048000 bytes at offset 0
1.953 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
wrote 81920/81920 bytes at offset 2048000
80 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
--- cluster_size=64k growth_size=80 create_mode=off growth_mode=metadata ---
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=2048000 preallocation=off
Image resized.
wrote 2048000/2048000 bytes at offset 0
1.953 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
wrote 81920/81920 bytes at offset 2048000
80 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
--- cluster_size=64k growth_size=80 create_mode=off growth_mode=falloc ---
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=2048000 preallocation=off
Image resized.
wrote 2048000/2048000 bytes at offset 0
1.953 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
wrote 81920/81920 bytes at offset 2048000
80 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
--- cluster_size=64k growth_size=80 create_mode=off growth_mode=full ---
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=2048000 preallocation=off
Image resized.
wrote 2048000/2048000 bytes at offset 0
1.953 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
wrote 81920/81920 bytes at offset 2048000
80 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
--- cluster_size=64k growth_size=80 create_mode=metadata growth_mode=off ---
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=2048000 preallocation=metadata
Image resized.
wrote 2048000/2048000 bytes at offset 0
1.953 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
wrote 81920/81920 bytes at offset 2048000
80 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
--- cluster_size=64k growth_size=80 create_mode=metadata growth_mode=metadata ---
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=2048000 preallocation=metadata
Image resized.
wrote 2048000/2048000 bytes at offset 0
1.953 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
wrote 81920/81920 bytes at offset 2048000
80 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
--- cluster_size=64k growth_size=80 create_mode=metadata growth_mode=falloc ---
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=2048000 preallocation=metadata
Image resized.
wrote 2048000/2048000 bytes at offset 0
1.953 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
wrote 81920/81920 bytes at offset 2048000
80 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
--- cluster_size=64k growth_size=80 create_mode=metadata growth_mode=full ---
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=2048000 preallocation=metadata
Image resized.
wrote 2048000/2048000 bytes at offset 0
1.953 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
wrote 81920/81920 bytes at offset 2048000
80 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
--- cluster_size=64k growth_size=80 create_mode=falloc growth_mode=off ---
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=2048000 preallocation=falloc
Image resized.
wrote 2048000/2048000 bytes at offset 0
1.953 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
wrote 81920/81920 bytes at offset 2048000
80 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
--- cluster_size=64k growth_size=80 create_mode=falloc growth_mode=metadata ---
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=2048000 preallocation=falloc
Image resized.
wrote 2048000/2048000 bytes at offset 0
1.953 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
wrote 81920/81920 bytes at offset 2048000
80 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
--- cluster_size=64k growth_size=80 create_mode=falloc growth_mode=falloc ---
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=2048000 preallocation=falloc
Image resized.
wrote 2048000/2048000 bytes at offset 0
1.953 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
wrote 81920/81920 bytes at offset 2048000
80 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
--- cluster_size=64k growth_size=80 create_mode=falloc growth_mode=full ---
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=2048000 preallocation=falloc
Image resized.
wrote 2048000/2048000 bytes at offset 0
1.953 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
wrote 81920/81920 bytes at offset 2048000
80 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
--- cluster_size=64k growth_size=80 create_mode=full growth_mode=off ---
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=2048000 preallocation=full
Image resized.
wrote 2048000/2048000 bytes at offset 0
1.953 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
wrote 81920/81920 bytes at offset 2048000
80 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
--- cluster_size=64k growth_size=80 create_mode=full growth_mode=metadata ---
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=2048000 preallocation=full
Image resized.
wrote 2048000/2048000 bytes at offset 0
1.953 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
wrote 81920/81920 bytes at offset 2048000
80 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
--- cluster_size=64k growth_size=80 create_mode=full growth_mode=falloc ---
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=2048000 preallocation=full
Image resized.
wrote 2048000/2048000 bytes at offset 0
1.953 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
wrote 81920/81920 bytes at offset 2048000
80 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
--- cluster_size=64k growth_size=80 create_mode=full growth_mode=full ---
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=2048000 preallocation=full
Image resized.
wrote 2048000/2048000 bytes at offset 0

97
tests/qemu-iotests/127 Executable file
View File

@ -0,0 +1,97 @@
#!/bin/bash
#
# Test case for mirroring with dataplane
#
# Copyright (C) 2017 Red Hat, Inc.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
# creator
owner=mreitz@redhat.com
seq=$(basename $0)
echo "QA output created by $seq"
here=$PWD
status=1 # failure is the default!
_cleanup()
{
_cleanup_qemu
_cleanup_test_img
_rm_test_img "$TEST_IMG.overlay0"
_rm_test_img "$TEST_IMG.overlay1"
}
trap "_cleanup; exit \$status" 0 1 2 3 15
# get standard environment, filters and qemu instance handling
. ./common.rc
. ./common.filter
. ./common.qemu
_supported_fmt qcow2
_supported_proto file
_supported_os Linux
IMG_SIZE=64K
_make_test_img $IMG_SIZE
TEST_IMG="$TEST_IMG.overlay0" _make_test_img -b "$TEST_IMG" $IMG_SIZE
TEST_IMG="$TEST_IMG.overlay1" _make_test_img -b "$TEST_IMG" $IMG_SIZE
# So that we actually have something to mirror and the job does not return
# immediately (which may be bad because then we cannot know whether the
# 'return' or the 'BLOCK_JOB_READY' comes first).
$QEMU_IO -c 'write 0 42' "$TEST_IMG.overlay0" | _filter_qemu_io
# We cannot use virtio-blk here because that does not actually set the attached
# BB's AioContext in qtest mode
_launch_qemu \
-object iothread,id=iothr \
-blockdev node-name=source,driver=$IMGFMT,file.driver=file,file.filename="$TEST_IMG.overlay0" \
-device virtio-scsi,id=scsi-bus,iothread=iothr \
-device scsi-hd,bus=scsi-bus.0,drive=source
_send_qemu_cmd $QEMU_HANDLE \
"{ 'execute': 'qmp_capabilities' }" \
'return'
_send_qemu_cmd $QEMU_HANDLE \
"{ 'execute': 'drive-mirror',
'arguments': {
'job-id': 'mirror',
'device': 'source',
'target': '$TEST_IMG.overlay1',
'mode': 'existing',
'sync': 'top'
} }" \
'BLOCK_JOB_READY'
# The backing BDS should be assigned the overlay's AioContext
_send_qemu_cmd $QEMU_HANDLE \
"{ 'execute': 'block-job-complete',
'arguments': { 'device': 'mirror' } }" \
'BLOCK_JOB_COMPLETED'
_send_qemu_cmd $QEMU_HANDLE \
"{ 'execute': 'quit' }" \
'return'
wait=yes _cleanup_qemu
# success, all done
echo '*** done'
rm -f $seq.full
status=0

View File

@ -0,0 +1,14 @@
QA output created by 127
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=65536
Formatting 'TEST_DIR/t.IMGFMT.overlay0', fmt=IMGFMT size=65536 backing_file=TEST_DIR/t.IMGFMT
Formatting 'TEST_DIR/t.IMGFMT.overlay1', fmt=IMGFMT size=65536 backing_file=TEST_DIR/t.IMGFMT
wrote 42/42 bytes at offset 0
42 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
{"return": {}}
{"return": {}}
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_READY", "data": {"device": "mirror", "len": 65536, "offset": 65536, "speed": 0, "type": "mirror"}}
{"return": {}}
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_COMPLETED", "data": {"device": "mirror", "len": 65536, "offset": 65536, "speed": 0, "type": "mirror"}}
{"return": {}}
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false}}
*** done

View File

@ -51,7 +51,7 @@ echo "== setting up files =="
TEST_IMG="$TEST_IMG.base" _make_test_img $size
$QEMU_IO -c "write -P 11 0 $size" "$TEST_IMG.base" | _filter_qemu_io
_make_test_img -b "$TEST_IMG.base"
$QEMU_IO -c "write -P 22 0 $size" "$TEST_IMG" | _filter_qemu_io
$QEMU_IO -c "write -P 22 0 110M" "$TEST_IMG" | _filter_qemu_io
# Limited to 64k max-transfer
echo
@ -81,6 +81,13 @@ limits=align=512,opt-write-zero=15M,max-write-zero=15M,opt-discard=15M,max-disca
$QEMU_IO -c "open -o $options,$limits blkdebug::$TEST_IMG" \
-c "discard 80000001 30M" | _filter_qemu_io
echo
echo "== block status smaller than alignment =="
limits=align=4k
$QEMU_IO -c "open -o $options,$limits blkdebug::$TEST_IMG" \
-c "alloc 1 1" -c "alloc 0x6dffff0 1000" -c "alloc 127m 5P" \
-c map | _filter_qemu_io
echo
echo "== verify image content =="
@ -103,7 +110,8 @@ function verify_io()
echo read -P 0 32M 32M
echo read -P 22 64M 13M
echo read -P $discarded 77M 29M
echo read -P 22 106M 22M
echo read -P 22 106M 4M
echo read -P 11 110M 18M
}
verify_io | $QEMU_IO -r "$TEST_IMG" | _filter_qemu_io

View File

@ -5,8 +5,8 @@ Formatting 'TEST_DIR/t.IMGFMT.base', fmt=IMGFMT size=134217728
wrote 134217728/134217728 bytes at offset 0
128 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728 backing_file=TEST_DIR/t.IMGFMT.base
wrote 134217728/134217728 bytes at offset 0
128 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
wrote 115343360/115343360 bytes at offset 0
110 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
== constrained alignment and max-transfer ==
wrote 131072/131072 bytes at offset 1000
@ -26,6 +26,13 @@ wrote 33554432/33554432 bytes at offset 33554432
discard 31457280/31457280 bytes at offset 80000001
30 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
== block status smaller than alignment ==
1/1 bytes allocated at offset 1 bytes
16/1000 bytes allocated at offset 110 MiB
0/1048576 bytes allocated at offset 127 MiB
110 MiB (0x6e00000) bytes allocated at offset 0 bytes (0x0)
18 MiB (0x1200000) bytes not allocated at offset 110 MiB (0x6e00000)
== verify image content ==
read 1000/1000 bytes at offset 0
1000 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
@ -43,12 +50,14 @@ read 13631488/13631488 bytes at offset 67108864
13 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
read 30408704/30408704 bytes at offset 80740352
29 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
read 23068672/23068672 bytes at offset 111149056
22 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
read 4194304/4194304 bytes at offset 111149056
4 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
read 18874368/18874368 bytes at offset 115343360
18 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
Offset Length File
0 0x800000 TEST_DIR/t.IMGFMT
0x900000 0x2400000 TEST_DIR/t.IMGFMT
0x3c00000 0x1100000 TEST_DIR/t.IMGFMT
0x6a00000 0x1600000 TEST_DIR/t.IMGFMT
0x6a00000 0x400000 TEST_DIR/t.IMGFMT
No errors were found on the image.
*** done

View File

@ -51,7 +51,8 @@ function do_run_qemu()
function run_qemu()
{
do_run_qemu "$@" 2>&1 | _filter_testdir | _filter_qemu | _filter_qmp\
| _filter_qemu_io | _filter_generated_node_ids
| _filter_qemu_io | _filter_generated_node_ids \
| _filter_actual_image_size
}
_make_test_img 64M

View File

@ -32,7 +32,7 @@ Testing:
"filename": "json:{\"throttle-group\": \"group0\", \"driver\": \"throttle\", \"file\": {\"driver\": \"qcow2\", \"file\": {\"driver\": \"file\", \"filename\": \"TEST_DIR/t.qcow2\"}}}",
"cluster-size": 65536,
"format": "throttle",
"actual-size": 200704,
"actual-size": SIZE,
"dirty-flag": false
},
"iops_wr": 0,
@ -62,7 +62,7 @@ Testing:
"filename": "TEST_DIR/t.qcow2",
"cluster-size": 65536,
"format": "qcow2",
"actual-size": 200704,
"actual-size": SIZE,
"format-specific": {
"type": "qcow2",
"data": {
@ -100,7 +100,7 @@ Testing:
"virtual-size": 197120,
"filename": "TEST_DIR/t.qcow2",
"format": "file",
"actual-size": 200704,
"actual-size": SIZE,
"dirty-flag": false
},
"iops_wr": 0,

View File

@ -56,7 +56,8 @@ echo === Preparing and starting VM ===
echo
TEST_IMG="${TEST_IMG}.base" _make_test_img $size
TEST_IMG="${TEST_IMG}.mid" _make_test_img -b "${TEST_IMG}.base"
IMGOPTS=$(_optstr_add "$IMGOPTS" "backing_fmt=$IMGFMT") \
TEST_IMG="${TEST_IMG}.mid" _make_test_img -b "${TEST_IMG}.base"
_make_test_img -b "${TEST_IMG}.mid"
TEST_IMG="${TEST_IMG}.ovl2" _make_test_img -b "${TEST_IMG}.mid"
@ -91,7 +92,7 @@ echo === Check that both top and top2 point to base now ===
echo
_send_qemu_cmd $h "{ 'execute': 'query-named-block-nodes' }" "^}" |
_filter_generated_node_ids
_filter_generated_node_ids | _filter_actual_image_size
_send_qemu_cmd $h "{ 'execute': 'quit' }" "^}"
wait=1 _cleanup_qemu
@ -139,7 +140,7 @@ echo === Check that both top and top2 point to base now ===
echo
_send_qemu_cmd $h "{ 'execute': 'query-named-block-nodes' }" "^}" |
_filter_generated_node_ids
_filter_generated_node_ids | _filter_actual_image_size
_send_qemu_cmd $h "{ 'execute': 'quit' }" "^}"
wait=1 _cleanup_qemu

View File

@ -3,7 +3,7 @@ QA output created by 191
=== Preparing and starting VM ===
Formatting 'TEST_DIR/t.IMGFMT.base', fmt=IMGFMT size=67108864
Formatting 'TEST_DIR/t.IMGFMT.mid', fmt=IMGFMT size=67108864 backing_file=TEST_DIR/t.IMGFMT.base
Formatting 'TEST_DIR/t.IMGFMT.mid', fmt=IMGFMT size=67108864 backing_file=TEST_DIR/t.IMGFMT.base backing_fmt=IMGFMT
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864 backing_file=TEST_DIR/t.IMGFMT.mid
Formatting 'TEST_DIR/t.IMGFMT.ovl2', fmt=IMGFMT size=67108864 backing_file=TEST_DIR/t.IMGFMT.mid
wrote 65536/65536 bytes at offset 1048576
@ -47,7 +47,7 @@ wrote 65536/65536 bytes at offset 1048576
"filename": "TEST_DIR/t.qcow2.base",
"cluster-size": 65536,
"format": "qcow2",
"actual-size": 397312,
"actual-size": SIZE,
"format-specific": {
"type": "qcow2",
"data": {
@ -64,7 +64,7 @@ wrote 65536/65536 bytes at offset 1048576
"filename": "TEST_DIR/t.qcow2.ovl2",
"cluster-size": 65536,
"format": "qcow2",
"actual-size": 200704,
"actual-size": SIZE,
"format-specific": {
"type": "qcow2",
"data": {
@ -105,7 +105,7 @@ wrote 65536/65536 bytes at offset 1048576
"virtual-size": 197120,
"filename": "TEST_DIR/t.qcow2.ovl2",
"format": "file",
"actual-size": 200704,
"actual-size": SIZE,
"dirty-flag": false
},
"iops_wr": 0,
@ -136,7 +136,7 @@ wrote 65536/65536 bytes at offset 1048576
"filename": "TEST_DIR/t.qcow2.base",
"cluster-size": 65536,
"format": "qcow2",
"actual-size": 397312,
"actual-size": SIZE,
"format-specific": {
"type": "qcow2",
"data": {
@ -153,7 +153,7 @@ wrote 65536/65536 bytes at offset 1048576
"filename": "TEST_DIR/t.qcow2",
"cluster-size": 65536,
"format": "qcow2",
"actual-size": 200704,
"actual-size": SIZE,
"format-specific": {
"type": "qcow2",
"data": {
@ -194,7 +194,7 @@ wrote 65536/65536 bytes at offset 1048576
"virtual-size": 197120,
"filename": "TEST_DIR/t.qcow2",
"format": "file",
"actual-size": 200704,
"actual-size": SIZE,
"dirty-flag": false
},
"iops_wr": 0,
@ -225,7 +225,7 @@ wrote 65536/65536 bytes at offset 1048576
"filename": "TEST_DIR/t.qcow2.base",
"cluster-size": 65536,
"format": "qcow2",
"actual-size": 397312,
"actual-size": SIZE,
"format-specific": {
"type": "qcow2",
"data": {
@ -242,7 +242,7 @@ wrote 65536/65536 bytes at offset 1048576
"filename": "TEST_DIR/t.qcow2.mid",
"cluster-size": 65536,
"format": "qcow2",
"actual-size": 397312,
"actual-size": SIZE,
"format-specific": {
"type": "qcow2",
"data": {
@ -283,7 +283,7 @@ wrote 65536/65536 bytes at offset 1048576
"virtual-size": 393216,
"filename": "TEST_DIR/t.qcow2.mid",
"format": "file",
"actual-size": 397312,
"actual-size": SIZE,
"dirty-flag": false
},
"iops_wr": 0,
@ -313,7 +313,7 @@ wrote 65536/65536 bytes at offset 1048576
"filename": "TEST_DIR/t.qcow2.base",
"cluster-size": 65536,
"format": "qcow2",
"actual-size": 397312,
"actual-size": SIZE,
"format-specific": {
"type": "qcow2",
"data": {
@ -351,7 +351,7 @@ wrote 65536/65536 bytes at offset 1048576
"virtual-size": 393216,
"filename": "TEST_DIR/t.qcow2.base",
"format": "file",
"actual-size": 397312,
"actual-size": SIZE,
"dirty-flag": false
},
"iops_wr": 0,
@ -450,7 +450,7 @@ wrote 65536/65536 bytes at offset 1048576
"filename": "TEST_DIR/t.qcow2.base",
"cluster-size": 65536,
"format": "qcow2",
"actual-size": 397312,
"actual-size": SIZE,
"format-specific": {
"type": "qcow2",
"data": {
@ -467,7 +467,7 @@ wrote 65536/65536 bytes at offset 1048576
"filename": "TEST_DIR/t.qcow2.ovl2",
"cluster-size": 65536,
"format": "qcow2",
"actual-size": 200704,
"actual-size": SIZE,
"format-specific": {
"type": "qcow2",
"data": {
@ -508,7 +508,7 @@ wrote 65536/65536 bytes at offset 1048576
"virtual-size": 197120,
"filename": "TEST_DIR/t.qcow2.ovl2",
"format": "file",
"actual-size": 200704,
"actual-size": SIZE,
"dirty-flag": false
},
"iops_wr": 0,
@ -540,7 +540,7 @@ wrote 65536/65536 bytes at offset 1048576
"filename": "TEST_DIR/t.qcow2.base",
"cluster-size": 65536,
"format": "qcow2",
"actual-size": 397312,
"actual-size": SIZE,
"format-specific": {
"type": "qcow2",
"data": {
@ -557,7 +557,7 @@ wrote 65536/65536 bytes at offset 1048576
"filename": "TEST_DIR/t.qcow2.ovl2",
"cluster-size": 65536,
"format": "qcow2",
"actual-size": 200704,
"actual-size": SIZE,
"format-specific": {
"type": "qcow2",
"data": {
@ -576,7 +576,7 @@ wrote 65536/65536 bytes at offset 1048576
"filename": "TEST_DIR/t.qcow2.ovl3",
"cluster-size": 65536,
"format": "qcow2",
"actual-size": 200704,
"actual-size": SIZE,
"format-specific": {
"type": "qcow2",
"data": {
@ -617,7 +617,7 @@ wrote 65536/65536 bytes at offset 1048576
"virtual-size": 197120,
"filename": "TEST_DIR/t.qcow2.ovl3",
"format": "file",
"actual-size": 200704,
"actual-size": SIZE,
"dirty-flag": false
},
"iops_wr": 0,
@ -647,7 +647,7 @@ wrote 65536/65536 bytes at offset 1048576
"filename": "TEST_DIR/t.qcow2.base",
"cluster-size": 65536,
"format": "qcow2",
"actual-size": 397312,
"actual-size": SIZE,
"format-specific": {
"type": "qcow2",
"data": {
@ -685,7 +685,7 @@ wrote 65536/65536 bytes at offset 1048576
"virtual-size": 393216,
"filename": "TEST_DIR/t.qcow2.base",
"format": "file",
"actual-size": 397312,
"actual-size": SIZE,
"dirty-flag": false
},
"iops_wr": 0,
@ -716,7 +716,7 @@ wrote 65536/65536 bytes at offset 1048576
"filename": "TEST_DIR/t.qcow2.base",
"cluster-size": 65536,
"format": "qcow2",
"actual-size": 397312,
"actual-size": SIZE,
"format-specific": {
"type": "qcow2",
"data": {
@ -733,7 +733,7 @@ wrote 65536/65536 bytes at offset 1048576
"filename": "TEST_DIR/t.qcow2",
"cluster-size": 65536,
"format": "qcow2",
"actual-size": 200704,
"actual-size": SIZE,
"format-specific": {
"type": "qcow2",
"data": {
@ -774,7 +774,7 @@ wrote 65536/65536 bytes at offset 1048576
"virtual-size": 197120,
"filename": "TEST_DIR/t.qcow2",
"format": "file",
"actual-size": 200704,
"actual-size": SIZE,
"dirty-flag": false
},
"iops_wr": 0,

View File

@ -105,6 +105,12 @@ _filter_block_job_len()
sed -e 's/, "len": [0-9]\+,/, "len": LEN,/g'
}
# replace actual image size (depends on the host filesystem)
_filter_actual_image_size()
{
sed -s 's/\("actual-size":\s*\)[0-9]\+/\1SIZE/g'
}
# replace driver-specific options in the "Formatting..." line
_filter_img_create()
{

View File

@ -133,6 +133,7 @@
124 rw auto backing
125 rw auto
126 rw auto backing
127 rw auto backing quick
128 rw auto quick
129 rw auto quick
130 rw auto quick