From patchwork Tue Apr 24 06:29:04 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: ronnie sahlberg X-Patchwork-Id: 154604 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (Client did not present a certificate) by ozlabs.org (Postfix) with ESMTPS id 66255B6FA3 for ; Tue, 24 Apr 2012 16:29:16 +1000 (EST) Received: from localhost ([::1]:40948 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1SMZFS-0008C1-7n for incoming@patchwork.ozlabs.org; Tue, 24 Apr 2012 02:29:14 -0400 Received: from eggs.gnu.org ([208.118.235.92]:44439) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1SMZFE-00082u-IC for qemu-devel@nongnu.org; Tue, 24 Apr 2012 02:29:02 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1SMZFA-0007WK-V5 for qemu-devel@nongnu.org; Tue, 24 Apr 2012 02:29:00 -0400 Received: from mail-iy0-f173.google.com ([209.85.210.173]:44276) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1SMZFA-0007Qo-Nk for qemu-devel@nongnu.org; Tue, 24 Apr 2012 02:28:56 -0400 Received: by mail-iy0-f173.google.com with SMTP id j26so721454iaf.4 for ; Mon, 23 Apr 2012 23:28:56 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=from:to:cc:subject:date:message-id:x-mailer:in-reply-to:references; bh=GTlIpC1QZjdmhzDGub+lxLAsfmsSGcGIMXdppAqJ8O0=; b=lrcNe+kWw6JaNKleP3qyqmOe6um/Sy7uOuDkZ2YSaIF04VRQRN4UkU6YcqcEzTBUV6 B6GFHghzSdR3WLq1SsY34F6GovQppm9++LBAwCRfplm3r3CFWAHvwj+MuDbhx6zQhIZY S5zSPfYvaSwgmZ9oMxG+PAqg1KctNPP2S2RWQdlSMOeHaXb0gLw3JZlkr3S78ZXQfFVZ k7R4Fq7YwKkM1g8T5YDGWz59FTkHbUi+1hwnwyMjXG7O6Xe8oxH+66bRstmLAkRxnQ/e yKS6S2UrzGpN38tlolsknVdq1nflk/eDr/RQtocrhLUgOGXes1P8lCzJgPXuWH+TLpmy XsSA== Received: by 10.50.222.202 with SMTP id qo10mr8778180igc.0.1335248935891; Mon, 23 Apr 2012 23:28:55 -0700 (PDT) Received: from ronniesahlberg@gmail.com (CPE-58-166-90-251.lnse5.cht.bigpond.net.au. [58.166.90.251]) by mx.google.com with ESMTPS id d5sm31771844iga.15.2012.04.23.23.28.52 (version=TLSv1/SSLv3 cipher=OTHER); Mon, 23 Apr 2012 23:28:55 -0700 (PDT) Received: by ronniesahlberg@gmail.com (sSMTP sendmail emulation); Tue, 24 Apr 2012 16:29:18 +1000 From: Ronnie Sahlberg To: pbonzini@redhat.com, kwolf@redhat.com, qemu-devel@nongnu.org Date: Tue, 24 Apr 2012 16:29:04 +1000 Message-Id: <1335248944-10765-2-git-send-email-ronniesahlberg@gmail.com> X-Mailer: git-send-email 1.7.3.1 In-Reply-To: <1335248944-10765-1-git-send-email-ronniesahlberg@gmail.com> References: <1335248944-10765-1-git-send-email-ronniesahlberg@gmail.com> X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 209.85.210.173 Cc: Ronnie Sahlberg Subject: [Qemu-devel] [PATCH] ISCSI: Add support for thin-provisioning via discard/UNMAP and bigger LUNs X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Update the configure test for libiscsi support to detect version 1.3 or later. Version 1.3 of libiscsi provides both READCAPACITY16 as well as UNMAP commands. Update the iscsi block layer to use READCAPACITY16 to detect the size of the LUN instead of READCAPACITY10. This allows support for LUNs larger than 2TB. Update to implement bdrv_aio_discard() using the UNMAP command. This allows us to use thin-provisioned LUNs from TGTD and other iSCSI targets that support thin-provisioning. Signed-off-by: Ronnie Sahlberg --- block/iscsi.c | 86 ++++++++++++++++++++++++++++++++++++++++++++++++-------- configure | 5 ++- 2 files changed, 77 insertions(+), 14 deletions(-) diff --git a/block/iscsi.c b/block/iscsi.c index bd3ca11..eb49093 100644 --- a/block/iscsi.c +++ b/block/iscsi.c @@ -383,6 +383,65 @@ iscsi_aio_flush(BlockDriverState *bs, return &acb->common; } +static void +iscsi_unmap_cb(struct iscsi_context *iscsi, int status, + void *command_data, void *opaque) +{ + IscsiAIOCB *acb = opaque; + + if (acb->canceled != 0) { + qemu_aio_release(acb); + scsi_free_scsi_task(acb->task); + acb->task = NULL; + return; + } + + acb->status = 0; + if (status < 0) { + error_report("Failed to unmap data on iSCSI lun. %s", + iscsi_get_error(iscsi)); + acb->status = -EIO; + } + + iscsi_schedule_bh(iscsi_readv_writev_bh_cb, acb); + scsi_free_scsi_task(acb->task); + acb->task = NULL; +} + +static BlockDriverAIOCB * +iscsi_aio_discard(BlockDriverState *bs, + int64_t sector_num, int nb_sectors, + BlockDriverCompletionFunc *cb, void *opaque) +{ + IscsiLun *iscsilun = bs->opaque; + struct iscsi_context *iscsi = iscsilun->iscsi; + IscsiAIOCB *acb; + struct unmap_list list[1]; + + acb = qemu_aio_get(&iscsi_aio_pool, bs, cb, opaque); + + acb->iscsilun = iscsilun; + acb->canceled = 0; + + list[0].lba = sector_qemu2lun(sector_num, iscsilun); + list[0].num = nb_sectors * BDRV_SECTOR_SIZE / iscsilun->block_size; + + acb->task = iscsi_unmap_task(iscsi, iscsilun->lun, + 0, 0, &list[0], 1, + iscsi_unmap_cb, + acb); + if (acb->task == NULL) { + error_report("iSCSI: Failed to send unmap command. %s", + iscsi_get_error(iscsi)); + qemu_aio_release(acb); + return NULL; + } + + iscsi_set_events(iscsilun); + + return &acb->common; +} + static int64_t iscsi_getlength(BlockDriverState *bs) { @@ -396,11 +455,11 @@ iscsi_getlength(BlockDriverState *bs) } static void -iscsi_readcapacity10_cb(struct iscsi_context *iscsi, int status, +iscsi_readcapacity16_cb(struct iscsi_context *iscsi, int status, void *command_data, void *opaque) { struct IscsiTask *itask = opaque; - struct scsi_readcapacity10 *rc10; + struct scsi_readcapacity16 *rc16; struct scsi_task *task = command_data; if (status != 0) { @@ -412,26 +471,25 @@ iscsi_readcapacity10_cb(struct iscsi_context *iscsi, int status, return; } - rc10 = scsi_datain_unmarshall(task); - if (rc10 == NULL) { - error_report("iSCSI: Failed to unmarshall readcapacity10 data."); + rc16 = scsi_datain_unmarshall(task); + if (rc16 == NULL) { + error_report("iSCSI: Failed to unmarshall readcapacity16 data."); itask->status = 1; itask->complete = 1; scsi_free_scsi_task(task); return; } - itask->iscsilun->block_size = rc10->block_size; - itask->iscsilun->num_blocks = rc10->lba; - itask->bs->total_sectors = (uint64_t)rc10->lba * - rc10->block_size / BDRV_SECTOR_SIZE ; + itask->iscsilun->block_size = rc16->block_length; + itask->iscsilun->num_blocks = rc16->returned_lba; + itask->bs->total_sectors = rc16->returned_lba * + rc16->block_length / BDRV_SECTOR_SIZE ; itask->status = 0; itask->complete = 1; scsi_free_scsi_task(task); } - static void iscsi_connect_cb(struct iscsi_context *iscsi, int status, void *command_data, void *opaque) @@ -445,10 +503,10 @@ iscsi_connect_cb(struct iscsi_context *iscsi, int status, void *command_data, return; } - task = iscsi_readcapacity10_task(iscsi, itask->iscsilun->lun, 0, 0, - iscsi_readcapacity10_cb, opaque); + task = iscsi_readcapacity16_task(iscsi, itask->iscsilun->lun, + iscsi_readcapacity16_cb, opaque); if (task == NULL) { - error_report("iSCSI: failed to send readcapacity command."); + error_report("iSCSI: failed to send readcapacity16 command."); itask->status = 1; itask->complete = 1; return; @@ -700,6 +758,8 @@ static BlockDriver bdrv_iscsi = { .bdrv_aio_readv = iscsi_aio_readv, .bdrv_aio_writev = iscsi_aio_writev, .bdrv_aio_flush = iscsi_aio_flush, + + .bdrv_aio_discard = iscsi_aio_discard, }; static void iscsi_block_init(void) diff --git a/configure b/configure index 2d62d12..1c693f0 100755 --- a/configure +++ b/configure @@ -2516,10 +2516,13 @@ fi ########################################## # Do we have libiscsi +# We check for iscsi_unmap_sync() to make sure we have a +# recent enough version of libiscsi. if test "$libiscsi" != "no" ; then cat > $TMPC << EOF +#include #include -int main(void) { iscsi_create_context(""); return 0; } +int main(void) { iscsi_unmap_sync(NULL,0,0,0,NULL,0); return 0; } EOF if compile_prog "-Werror" "-liscsi" ; then libiscsi="yes"