diff --git a/block.c b/block.c index f94585b230..814e5a02da 100644 --- a/block.c +++ b/block.c @@ -4010,17 +4010,11 @@ bool bdrv_unallocated_blocks_are_zero(BlockDriverState *bs) bool bdrv_can_write_zeroes_with_unmap(BlockDriverState *bs) { - BlockDriverInfo bdi; - if (!(bs->open_flags & BDRV_O_UNMAP)) { return false; } - if (bdrv_get_info(bs, &bdi) == 0) { - return bdi.can_write_zeroes_with_unmap; - } - - return false; + return bs->supported_zero_flags & BDRV_REQ_MAY_UNMAP; } const char *bdrv_get_encrypted_filename(BlockDriverState *bs) diff --git a/block/crypto.c b/block/crypto.c index 70e3691cd8..3df66947c5 100644 --- a/block/crypto.c +++ b/block/crypto.c @@ -576,7 +576,6 @@ static int block_crypto_get_info_luks(BlockDriverState *bs, } bdi->unallocated_blocks_are_zero = false; - bdi->can_write_zeroes_with_unmap = false; bdi->cluster_size = subbdi.cluster_size; return 0; diff --git a/block/file-posix.c b/block/file-posix.c index dd8d7cbbd2..ca49c1a98a 100644 --- a/block/file-posix.c +++ b/block/file-posix.c @@ -549,7 +549,6 @@ static int raw_open_common(BlockDriverState *bs, QDict *options, s->has_discard = true; s->has_write_zeroes = true; - bs->supported_zero_flags = BDRV_REQ_MAY_UNMAP; if ((bs->open_flags & BDRV_O_NOCACHE) != 0) { s->needs_alignment = true; } @@ -599,6 +598,7 @@ static int raw_open_common(BlockDriverState *bs, QDict *options, } #endif + bs->supported_zero_flags = s->discard_zeroes ? BDRV_REQ_MAY_UNMAP : 0; ret = 0; fail: if (filename && (bdrv_flags & BDRV_O_TEMPORARY)) { @@ -2223,7 +2223,6 @@ static int raw_get_info(BlockDriverState *bs, BlockDriverInfo *bdi) BDRVRawState *s = bs->opaque; bdi->unallocated_blocks_are_zero = s->discard_zeroes; - bdi->can_write_zeroes_with_unmap = s->discard_zeroes; return 0; } diff --git a/block/iscsi.c b/block/iscsi.c index 9f99ae5e07..421983dd6f 100644 --- a/block/iscsi.c +++ b/block/iscsi.c @@ -1877,7 +1877,6 @@ static int iscsi_open(BlockDriverState *bs, QDict *options, int flags, if (iscsilun->dpofua) { bs->supported_write_flags = BDRV_REQ_FUA; } - bs->supported_zero_flags = BDRV_REQ_MAY_UNMAP; /* Check the write protect flag of the LUN if we want to write */ if (iscsilun->type == TYPE_DISK && (flags & BDRV_O_RDWR) && @@ -1961,6 +1960,10 @@ static int iscsi_open(BlockDriverState *bs, QDict *options, int flags, } } + if (iscsilun->lbprz && iscsilun->lbp.lbpws) { + bs->supported_zero_flags = BDRV_REQ_MAY_UNMAP; + } + out: qemu_opts_del(opts); g_free(initiator_name); @@ -2160,7 +2163,6 @@ static int iscsi_get_info(BlockDriverState *bs, BlockDriverInfo *bdi) { IscsiLun *iscsilun = bs->opaque; bdi->unallocated_blocks_are_zero = iscsilun->lbprz; - bdi->can_write_zeroes_with_unmap = iscsilun->lbprz && iscsilun->lbp.lbpws; bdi->cluster_size = iscsilun->cluster_sectors * BDRV_SECTOR_SIZE; return 0; } diff --git a/block/nbd.c b/block/nbd.c index 411eeb42a7..ef81a9f53b 100644 --- a/block/nbd.c +++ b/block/nbd.c @@ -566,14 +566,6 @@ static void nbd_refresh_filename(BlockDriverState *bs, QDict *options) bs->full_open_options = opts; } -static int nbd_get_info(BlockDriverState *bs, BlockDriverInfo *bdi) -{ - if (bs->supported_zero_flags & BDRV_REQ_MAY_UNMAP) { - bdi->can_write_zeroes_with_unmap = true; - } - return 0; -} - static BlockDriver bdrv_nbd = { .format_name = "nbd", .protocol_name = "nbd", @@ -591,7 +583,6 @@ static BlockDriver bdrv_nbd = { .bdrv_detach_aio_context = nbd_detach_aio_context, .bdrv_attach_aio_context = nbd_attach_aio_context, .bdrv_refresh_filename = nbd_refresh_filename, - .bdrv_get_info = nbd_get_info, }; static BlockDriver bdrv_nbd_tcp = { @@ -611,7 +602,6 @@ static BlockDriver bdrv_nbd_tcp = { .bdrv_detach_aio_context = nbd_detach_aio_context, .bdrv_attach_aio_context = nbd_attach_aio_context, .bdrv_refresh_filename = nbd_refresh_filename, - .bdrv_get_info = nbd_get_info, }; static BlockDriver bdrv_nbd_unix = { @@ -631,7 +621,6 @@ static BlockDriver bdrv_nbd_unix = { .bdrv_detach_aio_context = nbd_detach_aio_context, .bdrv_attach_aio_context = nbd_attach_aio_context, .bdrv_refresh_filename = nbd_refresh_filename, - .bdrv_get_info = nbd_get_info, }; static void bdrv_nbd_init(void) diff --git a/block/qcow2.c b/block/qcow2.c index a64a572785..801e29fc56 100644 --- a/block/qcow2.c +++ b/block/qcow2.c @@ -1479,7 +1479,7 @@ static int qcow2_do_open(BlockDriverState *bs, QDict *options, int flags, /* Initialise locks */ qemu_co_mutex_init(&s->lock); - bs->supported_zero_flags = BDRV_REQ_MAY_UNMAP; + bs->supported_zero_flags = header.version >= 3 ? BDRV_REQ_MAY_UNMAP : 0; /* Repair image if dirty */ if (!(flags & (BDRV_O_CHECK | BDRV_O_INACTIVE)) && !bs->read_only && @@ -3771,7 +3771,6 @@ static int qcow2_get_info(BlockDriverState *bs, BlockDriverInfo *bdi) { BDRVQcow2State *s = bs->opaque; bdi->unallocated_blocks_are_zero = true; - bdi->can_write_zeroes_with_unmap = (s->qcow_version >= 3); bdi->cluster_size = s->cluster_size; bdi->vm_state_offset = qcow2_vm_state_offset(s); return 0; diff --git a/block/qed.c b/block/qed.c index 205dbf16e3..c6ff3ab015 100644 --- a/block/qed.c +++ b/block/qed.c @@ -1438,7 +1438,6 @@ static int bdrv_qed_get_info(BlockDriverState *bs, BlockDriverInfo *bdi) bdi->cluster_size = s->header.cluster_size; bdi->is_dirty = s->header.features & QED_F_NEED_CHECK; bdi->unallocated_blocks_are_zero = true; - bdi->can_write_zeroes_with_unmap = true; return 0; } diff --git a/include/block/block.h b/include/block/block.h index 24ef816960..19b3ab9cb5 100644 --- a/include/block/block.h +++ b/include/block/block.h @@ -26,17 +26,6 @@ typedef struct BlockDriverInfo { * to the LBPRZ flag in the SCSI logical block provisioning page. */ bool unallocated_blocks_are_zero; - /* - * True if the driver can optimize writing zeroes by unmapping - * sectors. This is equivalent to the BLKDISCARDZEROES ioctl in Linux - * with the difference that in qemu a discard is allowed to silently - * fail. Therefore we have to use bdrv_pwrite_zeroes with the - * BDRV_REQ_MAY_UNMAP flag for an optimized zero write with unmapping. - * After this call the driver has to guarantee that the contents read - * back as zero. It is additionally required that the block device is - * opened with BDRV_O_UNMAP flag for this to work. - */ - bool can_write_zeroes_with_unmap; /* * True if this block driver only supports compressed writes */ diff --git a/tests/qemu-iotests/205 b/tests/qemu-iotests/205 index 10388920dc..e7b2eae51d 100644 --- a/tests/qemu-iotests/205 +++ b/tests/qemu-iotests/205 @@ -22,7 +22,7 @@ import os import sys import iotests import time -from iotests import qemu_img, qemu_io, filter_qemu_io, QemuIoInteractive +from iotests import qemu_img_create, qemu_io, filter_qemu_io, QemuIoInteractive nbd_sock = 'nbd_sock' nbd_uri = 'nbd+unix:///exp?socket=' + nbd_sock @@ -31,7 +31,7 @@ disk = os.path.join(iotests.test_dir, 'disk') class TestNbdServerRemove(iotests.QMPTestCase): def setUp(self): - qemu_img('create', '-f', iotests.imgfmt, disk, '1M') + qemu_img_create('-f', iotests.imgfmt, disk, '1M') self.vm = iotests.VM().add_drive(disk) self.vm.launch() diff --git a/tests/qemu-iotests/iotests.py b/tests/qemu-iotests/iotests.py index 5a10b2d534..1bcc9ca57d 100644 --- a/tests/qemu-iotests/iotests.py +++ b/tests/qemu-iotests/iotests.py @@ -58,6 +58,11 @@ qemu_default_machine = os.environ.get('QEMU_DEFAULT_MACHINE') socket_scm_helper = os.environ.get('SOCKET_SCM_HELPER', 'socket_scm_helper') debug = False +luks_default_secret_object = 'secret,id=keysec0,data=' + \ + os.environ['IMGKEYSECRET'] +luks_default_key_secret_opt = 'key-secret=keysec0' + + def qemu_img(*args): '''Run qemu-img and return the exit code''' devnull = open('/dev/null', 'r+') @@ -66,6 +71,25 @@ def qemu_img(*args): sys.stderr.write('qemu-img received signal %i: %s\n' % (-exitcode, ' '.join(qemu_img_args + list(args)))) return exitcode +def qemu_img_create(*args): + args = list(args) + + # default luks support + if '-f' in args and args[args.index('-f') + 1] == 'luks': + if '-o' in args: + i = args.index('-o') + if 'key-secret' not in args[i + 1]: + args[i + 1].append(luks_default_key_secret_opt) + args.insert(i + 2, '--object') + args.insert(i + 3, luks_default_secret_object) + else: + args = ['-o', luks_default_key_secret_opt, + '--object', luks_default_secret_object] + args + + args.insert(0, 'create') + + return qemu_img(*args) + def qemu_img_verbose(*args): '''Run qemu-img without suppressing its output and return the exit code''' exitcode = subprocess.call(qemu_img_args + list(args)) @@ -263,6 +287,13 @@ class VM(qtest.QEMUQtestMachine): if opts: options.append(opts) + if format == 'luks' and 'key-secret' not in opts: + # default luks support + if luks_default_secret_object not in self._args: + self.add_object(luks_default_secret_object) + + options.append(luks_default_key_secret_opt) + self._args.append('-drive') self._args.append(','.join(options)) self._num_drives += 1