9ae3a8
From ce9c2ba7bd509d0d92c6f5a12ea27b9899126d6d Mon Sep 17 00:00:00 2001
9ae3a8
From: Fam Zheng <famz@redhat.com>
9ae3a8
Date: Fri, 4 Apr 2014 05:55:58 +0200
9ae3a8
Subject: [PATCH 03/12] block/iscsi: query for supported VPD pages
9ae3a8
9ae3a8
RH-Author: Fam Zheng <famz@redhat.com>
9ae3a8
Message-id: <1396590962-25815-4-git-send-email-famz@redhat.com>
9ae3a8
Patchwork-id: 58340
9ae3a8
O-Subject: [RHEL-7 0day qemu-kvm PATCH 3/7] block/iscsi: query for supported VPD pages
9ae3a8
Bugzilla: 1083413
9ae3a8
RH-Acked-by: Paolo Bonzini <pbonzini@redhat.com>
9ae3a8
RH-Acked-by: Markus Armbruster <armbru@redhat.com>
9ae3a8
RH-Acked-by: Kevin Wolf <kwolf@redhat.com>
9ae3a8
RH-Acked-by: Jeffrey Cody <jcody@redhat.com>
9ae3a8
9ae3a8
From: Peter Lieven <pl@kamp.de>
9ae3a8
9ae3a8
this patch ensures that we only query for block provisioning and
9ae3a8
block limits vpd pages if they are advertised. It also cleans
9ae3a8
up the inquiry code and eliminates some redundant code.
9ae3a8
9ae3a8
Signed-off-by: Peter Lieven <pl@kamp.de>
9ae3a8
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
9ae3a8
(cherry picked from commit 24d3bd67aca958c8ea103646d9d326de00056e4d)
9ae3a8
Signed-off-by: Fam Zheng <famz@redhat.com>
9ae3a8
---
9ae3a8
 block/iscsi.c | 107 +++++++++++++++++++++++++++++-----------------------------
9ae3a8
 1 file changed, 54 insertions(+), 53 deletions(-)
9ae3a8
9ae3a8
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
9ae3a8
---
9ae3a8
 block/iscsi.c |  107 +++++++++++++++++++++++++++++----------------------------
9ae3a8
 1 files changed, 54 insertions(+), 53 deletions(-)
9ae3a8
9ae3a8
diff --git a/block/iscsi.c b/block/iscsi.c
9ae3a8
index 537d2cb..d3c8802 100644
9ae3a8
--- a/block/iscsi.c
9ae3a8
+++ b/block/iscsi.c
9ae3a8
@@ -1240,7 +1240,7 @@ static QemuOptsList runtime_opts = {
9ae3a8
 };
9ae3a8
 
9ae3a8
 static struct scsi_task *iscsi_do_inquiry(struct iscsi_context *iscsi, int lun,
9ae3a8
-                                          int evpd, int pc, Error **errp)
9ae3a8
+                                          int evpd, int pc, void **inq, Error **errp)
9ae3a8
 {
9ae3a8
     int full_size;
9ae3a8
     struct scsi_task *task = NULL;
9ae3a8
@@ -1259,14 +1259,19 @@ static struct scsi_task *iscsi_do_inquiry(struct iscsi_context *iscsi, int lun,
9ae3a8
         }
9ae3a8
     }
9ae3a8
 
9ae3a8
+    *inq = scsi_datain_unmarshall(task);
9ae3a8
+    if (*inq == NULL) {
9ae3a8
+        error_setg(errp, "iSCSI: failed to unmarshall inquiry datain blob");
9ae3a8
+        goto fail;
9ae3a8
+    }
9ae3a8
+
9ae3a8
     return task;
9ae3a8
 
9ae3a8
 fail:
9ae3a8
     error_setg(errp, "iSCSI: Inquiry command failed : %s",
9ae3a8
                iscsi_get_error(iscsi));
9ae3a8
-    if (task) {
9ae3a8
+    if (task != NULL) {
9ae3a8
         scsi_free_scsi_task(task);
9ae3a8
-        return NULL;
9ae3a8
     }
9ae3a8
     return NULL;
9ae3a8
 }
