From: Greg Kroah-Hartman Date: Sun, 25 Jan 2015 17:32:24 +0000 (-0800) Subject: 3.14-stable patches X-Git-Tag: v3.10.66~13 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=5b01c73234f2f00dc5ad1dd3b6fcc138472578e9;p=thirdparty%2Fkernel%2Fstable-queue.git 3.14-stable patches 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 --- diff --git a/queue-3.14/series b/queue-3.14/series index f509c32cfbb..528255766d3 100644 --- a/queue-3.14/series +++ b/queue-3.14/series @@ -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 index 00000000000..81f823db1f8 --- /dev/null +++ b/queue-3.14/tcm_loop-fix-wrong-i_t-nexus-association.patch @@ -0,0 +1,225 @@ +From 506787a2c7daed45f0a213674ca706cbc83a9089 Mon Sep 17 00:00:00 2001 +From: Hannes Reinecke +Date: Wed, 26 Nov 2014 14:58:57 +0100 +Subject: tcm_loop: Fix wrong I_T nexus association + +From: Hannes Reinecke + +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 +Signed-off-by: Nicholas Bellinger +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..9c233d93f9a --- /dev/null +++ b/queue-3.14/tcm_loop-fixup-tag-handling.patch @@ -0,0 +1,75 @@ +From 6375f8908255ea7438b60bb5998e6b3e1628500d Mon Sep 17 00:00:00 2001 +From: Hannes Reinecke +Date: Thu, 2 Oct 2014 09:30:55 +0200 +Subject: tcm_loop: Fixup tag handling + +From: Hannes Reinecke + +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 +Reviewed-by: Sagi Grimberg +Signed-off-by: Nicholas Bellinger +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..1df194a46a5 --- /dev/null +++ b/queue-3.14/vhost-scsi-add-missing-virtio-scsi-tcm-attribute-conversion.patch @@ -0,0 +1,68 @@ +From 46243860806bdc2756f3ce8ac86b4d7c616bcd6c Mon Sep 17 00:00:00 2001 +From: Nicholas Bellinger +Date: Sun, 21 Dec 2014 10:42:08 -0800 +Subject: vhost-scsi: Add missing virtio-scsi -> TCM attribute conversion + +From: Nicholas Bellinger + +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 +Cc: Michael S. Tsirkin +Cc: Paolo Bonzini +Signed-off-by: Nicholas Bellinger +Signed-off-by: Greg Kroah-Hartman + + +--- + 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);