[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PATCHv2 07/11] iscsi: let bdrv_create conditionally zero o
From: |
Peter Lieven |
Subject: |
[Qemu-devel] [PATCHv2 07/11] iscsi: let bdrv_create conditionally zero out the device |
Date: |
Thu, 27 Jun 2013 15:11:31 +0200 |
if the device supports unmapping and unmapped blocks read as
zero ensure that the whole device is unmapped and report
.has_zero_init = 1 in this case to speed up qemu-img convert.
Signed-off-by: Peter Lieven <address@hidden>
---
block/iscsi.c | 72 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
1 file changed, 71 insertions(+), 1 deletion(-)
diff --git a/block/iscsi.c b/block/iscsi.c
index 92e66a6..621ca40 100644
--- a/block/iscsi.c
+++ b/block/iscsi.c
@@ -1436,7 +1436,8 @@ static int iscsi_truncate(BlockDriverState *bs, int64_t
offset)
static int iscsi_has_zero_init(BlockDriverState *bs)
{
- return 0;
+ IscsiLun *iscsilun = bs->opaque;
+ return (iscsilun->lbpu && iscsilun->lbprz) ? 1 : 0;
}
static int iscsi_create(const char *filename, QEMUOptionParameter *options)
@@ -1446,6 +1447,7 @@ static int iscsi_create(const char *filename,
QEMUOptionParameter *options)
BlockDriverState bs;
IscsiLun *iscsilun = NULL;
QDict *bs_options;
+ struct scsi_task *task = NULL;
memset(&bs, 0, sizeof(BlockDriverState));
@@ -1481,7 +1483,75 @@ static int iscsi_create(const char *filename,
QEMUOptionParameter *options)
}
ret = 0;
+
+ if (iscsilun->lbpu && iscsilun->lbprz) {
+ uint64_t lba = 0;
+ while (lba < iscsilun->num_blocks) {
+ struct scsi_get_lba_status *lbas = NULL;
+ struct scsi_lba_status_descriptor *lbasd = NULL;
+ enum scsi_provisioning_type provisioning;
+ uint32_t nb_sectors;
+
+ task = iscsi_get_lba_status_sync(iscsilun->iscsi, iscsilun->lun,
+ lba, 8 + 16);
+ if (task == NULL || task->status != SCSI_STATUS_GOOD) {
+ error_report("iSCSI: Failed to get_lba_status on iSCSI lun.
%s",
+ iscsi_get_error(iscsilun->iscsi));
+ ret = -EINVAL;
+ goto out;
+ }
+
+ lbas = scsi_datain_unmarshall(task);
+ if (lbas == NULL) {
+ error_report("iSCSI: failed to unmarshall inquiry datain
blob");
+ ret = -EINVAL;
+ goto out;
+ }
+ lbasd = &lbas->descriptors[0];
+ if (lbasd->lba != lba) {
+ ret = -EINVAL;
+ goto out;
+ }
+ nb_sectors = lbasd->num_blocks;
+ provisioning = lbasd->provisioning;
+ scsi_free_scsi_task(task);
+ task = NULL;
+
+ /* blocks from lba to lba + nb_sectors - 1 are not mapped
+ * and read as zero (lbprz==1) so we can skip them */
+ if (provisioning != SCSI_PROVISIONING_TYPE_MAPPED) {
+ lba += nb_sectors;
+ continue;
+ }
+
+ uint64_t lba2 = lba + nb_sectors;
+ while (lba < lba2) {
+ struct unmap_list list[1];
+ list[0].lba = lba;
+ list[0].num = iscsilun->max_unmap;
+ if (lba + list[0].num > iscsilun->num_blocks) {
+ list[0].num = iscsilun->num_blocks - lba;
+ }
+ task = iscsi_unmap_sync(iscsilun->iscsi,
+ iscsilun->lun,
+ 0, 0, &list[0], 1);
+ if (task == NULL || task->status != SCSI_STATUS_GOOD) {
+ error_report("iSCSI: Failed to unmap data on iSCSI lun.
%s",
+ iscsi_get_error(iscsilun->iscsi));
+ ret = -EINVAL;
+ goto out;
+ }
+ scsi_free_scsi_task(task);
+ task = NULL;
+ lba += list[0].num;
+ }
+ }
+ }
+
out:
+ if (task) {
+ scsi_free_scsi_task(task);
+ }
if (iscsilun->iscsi != NULL) {
iscsi_destroy_context(iscsilun->iscsi);
}
--
1.7.9.5
- [Qemu-devel] [PATCHv2 00/11] iscsi/qemu-img/block-migration enhancements, Peter Lieven, 2013/06/27
- [Qemu-devel] [PATCHv2 03/11] iscsi: add bdrv_co_is_allocated, Peter Lieven, 2013/06/27
- [Qemu-devel] [PATCHv2 02/11] iscsi: read unmap info from block limits vpd page, Peter Lieven, 2013/06/27
- [Qemu-devel] [PATCHv2 05/11] block: add bdrv_write_zeroes(), Peter Lieven, 2013/06/27
- [Qemu-devel] [PATCHv2 01/11] iscsi: add logical block provisioning information to iscsilun, Peter Lieven, 2013/06/27
- [Qemu-devel] [PATCHv2 06/11] block/raw: add bdrv_co_write_zeroes, Peter Lieven, 2013/06/27
- [Qemu-devel] [PATCHv2 09/11] iscsi: factor out sector conversions, Peter Lieven, 2013/06/27
- [Qemu-devel] [PATCHv2 07/11] iscsi: let bdrv_create conditionally zero out the device,
Peter Lieven <=
- [Qemu-devel] [PATCHv2 10/11] iscsi: ignore aio_discard if unsupported, Peter Lieven, 2013/06/27
- [Qemu-devel] [PATCHv2 04/11] iscsi: add bdrv_co_write_zeroes, Peter Lieven, 2013/06/27
- [Qemu-devel] [PATCHv2 11/11] iscsi: assert that sectors are aligned to LUN blocksize, Peter Lieven, 2013/06/27
- [Qemu-devel] [PATCHv2 08/11] block-migration: efficiently encode zero blocks, Peter Lieven, 2013/06/27