9ae3a8
@@ -1283,11 +1288,12 @@ static int iscsi_open(BlockDriverState *bs, QDict *options, int flags,
9ae3a8
     struct iscsi_url *iscsi_url = NULL;
9ae3a8
     struct scsi_task *task = NULL;
9ae3a8
     struct scsi_inquiry_standard *inq = NULL;
9ae3a8
+    struct scsi_inquiry_supported_pages *inq_vpd;
9ae3a8
     char *initiator_name = NULL;
9ae3a8
     QemuOpts *opts;
9ae3a8
     Error *local_err = NULL;
9ae3a8
     const char *filename;
9ae3a8
-    int ret;
9ae3a8
+    int i, ret;
9ae3a8
 
9ae3a8
     if ((BDRV_SECTOR_SIZE % 512) != 0) {
9ae3a8
         error_setg(errp, "iSCSI: Invalid BDRV_SECTOR_SIZE. "
9ae3a8
@@ -1373,24 +1379,17 @@ static int iscsi_open(BlockDriverState *bs, QDict *options, int flags,
9ae3a8
 
9ae3a8
     iscsilun->iscsi = iscsi;
9ae3a8
     iscsilun->lun   = iscsi_url->lun;
9ae3a8
+    iscsilun->has_write_same = true;
9ae3a8
 
9ae3a8
-    task = iscsi_inquiry_sync(iscsi, iscsilun->lun, 0, 0, 36);
9ae3a8
-
9ae3a8
-    if (task == NULL || task->status != SCSI_STATUS_GOOD) {
9ae3a8
-        error_setg(errp, "iSCSI: failed to send inquiry command.");
9ae3a8
-        ret = -EINVAL;
9ae3a8
-        goto out;
9ae3a8
-    }
9ae3a8
-
9ae3a8
-    inq = scsi_datain_unmarshall(task);
9ae3a8
-    if (inq == NULL) {
9ae3a8
-        error_setg(errp, "iSCSI: Failed to unmarshall inquiry data.");
9ae3a8
+    task = iscsi_do_inquiry(iscsilun->iscsi, iscsilun->lun, 0, 0,
9ae3a8
+                            (void **) &inq, errp);
9ae3a8
+    if (task == NULL) {
9ae3a8
         ret = -EINVAL;
9ae3a8
         goto out;
9ae3a8
     }
9ae3a8
-
9ae3a8
     iscsilun->type = inq->periperal_device_type;
9ae3a8
-    iscsilun->has_write_same = true;
9ae3a8
+    scsi_free_scsi_task(task);
9ae3a8
+    task = NULL;
9ae3a8
 
9ae3a8
     iscsi_readcapacity_sync(iscsilun, &local_err);
9ae3a8
     if (local_err != NULL) {
9ae3a8
@@ -1408,46 +1407,48 @@ static int iscsi_open(BlockDriverState *bs, QDict *options, int flags,
9ae3a8
         bs->sg = 1;
9ae3a8
     }
9ae3a8
 
9ae3a8
-    if (iscsilun->lbpme) {
9ae3a8
-        struct scsi_inquiry_logical_block_provisioning *inq_lbp;
9ae3a8
-        task = iscsi_do_inquiry(iscsilun->iscsi, iscsilun->lun, 1,
9ae3a8
-                                SCSI_INQUIRY_PAGECODE_LOGICAL_BLOCK_PROVISIONING,
9ae3a8
-                                errp);
9ae3a8
-        if (task == NULL) {
9ae3a8
-            ret = -EINVAL;
9ae3a8
-            goto out;
9ae3a8
-        }
9ae3a8
-        inq_lbp = scsi_datain_unmarshall(task);
9ae3a8
-        if (inq_lbp == NULL) {
9ae3a8
-            error_setg(errp, "iSCSI: failed to unmarshall inquiry datain blob");
9ae3a8
-            ret = -EINVAL;
9ae3a8
-            goto out;
9ae3a8
-        }
9ae3a8
-        memcpy(&iscsilun->lbp, inq_lbp,
9ae3a8
-               sizeof(struct scsi_inquiry_logical_block_provisioning));
9ae3a8
-        scsi_free_scsi_task(task);
9ae3a8
-        task = NULL;
9ae3a8
+    task = iscsi_do_inquiry(iscsilun->iscsi, iscsilun->lun, 1,
9ae3a8
+                            SCSI_INQUIRY_PAGECODE_SUPPORTED_VPD_PAGES,
9ae3a8
+                            (void **) &inq_vpd, errp);
9ae3a8
+    if (task == NULL) {
9ae3a8
+        ret = -EINVAL;
9ae3a8
+        goto out;
9ae3a8
     }
9ae3a8
-
9ae3a8
-    if (iscsilun->lbp.lbpu || iscsilun->lbp.lbpws) {
9ae3a8
+    for (i = 0; i < inq_vpd->num_pages; i++) {
9ae3a8
+        struct scsi_task *inq_task;
9ae3a8
+        struct scsi_inquiry_logical_block_provisioning *inq_lbp;
9ae3a8
         struct scsi_inquiry_block_limits *inq_bl;
9ae3a8
-        task = iscsi_do_inquiry(iscsilun->iscsi, iscsilun->lun, 1,
9ae3a8
-                                SCSI_INQUIRY_PAGECODE_BLOCK_LIMITS, errp);
9ae3a8
-        if (task == NULL) {
9ae3a8
-            ret = -EINVAL;
9ae3a8
-            goto out;
9ae3a8
-        }
9ae3a8
-        inq_bl = scsi_datain_unmarshall(task);
9ae3a8
-        if (inq_bl == NULL) {
9ae3a8
-            error_setg(errp, "iSCSI: failed to unmarshall inquiry datain blob");
9ae3a8
-            ret = -EINVAL;
9ae3a8
-            goto out;
9ae3a8
+        switch (inq_vpd->pages[i]) {
9ae3a8
+        case SCSI_INQUIRY_PAGECODE_LOGICAL_BLOCK_PROVISIONING:
9ae3a8
+            inq_task = iscsi_do_inquiry(iscsilun->iscsi, iscsilun->lun, 1,
9ae3a8
+                                        SCSI_INQUIRY_PAGECODE_LOGICAL_BLOCK_PROVISIONING,
9ae3a8
+                                        (void **) &inq_lbp, errp);
9ae3a8
+            if (inq_task == NULL) {
9ae3a8
+                ret = -EINVAL;
9ae3a8
+                goto out;
9ae3a8
+            }
9ae3a8
+            memcpy(&iscsilun->lbp, inq_lbp,
9ae3a8
+                   sizeof(struct scsi_inquiry_logical_block_provisioning));
9ae3a8
+            scsi_free_scsi_task(inq_task);
9ae3a8
+            break;
9ae3a8
+        case SCSI_INQUIRY_PAGECODE_BLOCK_LIMITS:
9ae3a8
+            inq_task = iscsi_do_inquiry(iscsilun->iscsi, iscsilun->lun, 1,
9ae3a8
+                                    SCSI_INQUIRY_PAGECODE_BLOCK_LIMITS,
9ae3a8
+                                    (void **) &inq_bl, errp);
9ae3a8
+            if (inq_task == NULL) {
9ae3a8
+                ret = -EINVAL;
9ae3a8
+                goto out;
9ae3a8
+            }
9ae3a8
+            memcpy(&iscsilun->bl, inq_bl,
9ae3a8
+                   sizeof(struct scsi_inquiry_block_limits));
9ae3a8
+            scsi_free_scsi_task(inq_task);
9ae3a8
+            break;
9ae3a8
+        default:
9ae3a8
+            break;
9ae3a8
         }
9ae3a8
-        memcpy(&iscsilun->bl, inq_bl,
9ae3a8
-               sizeof(struct scsi_inquiry_block_limits));
9ae3a8
-        scsi_free_scsi_task(task);
9ae3a8
-        task = NULL;
9ae3a8
     }
9ae3a8
+    scsi_free_scsi_task(task);
9ae3a8
+    task = NULL;
9ae3a8
 
9ae3a8
 #if defined(LIBISCSI_FEATURE_NOP_COUNTER)
9ae3a8
     /* Set up a timer for sending out iSCSI NOPs */
9ae3a8
-- 
9ae3a8
1.7.1
9ae3a8