From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([2001:4830:134:3::10]:34115) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1UtldH-0003X5-SA for qemu-devel@nongnu.org; Mon, 01 Jul 2013 17:27:37 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1UtldG-0002zv-JS for qemu-devel@nongnu.org; Mon, 01 Jul 2013 17:27:35 -0400 Received: from mail-ea0-x22f.google.com ([2a00:1450:4013:c01::22f]:50849) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1UtldG-0002zq-Ah for qemu-devel@nongnu.org; Mon, 01 Jul 2013 17:27:34 -0400 Received: by mail-ea0-f175.google.com with SMTP id z7so2312681eaf.20 for ; Mon, 01 Jul 2013 14:27:33 -0700 (PDT) Sender: Paolo Bonzini Message-ID: <51D1E49D.2000600@redhat.com> Date: Mon, 01 Jul 2013 22:20:45 +0200 From: Paolo Bonzini MIME-Version: 1.0 References: <1372338695-411-1-git-send-email-pl@kamp.de> <1372338695-411-8-git-send-email-pl@kamp.de> In-Reply-To: <1372338695-411-8-git-send-email-pl@kamp.de> Content-Type: text/plain; charset=ISO-8859-15 Content-Transfer-Encoding: 7bit Subject: Re: [Qemu-devel] [PATCHv2 07/11] iscsi: let bdrv_create conditionally zero out the device List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: Peter Lieven Cc: kwolf@redhat.com, ronniesahlberg@gmail.com, qemu-devel@nongnu.org, stefanha@redhat.com Il 27/06/2013 15:11, Peter Lieven ha scritto: > 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. This can still take several minutes. Do you need any special timeout in libiscsi? Perhaps we can have a new "discard_zeroes" field in bdrv_get_info, and the unmap functionality can be moved up to qemu-img convert? Paolo > > Signed-off-by: Peter Lieven > --- > 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); > } >