]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
3.14-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Sun, 25 Jan 2015 17:32:24 +0000 (09:32 -0800)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Sun, 25 Jan 2015 17:32:24 +0000 (09:32 -0800)
added patches:
tcm_loop-fix-wrong-i_t-nexus-association.patch
tcm_loop-fixup-tag-handling.patch
vhost-scsi-add-missing-virtio-scsi-tcm-attribute-conversion.patch

queue-3.14/series
queue-3.14/tcm_loop-fix-wrong-i_t-nexus-association.patch [new file with mode: 0644]
queue-3.14/tcm_loop-fixup-tag-handling.patch [new file with mode: 0644]
queue-3.14/vhost-scsi-add-missing-virtio-scsi-tcm-attribute-conversion.patch [new file with mode: 0644]

index f509c32cfbb49b9ebc6fda364c04fc5eead0620a..528255766d3319d86719fc7af0ed0e69f808a3c8 100644 (file)
@@ -79,3 +79,6 @@ decompress_bunzip2-off-by-one-in-get_next_block.patch
 um-skip-futex_atomic_cmpxchg_inatomic-test.patch
 x86-um-actually-mark-system-call-tables-readonly.patch
 lockd-fix-a-race-when-initialising-nlmsvc_timeout.patch
+tcm_loop-fixup-tag-handling.patch
+tcm_loop-fix-wrong-i_t-nexus-association.patch
+vhost-scsi-add-missing-virtio-scsi-tcm-attribute-conversion.patch
diff --git a/queue-3.14/tcm_loop-fix-wrong-i_t-nexus-association.patch b/queue-3.14/tcm_loop-fix-wrong-i_t-nexus-association.patch
new file mode 100644 (file)
index 0000000..81f823d
--- /dev/null
@@ -0,0 +1,225 @@
+From 506787a2c7daed45f0a213674ca706cbc83a9089 Mon Sep 17 00:00:00 2001
+From: Hannes Reinecke <hare@suse.de>
+Date: Wed, 26 Nov 2014 14:58:57 +0100
+Subject: tcm_loop: Fix wrong I_T nexus association
+
+From: Hannes Reinecke <hare@suse.de>
+
+commit 506787a2c7daed45f0a213674ca706cbc83a9089 upstream.
+
+tcm_loop has the I_T nexus associated with the HBA. This causes
+commands to become misdirected if the HBA has more than one
+target portal group; any command is then being sent to the
+first target portal group instead of the correct one.
+
+The nexus needs to be associated with the target portal group
+instead.
+
+Signed-off-by: Hannes Reinecke <hare@suse.de>
+Signed-off-by: Nicholas Bellinger <nab@linux-iscsi.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/target/loopback/tcm_loop.c |   66 ++++++++++++-------------------------
+ drivers/target/loopback/tcm_loop.h |    7 ---
+ 2 files changed, 24 insertions(+), 49 deletions(-)
+
+--- a/drivers/target/loopback/tcm_loop.c
++++ b/drivers/target/loopback/tcm_loop.c
+@@ -190,7 +190,7 @@ static void tcm_loop_submission_work(str
+               set_host_byte(sc, DID_TRANSPORT_DISRUPTED);
+               goto out_done;
+       }
+-      tl_nexus = tl_hba->tl_nexus;
++      tl_nexus = tl_tpg->tl_nexus;
+       if (!tl_nexus) {
+               scmd_printk(KERN_ERR, sc, "TCM_Loop I_T Nexus"
+                               " does not exist\n");
+@@ -256,16 +256,26 @@ static int tcm_loop_queuecommand(struct
+  * to struct scsi_device
+  */
+ static int tcm_loop_issue_tmr(struct tcm_loop_tpg *tl_tpg,
+-                            struct tcm_loop_nexus *tl_nexus,
+                             int lun, int task, enum tcm_tmreq_table tmr)
+ {
+       struct se_cmd *se_cmd = NULL;
+       struct se_session *se_sess;
+       struct se_portal_group *se_tpg;
++      struct tcm_loop_nexus *tl_nexus;
+       struct tcm_loop_cmd *tl_cmd = NULL;
+       struct tcm_loop_tmr *tl_tmr = NULL;
+       int ret = TMR_FUNCTION_FAILED, rc;
++      /*
++       * Locate the tl_nexus and se_sess pointers
++       */
++      tl_nexus = tl_tpg->tl_nexus;
++      if (!tl_nexus) {
++              pr_err("Unable to perform device reset without"
++                              " active I_T Nexus\n");
++              return ret;
++      }
++
+       tl_cmd = kmem_cache_zalloc(tcm_loop_cmd_cache, GFP_KERNEL);
+       if (!tl_cmd) {
+               pr_err("Unable to allocate memory for tl_cmd\n");
+@@ -281,7 +291,7 @@ static int tcm_loop_issue_tmr(struct tcm
+       se_cmd = &tl_cmd->tl_se_cmd;
+       se_tpg = &tl_tpg->tl_se_tpg;
+-      se_sess = tl_nexus->se_sess;
++      se_sess = tl_tpg->tl_nexus->se_sess;
+       /*
+        * Initialize struct se_cmd descriptor from target_core_mod infrastructure
+        */
+@@ -326,7 +336,6 @@ release:
+ static int tcm_loop_abort_task(struct scsi_cmnd *sc)
+ {
+       struct tcm_loop_hba *tl_hba;
+-      struct tcm_loop_nexus *tl_nexus;
+       struct tcm_loop_tpg *tl_tpg;
+       int ret = FAILED;
+@@ -334,21 +343,8 @@ static int tcm_loop_abort_task(struct sc
+        * Locate the tcm_loop_hba_t pointer
+        */
+       tl_hba = *(struct tcm_loop_hba **)shost_priv(sc->device->host);
+-      /*
+-       * Locate the tl_nexus and se_sess pointers
+-       */
+-      tl_nexus = tl_hba->tl_nexus;
+-      if (!tl_nexus) {
+-              pr_err("Unable to perform device reset without"
+-                              " active I_T Nexus\n");
+-              return FAILED;
+-      }
+-
+-      /*
+-       * Locate the tl_tpg pointer from TargetID in sc->device->id
+-       */
+       tl_tpg = &tl_hba->tl_hba_tpgs[sc->device->id];
+-      ret = tcm_loop_issue_tmr(tl_tpg, tl_nexus, sc->device->lun,
++      ret = tcm_loop_issue_tmr(tl_tpg, sc->device->lun,
+                                sc->request->tag, TMR_ABORT_TASK);
+       return (ret == TMR_FUNCTION_COMPLETE) ? SUCCESS : FAILED;
+ }
+@@ -360,7 +356,6 @@ static int tcm_loop_abort_task(struct sc
+ static int tcm_loop_device_reset(struct scsi_cmnd *sc)
+ {
+       struct tcm_loop_hba *tl_hba;
+-      struct tcm_loop_nexus *tl_nexus;
+       struct tcm_loop_tpg *tl_tpg;
+       int ret = FAILED;
+@@ -368,20 +363,9 @@ static int tcm_loop_device_reset(struct
+        * Locate the tcm_loop_hba_t pointer
+        */
+       tl_hba = *(struct tcm_loop_hba **)shost_priv(sc->device->host);
+-      /*
+-       * Locate the tl_nexus and se_sess pointers
+-       */
+-      tl_nexus = tl_hba->tl_nexus;
+-      if (!tl_nexus) {
+-              pr_err("Unable to perform device reset without"
+-                              " active I_T Nexus\n");
+-              return FAILED;
+-      }
+-      /*
+-       * Locate the tl_tpg pointer from TargetID in sc->device->id
+-       */
+       tl_tpg = &tl_hba->tl_hba_tpgs[sc->device->id];
+-      ret = tcm_loop_issue_tmr(tl_tpg, tl_nexus, sc->device->lun,
++
++      ret = tcm_loop_issue_tmr(tl_tpg, sc->device->lun,
+                                0, TMR_LUN_RESET);
+       return (ret == TMR_FUNCTION_COMPLETE) ? SUCCESS : FAILED;
+ }
+@@ -988,8 +972,8 @@ static int tcm_loop_make_nexus(
+       struct tcm_loop_nexus *tl_nexus;
+       int ret = -ENOMEM;
+-      if (tl_tpg->tl_hba->tl_nexus) {
+-              pr_debug("tl_tpg->tl_hba->tl_nexus already exists\n");
++      if (tl_tpg->tl_nexus) {
++              pr_debug("tl_tpg->tl_nexus already exists\n");
+               return -EEXIST;
+       }
+       se_tpg = &tl_tpg->tl_se_tpg;
+@@ -1024,7 +1008,7 @@ static int tcm_loop_make_nexus(
+        */
+       __transport_register_session(se_tpg, tl_nexus->se_sess->se_node_acl,
+                       tl_nexus->se_sess, tl_nexus);
+-      tl_tpg->tl_hba->tl_nexus = tl_nexus;
++      tl_tpg->tl_nexus = tl_nexus;
+       pr_debug("TCM_Loop_ConfigFS: Established I_T Nexus to emulated"
+               " %s Initiator Port: %s\n", tcm_loop_dump_proto_id(tl_hba),
+               name);
+@@ -1040,12 +1024,8 @@ static int tcm_loop_drop_nexus(
+ {
+       struct se_session *se_sess;
+       struct tcm_loop_nexus *tl_nexus;
+-      struct tcm_loop_hba *tl_hba = tpg->tl_hba;
+-      if (!tl_hba)
+-              return -ENODEV;
+-
+-      tl_nexus = tl_hba->tl_nexus;
++      tl_nexus = tpg->tl_nexus;
+       if (!tl_nexus)
+               return -ENODEV;
+@@ -1061,13 +1041,13 @@ static int tcm_loop_drop_nexus(
+       }
+       pr_debug("TCM_Loop_ConfigFS: Removing I_T Nexus to emulated"
+-              " %s Initiator Port: %s\n", tcm_loop_dump_proto_id(tl_hba),
++              " %s Initiator Port: %s\n", tcm_loop_dump_proto_id(tpg->tl_hba),
+               tl_nexus->se_sess->se_node_acl->initiatorname);
+       /*
+        * Release the SCSI I_T Nexus to the emulated SAS Target Port
+        */
+       transport_deregister_session(tl_nexus->se_sess);
+-      tpg->tl_hba->tl_nexus = NULL;
++      tpg->tl_nexus = NULL;
+       kfree(tl_nexus);
+       return 0;
+ }
+@@ -1083,7 +1063,7 @@ static ssize_t tcm_loop_tpg_show_nexus(
+       struct tcm_loop_nexus *tl_nexus;
+       ssize_t ret;
+-      tl_nexus = tl_tpg->tl_hba->tl_nexus;
++      tl_nexus = tl_tpg->tl_nexus;
+       if (!tl_nexus)
+               return -ENODEV;
+--- a/drivers/target/loopback/tcm_loop.h
++++ b/drivers/target/loopback/tcm_loop.h
+@@ -27,11 +27,6 @@ struct tcm_loop_tmr {
+ };
+ struct tcm_loop_nexus {
+-      int it_nexus_active;
+-      /*
+-       * Pointer to Linux/SCSI HBA from linux/include/scsi_host.h
+-       */
+-      struct scsi_host *sh;
+       /*
+        * Pointer to TCM session for I_T Nexus
+        */
+@@ -51,6 +46,7 @@ struct tcm_loop_tpg {
+       atomic_t tl_tpg_port_count;
+       struct se_portal_group tl_se_tpg;
+       struct tcm_loop_hba *tl_hba;
++      struct tcm_loop_nexus *tl_nexus;
+ };
+ struct tcm_loop_hba {
+@@ -59,7 +55,6 @@ struct tcm_loop_hba {
+       struct se_hba_s *se_hba;
+       struct se_lun *tl_hba_lun;
+       struct se_port *tl_hba_lun_sep;
+-      struct tcm_loop_nexus *tl_nexus;
+       struct device dev;
+       struct Scsi_Host *sh;
+       struct tcm_loop_tpg tl_hba_tpgs[TL_TPGS_PER_HBA];
diff --git a/queue-3.14/tcm_loop-fixup-tag-handling.patch b/queue-3.14/tcm_loop-fixup-tag-handling.patch
new file mode 100644 (file)
index 0000000..9c233d9
--- /dev/null
@@ -0,0 +1,75 @@
+From 6375f8908255ea7438b60bb5998e6b3e1628500d Mon Sep 17 00:00:00 2001
+From: Hannes Reinecke <hare@suse.de>
+Date: Thu, 2 Oct 2014 09:30:55 +0200
+Subject: tcm_loop: Fixup tag handling
+
+From: Hannes Reinecke <hare@suse.de>
+
+commit 6375f8908255ea7438b60bb5998e6b3e1628500d upstream.
+
+The SCSI command tag is set to the tag assigned from the block
+layer, not the SCSI-II tag message. So we need to convert
+it into the correct SCSI-II tag message based on the
+device flags, not the tag value itself.
+
+Signed-off-by: Hannes Reinecke <hare@suse.de>
+Reviewed-by: Sagi Grimberg <sagig@mellanox.com>
+Signed-off-by: Nicholas Bellinger <nab@linux-iscsi.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/target/loopback/tcm_loop.c |   21 +++++++--------------
+ 1 file changed, 7 insertions(+), 14 deletions(-)
+
+--- a/drivers/target/loopback/tcm_loop.c
++++ b/drivers/target/loopback/tcm_loop.c
+@@ -153,18 +153,11 @@ static int tcm_loop_change_queue_type(st
+ /*
+  * Locate the SAM Task Attr from struct scsi_cmnd *
+  */
+-static int tcm_loop_sam_attr(struct scsi_cmnd *sc)
++static int tcm_loop_sam_attr(struct scsi_cmnd *sc, int tag)
+ {
+-      if (sc->device->tagged_supported) {
+-              switch (sc->tag) {
+-              case HEAD_OF_QUEUE_TAG:
+-                      return MSG_HEAD_TAG;
+-              case ORDERED_QUEUE_TAG:
+-                      return MSG_ORDERED_TAG;
+-              default:
+-                      break;
+-              }
+-      }
++      if (sc->device->tagged_supported &&
++          sc->device->ordered_tags && tag >= 0)
++              return MSG_ORDERED_TAG;
+       return MSG_SIMPLE_TAG;
+ }
+@@ -214,7 +207,7 @@ static void tcm_loop_submission_work(str
+       }
+       rc = target_submit_cmd_map_sgls(se_cmd, tl_nexus->se_sess, sc->cmnd,
+                       &tl_cmd->tl_sense_buf[0], tl_cmd->sc->device->lun,
+-                      scsi_bufflen(sc), tcm_loop_sam_attr(sc),
++                      scsi_bufflen(sc), tcm_loop_sam_attr(sc, tl_cmd->sc_cmd_tag),
+                       sc->sc_data_direction, 0,
+                       scsi_sglist(sc), scsi_sg_count(sc),
+                       sgl_bidi, sgl_bidi_count,
+@@ -252,7 +245,7 @@ static int tcm_loop_queuecommand(struct
+       }
+       tl_cmd->sc = sc;
+-      tl_cmd->sc_cmd_tag = sc->tag;
++      tl_cmd->sc_cmd_tag = sc->request->tag;
+       INIT_WORK(&tl_cmd->work, tcm_loop_submission_work);
+       queue_work(tcm_loop_workqueue, &tl_cmd->work);
+       return 0;
+@@ -356,7 +349,7 @@ static int tcm_loop_abort_task(struct sc
+        */
+       tl_tpg = &tl_hba->tl_hba_tpgs[sc->device->id];
+       ret = tcm_loop_issue_tmr(tl_tpg, tl_nexus, sc->device->lun,
+-                               sc->tag, TMR_ABORT_TASK);
++                               sc->request->tag, TMR_ABORT_TASK);
+       return (ret == TMR_FUNCTION_COMPLETE) ? SUCCESS : FAILED;
+ }
diff --git a/queue-3.14/vhost-scsi-add-missing-virtio-scsi-tcm-attribute-conversion.patch b/queue-3.14/vhost-scsi-add-missing-virtio-scsi-tcm-attribute-conversion.patch
new file mode 100644 (file)
index 0000000..1df194a
--- /dev/null
@@ -0,0 +1,68 @@
+From 46243860806bdc2756f3ce8ac86b4d7c616bcd6c Mon Sep 17 00:00:00 2001
+From: Nicholas Bellinger <nab@linux-iscsi.org>
+Date: Sun, 21 Dec 2014 10:42:08 -0800
+Subject: vhost-scsi: Add missing virtio-scsi -> TCM attribute conversion
+
+From: Nicholas Bellinger <nab@linux-iscsi.org>
+
+commit 46243860806bdc2756f3ce8ac86b4d7c616bcd6c upstream.
+
+While looking at hch's recent conversion to drop the MSG_*_TAG
+definitions, I noticed a long standing bug in vhost-scsi where
+the VIRTIO_SCSI_S_* attribute definitions where incorrectly
+being passed directly into target_submit_cmd_map_sgls().
+
+This patch adds the missing virtio-scsi to TCM/SAM task attribute
+conversion.
+
+Cc: Christoph Hellwig <hch@lst.de>
+Cc: Michael S. Tsirkin <mst@redhat.com>
+Cc: Paolo Bonzini <pbonzini@redhat.com>
+Signed-off-by: Nicholas Bellinger <nab@linux-iscsi.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+
+---
+ drivers/vhost/scsi.c |   24 +++++++++++++++++++++---
+ 1 file changed, 21 insertions(+), 3 deletions(-)
+
+--- a/drivers/vhost/scsi.c
++++ b/drivers/vhost/scsi.c
+@@ -861,6 +861,23 @@ vhost_scsi_map_iov_to_sgl(struct tcm_vho
+       return 0;
+ }
++static int vhost_scsi_to_tcm_attr(int attr)
++{
++      switch (attr) {
++      case VIRTIO_SCSI_S_SIMPLE:
++              return MSG_SIMPLE_TAG;
++      case VIRTIO_SCSI_S_ORDERED:
++              return MSG_ORDERED_TAG;
++      case VIRTIO_SCSI_S_HEAD:
++              return MSG_HEAD_TAG;
++      case VIRTIO_SCSI_S_ACA:
++              return MSG_ACA_TAG;
++      default:
++              break;
++      }
++      return MSG_SIMPLE_TAG;
++}
++
+ static void tcm_vhost_submission_work(struct work_struct *work)
+ {
+       struct tcm_vhost_cmd *cmd =
+@@ -887,9 +904,10 @@ static void tcm_vhost_submission_work(st
+       rc = target_submit_cmd_map_sgls(se_cmd, tv_nexus->tvn_se_sess,
+                       cmd->tvc_cdb, &cmd->tvc_sense_buf[0],
+                       cmd->tvc_lun, cmd->tvc_exp_data_len,
+-                      cmd->tvc_task_attr, cmd->tvc_data_direction,
+-                      TARGET_SCF_ACK_KREF, sg_ptr, cmd->tvc_sgl_count,
+-                      sg_bidi_ptr, sg_no_bidi, NULL, 0);
++                      vhost_scsi_to_tcm_attr(cmd->tvc_task_attr),
++                      cmd->tvc_data_direction, TARGET_SCF_ACK_KREF,
++                      sg_ptr, cmd->tvc_sgl_count, sg_bidi_ptr, sg_no_bidi,
++                      NULL, 0);
+       if (rc < 0) {
+               transport_send_check_condition_and_sense(se_cmd,
+                               TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE, 0);