Block layer patches:
- Fix slow pre-zeroing in qemu-img convert - Test case for block job pausing on I/O errors -----BEGIN PGP SIGNATURE----- iQIcBAABAgAGBQJcmkUAAAoJEH8JsnLIjy/WYWcQAJaDWuowiFZ8myUcv46+A3tE WjTUrXKe+hUYUzuEWdpIHjvx4paogfu0Qo+8EdBWphYsSKPqqxQb0wFMtaxD4fC6 jN3p/7LYyc2ce6puquX7yoBvXcIiTZimTLodf4Go3t4eDAcR88X75S0GSLqTWFT0 qWpxOpDlWhBACPRAjQCQT4dez3rBtgaD6IXmBXX0BQjzsDtRCeg68PZyN1WAcT20 KosatuEyaO6H2N9LbBMFFvfpO8rTaObY9F4jKFuFKw4iwjaWe8zCeoCXVBd7r+G4 vVzvCC+JZN/2KgBi8bX2CjID/CGiSOWNsVmBjylWWdWUsql/z0k1c9taqULfb4t9 unUIbsK/iATW5Pa1rBkoFK2spS5UEAMyGyqx5dtJoKOq8UMdheWYrqNRAgZ4jbg0 IE08Qgdh9+gA9mVHvy880ZAlPSPsUegeYGAZ/kS1yeNqkts2oStFKwyYZ1MXNUyJ rVTUtT1Zs8oxKg8mVQ0tq6M+boDksPhnB995eVuQy5Uo5pI8viXrceX1QcrRNFZP 7FEoc0lMPlPWHbGuJPamxKLLKcAKrp7aVGfWb4CGvGKoKDNcs8reQ3odPXLdQ1qa LjFnOos6EXf3Rrl5d5jXEPdmjrw6oPmTPiOReie+ktwPuzNFV3wZHnTrbqoYAoWl blKdSV1xhTZRkMy4aCbz =wQ4/ -----END PGP SIGNATURE----- Merge remote-tracking branch 'remotes/kevin/tags/for-upstream' into staging Block layer patches: - Fix slow pre-zeroing in qemu-img convert - Test case for block job pausing on I/O errors # gpg: Signature made Tue 26 Mar 2019 15:28:00 GMT # gpg: using RSA key 7F09B272C88F2FD6 # gpg: Good signature from "Kevin Wolf <kwolf@redhat.com>" [full] # Primary key fingerprint: DC3D EB15 9A9A F95D 3D74 56FE 7F09 B272 C88F 2FD6 * remotes/kevin/tags/for-upstream: qemu-io: Add write -n for BDRV_REQ_NO_FALLBACK qemu-img: Use BDRV_REQ_NO_FALLBACK for pre-zeroing file-posix: Support BDRV_REQ_NO_FALLBACK for zero writes block: Advertise BDRV_REQ_NO_FALLBACK in filter drivers block: Add BDRV_REQ_NO_FALLBACK block: Remove error messages in bdrv_make_zero() iotests: add 248: test resume mirror after auto pause on ENOSPC Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
commit
1bd2e35c29
@ -401,7 +401,7 @@ static int blkdebug_open(BlockDriverState *bs, QDict *options, int flags,
|
||||
bs->supported_write_flags = BDRV_REQ_WRITE_UNCHANGED |
|
||||
(BDRV_REQ_FUA & bs->file->bs->supported_write_flags);
|
||||
bs->supported_zero_flags = BDRV_REQ_WRITE_UNCHANGED |
|
||||
((BDRV_REQ_FUA | BDRV_REQ_MAY_UNMAP) &
|
||||
((BDRV_REQ_FUA | BDRV_REQ_MAY_UNMAP | BDRV_REQ_NO_FALLBACK) &
|
||||
bs->file->bs->supported_zero_flags);
|
||||
ret = -EINVAL;
|
||||
|
||||
|
@ -34,12 +34,11 @@ static int cor_open(BlockDriverState *bs, QDict *options, int flags,
|
||||
}
|
||||
|
||||
bs->supported_write_flags = BDRV_REQ_WRITE_UNCHANGED |
|
||||
(BDRV_REQ_FUA &
|
||||
bs->file->bs->supported_write_flags);
|
||||
(BDRV_REQ_FUA & bs->file->bs->supported_write_flags);
|
||||
|
||||
bs->supported_zero_flags = BDRV_REQ_WRITE_UNCHANGED |
|
||||
((BDRV_REQ_FUA | BDRV_REQ_MAY_UNMAP) &
|
||||
bs->file->bs->supported_zero_flags);
|
||||
((BDRV_REQ_FUA | BDRV_REQ_MAY_UNMAP | BDRV_REQ_NO_FALLBACK) &
|
||||
bs->file->bs->supported_zero_flags);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -652,7 +652,7 @@ static int raw_open_common(BlockDriverState *bs, QDict *options,
|
||||
}
|
||||
#endif
|
||||
|
||||
bs->supported_zero_flags = BDRV_REQ_MAY_UNMAP;
|
||||
bs->supported_zero_flags = BDRV_REQ_MAY_UNMAP | BDRV_REQ_NO_FALLBACK;
|
||||
ret = 0;
|
||||
fail:
|
||||
if (filename && (bdrv_flags & BDRV_O_TEMPORARY)) {
|
||||
@ -1500,14 +1500,19 @@ static ssize_t handle_aiocb_write_zeroes_block(RawPosixAIOData *aiocb)
|
||||
}
|
||||
|
||||
#ifdef BLKZEROOUT
|
||||
do {
|
||||
uint64_t range[2] = { aiocb->aio_offset, aiocb->aio_nbytes };
|
||||
if (ioctl(aiocb->aio_fildes, BLKZEROOUT, range) == 0) {
|
||||
return 0;
|
||||
}
|
||||
} while (errno == EINTR);
|
||||
/* The BLKZEROOUT implementation in the kernel doesn't set
|
||||
* BLKDEV_ZERO_NOFALLBACK, so we can't call this if we have to avoid slow
|
||||
* fallbacks. */
|
||||
if (!(aiocb->aio_type & QEMU_AIO_NO_FALLBACK)) {
|
||||
do {
|
||||
uint64_t range[2] = { aiocb->aio_offset, aiocb->aio_nbytes };
|
||||
if (ioctl(aiocb->aio_fildes, BLKZEROOUT, range) == 0) {
|
||||
return 0;
|
||||
}
|
||||
} while (errno == EINTR);
|
||||
|
||||
ret = translate_err(-errno);
|
||||
ret = translate_err(-errno);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (ret == -ENOTSUP) {
|
||||
@ -2659,6 +2664,9 @@ raw_do_pwrite_zeroes(BlockDriverState *bs, int64_t offset, int bytes,
|
||||
if (blkdev) {
|
||||
acb.aio_type |= QEMU_AIO_BLKDEV;
|
||||
}
|
||||
if (flags & BDRV_REQ_NO_FALLBACK) {
|
||||
acb.aio_type |= QEMU_AIO_NO_FALLBACK;
|
||||
}
|
||||
|
||||
if (flags & BDRV_REQ_MAY_UNMAP) {
|
||||
acb.aio_type |= QEMU_AIO_DISCARD;
|
||||
|
16
block/io.c
16
block/io.c
@ -909,8 +909,6 @@ int bdrv_make_zero(BdrvChild *child, BdrvRequestFlags flags)
|
||||
}
|
||||
ret = bdrv_block_status(bs, offset, bytes, &bytes, NULL, NULL);
|
||||
if (ret < 0) {
|
||||
error_report("error getting block status at offset %" PRId64 ": %s",
|
||||
offset, strerror(-ret));
|
||||
return ret;
|
||||
}
|
||||
if (ret & BDRV_BLOCK_ZERO) {
|
||||
@ -919,8 +917,6 @@ int bdrv_make_zero(BdrvChild *child, BdrvRequestFlags flags)
|
||||
}
|
||||
ret = bdrv_pwrite_zeroes(child, offset, bytes, flags);
|
||||
if (ret < 0) {
|
||||
error_report("error writing zeroes at offset %" PRId64 ": %s",
|
||||
offset, strerror(-ret));
|
||||
return ret;
|
||||
}
|
||||
offset += bytes;
|
||||
@ -1019,6 +1015,7 @@ static int coroutine_fn bdrv_driver_preadv(BlockDriverState *bs,
|
||||
unsigned int nb_sectors;
|
||||
|
||||
assert(!(flags & ~BDRV_REQ_MASK));
|
||||
assert(!(flags & BDRV_REQ_NO_FALLBACK));
|
||||
|
||||
if (!drv) {
|
||||
return -ENOMEDIUM;
|
||||
@ -1065,6 +1062,7 @@ static int coroutine_fn bdrv_driver_pwritev(BlockDriverState *bs,
|
||||
int ret;
|
||||
|
||||
assert(!(flags & ~BDRV_REQ_MASK));
|
||||
assert(!(flags & BDRV_REQ_NO_FALLBACK));
|
||||
|
||||
if (!drv) {
|
||||
return -ENOMEDIUM;
|
||||
@ -1471,6 +1469,10 @@ static int coroutine_fn bdrv_co_do_pwrite_zeroes(BlockDriverState *bs,
|
||||
return -ENOMEDIUM;
|
||||
}
|
||||
|
||||
if ((flags & ~bs->supported_zero_flags) & BDRV_REQ_NO_FALLBACK) {
|
||||
return -ENOTSUP;
|
||||
}
|
||||
|
||||
assert(alignment % bs->bl.request_alignment == 0);
|
||||
head = offset % alignment;
|
||||
tail = (offset + bytes) % alignment;
|
||||
@ -1514,7 +1516,7 @@ static int coroutine_fn bdrv_co_do_pwrite_zeroes(BlockDriverState *bs,
|
||||
assert(!bs->supported_zero_flags);
|
||||
}
|
||||
|
||||
if (ret == -ENOTSUP) {
|
||||
if (ret == -ENOTSUP && !(flags & BDRV_REQ_NO_FALLBACK)) {
|
||||
/* Fall back to bounce buffer if write zeroes is unsupported */
|
||||
BdrvRequestFlags write_flags = flags & ~BDRV_REQ_ZERO_WRITE;
|
||||
|
||||
@ -2953,6 +2955,10 @@ static int coroutine_fn bdrv_co_copy_range_internal(
|
||||
BdrvTrackedRequest req;
|
||||
int ret;
|
||||
|
||||
/* TODO We can support BDRV_REQ_NO_FALLBACK here */
|
||||
assert(!(read_flags & BDRV_REQ_NO_FALLBACK));
|
||||
assert(!(write_flags & BDRV_REQ_NO_FALLBACK));
|
||||
|
||||
if (!dst || !dst->bs) {
|
||||
return -ENOMEDIUM;
|
||||
}
|
||||
|
@ -1548,7 +1548,8 @@ static void mirror_start_job(const char *job_id, BlockDriverState *bs,
|
||||
}
|
||||
mirror_top_bs->total_sectors = bs->total_sectors;
|
||||
mirror_top_bs->supported_write_flags = BDRV_REQ_WRITE_UNCHANGED;
|
||||
mirror_top_bs->supported_zero_flags = BDRV_REQ_WRITE_UNCHANGED;
|
||||
mirror_top_bs->supported_zero_flags = BDRV_REQ_WRITE_UNCHANGED |
|
||||
BDRV_REQ_NO_FALLBACK;
|
||||
bs_opaque = g_new0(MirrorBDSOpaque, 1);
|
||||
mirror_top_bs->opaque = bs_opaque;
|
||||
bdrv_set_aio_context(mirror_top_bs, bdrv_get_aio_context(bs));
|
||||
|
@ -434,7 +434,7 @@ static int raw_open(BlockDriverState *bs, QDict *options, int flags,
|
||||
bs->supported_write_flags = BDRV_REQ_WRITE_UNCHANGED |
|
||||
(BDRV_REQ_FUA & bs->file->bs->supported_write_flags);
|
||||
bs->supported_zero_flags = BDRV_REQ_WRITE_UNCHANGED |
|
||||
((BDRV_REQ_FUA | BDRV_REQ_MAY_UNMAP) &
|
||||
((BDRV_REQ_FUA | BDRV_REQ_MAY_UNMAP | BDRV_REQ_NO_FALLBACK) &
|
||||
bs->file->bs->supported_zero_flags);
|
||||
|
||||
if (bs->probed && !bdrv_is_read_only(bs)) {
|
||||
|
@ -83,8 +83,13 @@ typedef enum {
|
||||
*/
|
||||
BDRV_REQ_SERIALISING = 0x80,
|
||||
|
||||
/* Execute the request only if the operation can be offloaded or otherwise
|
||||
* be executed efficiently, but return an error instead of using a slow
|
||||
* fallback. */
|
||||
BDRV_REQ_NO_FALLBACK = 0x100,
|
||||
|
||||
/* Mask of valid flags */
|
||||
BDRV_REQ_MASK = 0xff,
|
||||
BDRV_REQ_MASK = 0x1ff,
|
||||
} BdrvRequestFlags;
|
||||
|
||||
typedef struct BlockSizes {
|
||||
|
@ -40,6 +40,7 @@
|
||||
/* AIO flags */
|
||||
#define QEMU_AIO_MISALIGNED 0x1000
|
||||
#define QEMU_AIO_BLKDEV 0x2000
|
||||
#define QEMU_AIO_NO_FALLBACK 0x4000
|
||||
|
||||
|
||||
/* linux-aio.c - Linux native implementation */
|
||||
|
@ -1932,7 +1932,7 @@ static int convert_do_copy(ImgConvertState *s)
|
||||
if (!s->has_zero_init && !s->target_has_backing &&
|
||||
bdrv_can_write_zeroes_with_unmap(blk_bs(s->target)))
|
||||
{
|
||||
ret = blk_make_zero(s->target, BDRV_REQ_MAY_UNMAP);
|
||||
ret = blk_make_zero(s->target, BDRV_REQ_MAY_UNMAP | BDRV_REQ_NO_FALLBACK);
|
||||
if (ret == 0) {
|
||||
s->has_zero_init = true;
|
||||
}
|
||||
|
@ -946,6 +946,7 @@ static void write_help(void)
|
||||
" -b, -- write to the VM state rather than the virtual disk\n"
|
||||
" -c, -- write compressed data with blk_write_compressed\n"
|
||||
" -f, -- use Force Unit Access semantics\n"
|
||||
" -n, -- with -z, don't allow slow fallback\n"
|
||||
" -p, -- ignored for backwards compatibility\n"
|
||||
" -P, -- use different pattern to fill file\n"
|
||||
" -C, -- report statistics in a machine parsable format\n"
|
||||
@ -964,7 +965,7 @@ static const cmdinfo_t write_cmd = {
|
||||
.perm = BLK_PERM_WRITE,
|
||||
.argmin = 2,
|
||||
.argmax = -1,
|
||||
.args = "[-bcCfquz] [-P pattern] off len",
|
||||
.args = "[-bcCfnquz] [-P pattern] off len",
|
||||
.oneline = "writes a number of bytes at a specified offset",
|
||||
.help = write_help,
|
||||
};
|
||||
@ -983,7 +984,7 @@ static int write_f(BlockBackend *blk, int argc, char **argv)
|
||||
int64_t total = 0;
|
||||
int pattern = 0xcd;
|
||||
|
||||
while ((c = getopt(argc, argv, "bcCfpP:quz")) != -1) {
|
||||
while ((c = getopt(argc, argv, "bcCfnpP:quz")) != -1) {
|
||||
switch (c) {
|
||||
case 'b':
|
||||
bflag = true;
|
||||
@ -997,6 +998,9 @@ static int write_f(BlockBackend *blk, int argc, char **argv)
|
||||
case 'f':
|
||||
flags |= BDRV_REQ_FUA;
|
||||
break;
|
||||
case 'n':
|
||||
flags |= BDRV_REQ_NO_FALLBACK;
|
||||
break;
|
||||
case 'p':
|
||||
/* Ignored for backwards compatibility */
|
||||
break;
|
||||
@ -1037,6 +1041,11 @@ static int write_f(BlockBackend *blk, int argc, char **argv)
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if ((flags & BDRV_REQ_NO_FALLBACK) && !zflag) {
|
||||
printf("-n requires -z to be specified\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if ((flags & BDRV_REQ_MAY_UNMAP) && !zflag) {
|
||||
printf("-u requires -z to be specified\n");
|
||||
return -EINVAL;
|
||||
|
71
tests/qemu-iotests/248
Executable file
71
tests/qemu-iotests/248
Executable file
@ -0,0 +1,71 @@
|
||||
#!/usr/bin/env python
|
||||
#
|
||||
# Test resume mirror after auto pause on ENOSPC
|
||||
#
|
||||
# Copyright (c) 2019 Virtuozzo International GmbH. All rights reserved.
|
||||
#
|
||||
# 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/>.
|
||||
#
|
||||
|
||||
import iotests
|
||||
from iotests import qemu_img_create, qemu_io, file_path, filter_qmp_testfiles
|
||||
|
||||
iotests.verify_image_format(supported_fmts=['qcow2'])
|
||||
|
||||
source, target = file_path('source', 'target')
|
||||
size = 5 * 1024 * 1024
|
||||
limit = 2 * 1024 * 1024
|
||||
|
||||
qemu_img_create('-f', iotests.imgfmt, source, str(size))
|
||||
qemu_img_create('-f', iotests.imgfmt, target, str(size))
|
||||
qemu_io('-c', 'write 0 {}'.format(size), source)
|
||||
|
||||
# raw format don't like empty files
|
||||
qemu_io('-c', 'write 0 {}'.format(size), target)
|
||||
|
||||
vm = iotests.VM().add_drive(source)
|
||||
vm.launch()
|
||||
|
||||
blockdev_opts = {
|
||||
'driver': iotests.imgfmt,
|
||||
'node-name': 'target',
|
||||
'file': {
|
||||
'driver': 'raw',
|
||||
'size': limit,
|
||||
'file': {
|
||||
'driver': 'file',
|
||||
'filename': target
|
||||
}
|
||||
}
|
||||
}
|
||||
vm.qmp_log('blockdev-add', filters=[filter_qmp_testfiles], **blockdev_opts)
|
||||
|
||||
vm.qmp_log('blockdev-mirror', device='drive0', sync='full', target='target',
|
||||
on_target_error='enospc')
|
||||
|
||||
vm.event_wait('JOB_STATUS_CHANGE', timeout=3.0,
|
||||
match={'data': {'status': 'paused'}})
|
||||
|
||||
# drop other cached events, to not interfere with further wait for 'running'
|
||||
vm.get_qmp_events()
|
||||
|
||||
del blockdev_opts['file']['size']
|
||||
vm.qmp_log('x-blockdev-reopen', filters=[filter_qmp_testfiles],
|
||||
**blockdev_opts)
|
||||
|
||||
vm.qmp_log('block-job-resume', device='drive0')
|
||||
vm.event_wait('JOB_STATUS_CHANGE', timeout=1.0,
|
||||
match={'data': {'status': 'running'}})
|
||||
|
||||
vm.shutdown()
|
8
tests/qemu-iotests/248.out
Normal file
8
tests/qemu-iotests/248.out
Normal file
@ -0,0 +1,8 @@
|
||||
{"execute": "blockdev-add", "arguments": {"driver": "qcow2", "file": {"driver": "raw", "file": {"driver": "file", "filename": "TEST_DIR/PID-target"}, "size": 2097152}, "node-name": "target"}}
|
||||
{"return": {}}
|
||||
{"execute": "blockdev-mirror", "arguments": {"device": "drive0", "on-target-error": "enospc", "sync": "full", "target": "target"}}
|
||||
{"return": {}}
|
||||
{"execute": "x-blockdev-reopen", "arguments": {"driver": "qcow2", "file": {"driver": "raw", "file": {"driver": "file", "filename": "TEST_DIR/PID-target"}}, "node-name": "target"}}
|
||||
{"return": {}}
|
||||
{"execute": "block-job-resume", "arguments": {"device": "drive0"}}
|
||||
{"return": {}}
|
@ -246,3 +246,4 @@
|
||||
245 rw auto
|
||||
246 rw auto quick
|
||||
247 rw auto quick
|
||||
248 rw auto quick
|
||||
|
Loading…
Reference in New Issue
Block a user