From 0662ad47123c102f2ad3de16391f00859537eb35 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Fri, 27 Jun 2014 17:13:10 -0700 Subject: [PATCH] 3.15-stable patches added patches: iscsi-target-fix-abort_task-connection-reset-iscsi_queue_req-memory-leak.patch libiscsi-iser-adjust-data_length-to-include-protection-information.patch scsi_cmnd-introduce-scsi_transfer_length-helper.patch target-iscsi-fix-sendtargets-response-pdu-for-iser-transport.patch target-iser-fix-a-wrong-dereference-in-case-discovery-session-is-over-iser.patch target-iser-gracefully-reject-t10-pi-enabled-connect-request-if-not-supported.patch target-iser-improve-cm-events-handling.patch target-iser-wait-for-proper-cleanup-before-unloading.patch target-report-correct-response-length-for-some-commands.patch target-sbc-loopback-adjust-command-data-length-in-case-pi-exists-on-the-wire.patch target-set-cmd_t_active-bit-for-task-management-requests.patch target-use-complete_all-for-se_cmd-t_transport_stop_comp.patch --- ...on-reset-iscsi_queue_req-memory-leak.patch | 48 +++++ ...th-to-include-protection-information.patch | 170 ++++++++++++++++++ ...ntroduce-scsi_transfer_length-helper.patch | 56 ++++++ queue-3.15/series | 12 ++ ...gets-response-pdu-for-iser-transport.patch | 98 ++++++++++ ...-case-discovery-session-is-over-iser.patch | 36 ++++ ...led-connect-request-if-not-supported.patch | 35 ++++ ...rget-iser-improve-cm-events-handling.patch | 113 ++++++++++++ ...-for-proper-cleanup-before-unloading.patch | 31 ++++ ...ct-response-length-for-some-commands.patch | 145 +++++++++++++++ ...length-in-case-pi-exists-on-the-wire.patch | 87 +++++++++ ...ive-bit-for-task-management-requests.patch | 42 +++++ ...all-for-se_cmd-t_transport_stop_comp.patch | 56 ++++++ 13 files changed, 929 insertions(+) create mode 100644 queue-3.15/iscsi-target-fix-abort_task-connection-reset-iscsi_queue_req-memory-leak.patch create mode 100644 queue-3.15/libiscsi-iser-adjust-data_length-to-include-protection-information.patch create mode 100644 queue-3.15/scsi_cmnd-introduce-scsi_transfer_length-helper.patch create mode 100644 queue-3.15/target-iscsi-fix-sendtargets-response-pdu-for-iser-transport.patch create mode 100644 queue-3.15/target-iser-fix-a-wrong-dereference-in-case-discovery-session-is-over-iser.patch create mode 100644 queue-3.15/target-iser-gracefully-reject-t10-pi-enabled-connect-request-if-not-supported.patch create mode 100644 queue-3.15/target-iser-improve-cm-events-handling.patch create mode 100644 queue-3.15/target-iser-wait-for-proper-cleanup-before-unloading.patch create mode 100644 queue-3.15/target-report-correct-response-length-for-some-commands.patch create mode 100644 queue-3.15/target-sbc-loopback-adjust-command-data-length-in-case-pi-exists-on-the-wire.patch create mode 100644 queue-3.15/target-set-cmd_t_active-bit-for-task-management-requests.patch create mode 100644 queue-3.15/target-use-complete_all-for-se_cmd-t_transport_stop_comp.patch diff --git a/queue-3.15/iscsi-target-fix-abort_task-connection-reset-iscsi_queue_req-memory-leak.patch b/queue-3.15/iscsi-target-fix-abort_task-connection-reset-iscsi_queue_req-memory-leak.patch new file mode 100644 index 00000000000..0b66930b783 --- /dev/null +++ b/queue-3.15/iscsi-target-fix-abort_task-connection-reset-iscsi_queue_req-memory-leak.patch @@ -0,0 +1,48 @@ +From bbc050488525e1ab1194c27355f63c66814385b8 Mon Sep 17 00:00:00 2001 +From: Nicholas Bellinger +Date: Tue, 10 Jun 2014 04:03:54 +0000 +Subject: iscsi-target: Fix ABORT_TASK + connection reset iscsi_queue_req memory leak + +From: Nicholas Bellinger + +commit bbc050488525e1ab1194c27355f63c66814385b8 upstream. + +This patch fixes a iscsi_queue_req memory leak when ABORT_TASK response +has been queued by TFO->queue_tm_rsp() -> lio_queue_tm_rsp() after a +long standing I/O completes, but the connection has already reset and +waiting for cleanup to complete in iscsit_release_commands_from_conn() +-> transport_generic_free_cmd() -> transport_wait_for_tasks() code. + +It moves iscsit_free_queue_reqs_for_conn() after the per-connection command +list has been released, so that the associated se_cmd tag can be completed + +released by target-core before freeing any remaining iscsi_queue_req memory +for the connection generated by lio_queue_tm_rsp(). + +Cc: Thomas Glanzmann +Cc: Charalampos Pournaris +Signed-off-by: Nicholas Bellinger +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/target/iscsi/iscsi_target.c | 3 +-- + 1 file changed, 1 insertion(+), 2 deletions(-) + +--- a/drivers/target/iscsi/iscsi_target.c ++++ b/drivers/target/iscsi/iscsi_target.c +@@ -4234,8 +4234,6 @@ int iscsit_close_connection( + if (conn->conn_transport->iscsit_wait_conn) + conn->conn_transport->iscsit_wait_conn(conn); + +- iscsit_free_queue_reqs_for_conn(conn); +- + /* + * During Connection recovery drop unacknowledged out of order + * commands for this connection, and prepare the other commands +@@ -4252,6 +4250,7 @@ int iscsit_close_connection( + iscsit_clear_ooo_cmdsns_for_conn(conn); + iscsit_release_commands_from_conn(conn); + } ++ iscsit_free_queue_reqs_for_conn(conn); + + /* + * Handle decrementing session or connection usage count if diff --git a/queue-3.15/libiscsi-iser-adjust-data_length-to-include-protection-information.patch b/queue-3.15/libiscsi-iser-adjust-data_length-to-include-protection-information.patch new file mode 100644 index 00000000000..e9a3a9df2df --- /dev/null +++ b/queue-3.15/libiscsi-iser-adjust-data_length-to-include-protection-information.patch @@ -0,0 +1,170 @@ +From d77e65350f2d82dfa0557707d505711f5a43c8fd Mon Sep 17 00:00:00 2001 +From: Sagi Grimberg +Date: Wed, 11 Jun 2014 12:09:58 +0300 +Subject: libiscsi, iser: Adjust data_length to include protection information + +From: Sagi Grimberg + +commit d77e65350f2d82dfa0557707d505711f5a43c8fd upstream. + +In case protection information exists over the wire +iscsi header data length is required to include it. +Use protection information aware scsi helpers to set +the correct transfer length. + +In order to avoid breakage, remove iser transfer length +checks for each task as they are not always true and +somewhat redundant anyway. + +Signed-off-by: Sagi Grimberg +Reviewed-by: Mike Christie +Acked-by: Mike Christie +Signed-off-by: Nicholas Bellinger +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/infiniband/ulp/iser/iser_initiator.c | 34 +++++++-------------------- + drivers/scsi/libiscsi.c | 18 +++++++------- + 2 files changed, 19 insertions(+), 33 deletions(-) + +--- a/drivers/infiniband/ulp/iser/iser_initiator.c ++++ b/drivers/infiniband/ulp/iser/iser_initiator.c +@@ -41,11 +41,11 @@ + #include "iscsi_iser.h" + + /* Register user buffer memory and initialize passive rdma +- * dto descriptor. Total data size is stored in +- * iser_task->data[ISER_DIR_IN].data_len ++ * dto descriptor. Data size is stored in ++ * task->data[ISER_DIR_IN].data_len, Protection size ++ * os stored in task->prot[ISER_DIR_IN].data_len + */ +-static int iser_prepare_read_cmd(struct iscsi_task *task, +- unsigned int edtl) ++static int iser_prepare_read_cmd(struct iscsi_task *task) + + { + struct iscsi_iser_task *iser_task = task->dd_data; +@@ -73,14 +73,6 @@ static int iser_prepare_read_cmd(struct + return err; + } + +- if (edtl > iser_task->data[ISER_DIR_IN].data_len) { +- iser_err("Total data length: %ld, less than EDTL: " +- "%d, in READ cmd BHS itt: %d, conn: 0x%p\n", +- iser_task->data[ISER_DIR_IN].data_len, edtl, +- task->itt, iser_task->ib_conn); +- return -EINVAL; +- } +- + err = device->iser_reg_rdma_mem(iser_task, ISER_DIR_IN); + if (err) { + iser_err("Failed to set up Data-IN RDMA\n"); +@@ -100,8 +92,9 @@ static int iser_prepare_read_cmd(struct + } + + /* Register user buffer memory and initialize passive rdma +- * dto descriptor. Total data size is stored in +- * task->data[ISER_DIR_OUT].data_len ++ * dto descriptor. Data size is stored in ++ * task->data[ISER_DIR_OUT].data_len, Protection size ++ * is stored at task->prot[ISER_DIR_OUT].data_len + */ + static int + iser_prepare_write_cmd(struct iscsi_task *task, +@@ -135,14 +128,6 @@ iser_prepare_write_cmd(struct iscsi_task + return err; + } + +- if (edtl > iser_task->data[ISER_DIR_OUT].data_len) { +- iser_err("Total data length: %ld, less than EDTL: %d, " +- "in WRITE cmd BHS itt: %d, conn: 0x%p\n", +- iser_task->data[ISER_DIR_OUT].data_len, +- edtl, task->itt, task->conn); +- return -EINVAL; +- } +- + err = device->iser_reg_rdma_mem(iser_task, ISER_DIR_OUT); + if (err != 0) { + iser_err("Failed to register write cmd RDMA mem\n"); +@@ -417,11 +402,12 @@ int iser_send_command(struct iscsi_conn + if (scsi_prot_sg_count(sc)) { + prot_buf->buf = scsi_prot_sglist(sc); + prot_buf->size = scsi_prot_sg_count(sc); +- prot_buf->data_len = sc->prot_sdb->length; ++ prot_buf->data_len = data_buf->data_len >> ++ ilog2(sc->device->sector_size) * 8; + } + + if (hdr->flags & ISCSI_FLAG_CMD_READ) { +- err = iser_prepare_read_cmd(task, edtl); ++ err = iser_prepare_read_cmd(task); + if (err) + goto send_command_error; + } +--- a/drivers/scsi/libiscsi.c ++++ b/drivers/scsi/libiscsi.c +@@ -338,7 +338,7 @@ static int iscsi_prep_scsi_cmd_pdu(struc + struct iscsi_session *session = conn->session; + struct scsi_cmnd *sc = task->sc; + struct iscsi_scsi_req *hdr; +- unsigned hdrlength, cmd_len; ++ unsigned hdrlength, cmd_len, transfer_length; + itt_t itt; + int rc; + +@@ -391,11 +391,11 @@ static int iscsi_prep_scsi_cmd_pdu(struc + if (scsi_get_prot_op(sc) != SCSI_PROT_NORMAL) + task->protected = true; + ++ transfer_length = scsi_transfer_length(sc); ++ hdr->data_length = cpu_to_be32(transfer_length); + if (sc->sc_data_direction == DMA_TO_DEVICE) { +- unsigned out_len = scsi_out(sc)->length; + struct iscsi_r2t_info *r2t = &task->unsol_r2t; + +- hdr->data_length = cpu_to_be32(out_len); + hdr->flags |= ISCSI_FLAG_CMD_WRITE; + /* + * Write counters: +@@ -414,18 +414,19 @@ static int iscsi_prep_scsi_cmd_pdu(struc + memset(r2t, 0, sizeof(*r2t)); + + if (session->imm_data_en) { +- if (out_len >= session->first_burst) ++ if (transfer_length >= session->first_burst) + task->imm_count = min(session->first_burst, + conn->max_xmit_dlength); + else +- task->imm_count = min(out_len, +- conn->max_xmit_dlength); ++ task->imm_count = min(transfer_length, ++ conn->max_xmit_dlength); + hton24(hdr->dlength, task->imm_count); + } else + zero_data(hdr->dlength); + + if (!session->initial_r2t_en) { +- r2t->data_length = min(session->first_burst, out_len) - ++ r2t->data_length = min(session->first_burst, ++ transfer_length) - + task->imm_count; + r2t->data_offset = task->imm_count; + r2t->ttt = cpu_to_be32(ISCSI_RESERVED_TAG); +@@ -438,7 +439,6 @@ static int iscsi_prep_scsi_cmd_pdu(struc + } else { + hdr->flags |= ISCSI_FLAG_CMD_FINAL; + zero_data(hdr->dlength); +- hdr->data_length = cpu_to_be32(scsi_in(sc)->length); + + if (sc->sc_data_direction == DMA_FROM_DEVICE) + hdr->flags |= ISCSI_FLAG_CMD_READ; +@@ -466,7 +466,7 @@ static int iscsi_prep_scsi_cmd_pdu(struc + scsi_bidi_cmnd(sc) ? "bidirectional" : + sc->sc_data_direction == DMA_TO_DEVICE ? + "write" : "read", conn->id, sc, sc->cmnd[0], +- task->itt, scsi_bufflen(sc), ++ task->itt, transfer_length, + scsi_bidi_cmnd(sc) ? scsi_in(sc)->length : 0, + session->cmdsn, + session->max_cmdsn - session->exp_cmdsn + 1); diff --git a/queue-3.15/scsi_cmnd-introduce-scsi_transfer_length-helper.patch b/queue-3.15/scsi_cmnd-introduce-scsi_transfer_length-helper.patch new file mode 100644 index 00000000000..ae02fcf25d4 --- /dev/null +++ b/queue-3.15/scsi_cmnd-introduce-scsi_transfer_length-helper.patch @@ -0,0 +1,56 @@ +From 8846bab180fa2bcfe02d4ba5288fbaba12c8f4f3 Mon Sep 17 00:00:00 2001 +From: Sagi Grimberg +Date: Wed, 11 Jun 2014 12:09:57 +0300 +Subject: scsi_cmnd: Introduce scsi_transfer_length helper + +From: Sagi Grimberg + +commit 8846bab180fa2bcfe02d4ba5288fbaba12c8f4f3 upstream. + +In case protection information exists on the wire +scsi transports should include it in the transfer +byte count (even if protection information does not +exist in the host memory space). This helper will +compute the total transfer length from the scsi +command data length and protection attributes. + +Signed-off-by: Sagi Grimberg +Signed-off-by: Martin K. Petersen +Signed-off-by: Nicholas Bellinger +Signed-off-by: Greg Kroah-Hartman + +--- + include/scsi/scsi_cmnd.h | 17 +++++++++++++++++ + 1 file changed, 17 insertions(+) + +--- a/include/scsi/scsi_cmnd.h ++++ b/include/scsi/scsi_cmnd.h +@@ -7,6 +7,7 @@ + #include + #include + #include ++#include + + struct Scsi_Host; + struct scsi_device; +@@ -306,4 +307,20 @@ static inline void set_driver_byte(struc + cmd->result = (cmd->result & 0x00ffffff) | (status << 24); + } + ++static inline unsigned scsi_transfer_length(struct scsi_cmnd *scmd) ++{ ++ unsigned int xfer_len = blk_rq_bytes(scmd->request); ++ unsigned int prot_op = scsi_get_prot_op(scmd); ++ unsigned int sector_size = scmd->device->sector_size; ++ ++ switch (prot_op) { ++ case SCSI_PROT_NORMAL: ++ case SCSI_PROT_WRITE_STRIP: ++ case SCSI_PROT_READ_INSERT: ++ return xfer_len; ++ } ++ ++ return xfer_len + (xfer_len >> ilog2(sector_size)) * 8; ++} ++ + #endif /* _SCSI_SCSI_CMND_H */ diff --git a/queue-3.15/series b/queue-3.15/series index 1c5833b0736..bc8e595c816 100644 --- a/queue-3.15/series +++ b/queue-3.15/series @@ -86,3 +86,15 @@ bluetooth-fix-requiring-smp-mitm-for-outgoing-connections.patch bluetooth-fix-missing-check-for-fips-security-level.patch target-iser-bail-from-accept_np-if-np_thread-is-trying-to-close.patch target-iser-fix-hangs-in-connection-teardown.patch +target-iser-improve-cm-events-handling.patch +target-iser-wait-for-proper-cleanup-before-unloading.patch +target-iser-gracefully-reject-t10-pi-enabled-connect-request-if-not-supported.patch +target-set-cmd_t_active-bit-for-task-management-requests.patch +target-use-complete_all-for-se_cmd-t_transport_stop_comp.patch +iscsi-target-fix-abort_task-connection-reset-iscsi_queue_req-memory-leak.patch +target-iser-fix-a-wrong-dereference-in-case-discovery-session-is-over-iser.patch +target-iscsi-fix-sendtargets-response-pdu-for-iser-transport.patch +target-report-correct-response-length-for-some-commands.patch +scsi_cmnd-introduce-scsi_transfer_length-helper.patch +libiscsi-iser-adjust-data_length-to-include-protection-information.patch +target-sbc-loopback-adjust-command-data-length-in-case-pi-exists-on-the-wire.patch diff --git a/queue-3.15/target-iscsi-fix-sendtargets-response-pdu-for-iser-transport.patch b/queue-3.15/target-iscsi-fix-sendtargets-response-pdu-for-iser-transport.patch new file mode 100644 index 00000000000..72dd785930f --- /dev/null +++ b/queue-3.15/target-iscsi-fix-sendtargets-response-pdu-for-iser-transport.patch @@ -0,0 +1,98 @@ +From 22c7aaa57e80853b4904a46c18f97db0036a3b97 Mon Sep 17 00:00:00 2001 +From: Sagi Grimberg +Date: Tue, 10 Jun 2014 18:27:59 +0300 +Subject: Target/iscsi: Fix sendtargets response pdu for iser transport + +From: Sagi Grimberg + +commit 22c7aaa57e80853b4904a46c18f97db0036a3b97 upstream. + +In case the transport is iser we should not include the +iscsi target info in the sendtargets text response pdu. +This causes sendtargets response to include the target +info twice. + +Modify iscsit_build_sendtargets_response to filter +transport types that don't match. + +Signed-off-by: Sagi Grimberg +Reported-by: Slava Shwartsman +Signed-off-by: Nicholas Bellinger +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/infiniband/ulp/isert/ib_isert.c | 2 +- + drivers/target/iscsi/iscsi_target.c | 14 ++++++++++---- + include/target/iscsi/iscsi_transport.h | 3 ++- + 3 files changed, 13 insertions(+), 6 deletions(-) + +--- a/drivers/infiniband/ulp/isert/ib_isert.c ++++ b/drivers/infiniband/ulp/isert/ib_isert.c +@@ -2320,7 +2320,7 @@ isert_put_text_rsp(struct iscsi_cmd *cmd + int rc; + + isert_create_send_desc(isert_conn, isert_cmd, &isert_cmd->tx_desc); +- rc = iscsit_build_text_rsp(cmd, conn, hdr); ++ rc = iscsit_build_text_rsp(cmd, conn, hdr, ISCSI_INFINIBAND); + if (rc < 0) + return rc; + +--- a/drivers/target/iscsi/iscsi_target.c ++++ b/drivers/target/iscsi/iscsi_target.c +@@ -3390,7 +3390,9 @@ static bool iscsit_check_inaddr_any(stru + + #define SENDTARGETS_BUF_LIMIT 32768U + +-static int iscsit_build_sendtargets_response(struct iscsi_cmd *cmd) ++static int ++iscsit_build_sendtargets_response(struct iscsi_cmd *cmd, ++ enum iscsit_transport_type network_transport) + { + char *payload = NULL; + struct iscsi_conn *conn = cmd->conn; +@@ -3467,6 +3469,9 @@ static int iscsit_build_sendtargets_resp + struct iscsi_np *np = tpg_np->tpg_np; + bool inaddr_any = iscsit_check_inaddr_any(np); + ++ if (np->np_network_transport != network_transport) ++ continue; ++ + if (!target_name_printed) { + len = sprintf(buf, "TargetName=%s", + tiqn->tiqn); +@@ -3520,11 +3525,12 @@ eob: + + int + iscsit_build_text_rsp(struct iscsi_cmd *cmd, struct iscsi_conn *conn, +- struct iscsi_text_rsp *hdr) ++ struct iscsi_text_rsp *hdr, ++ enum iscsit_transport_type network_transport) + { + int text_length, padding; + +- text_length = iscsit_build_sendtargets_response(cmd); ++ text_length = iscsit_build_sendtargets_response(cmd, network_transport); + if (text_length < 0) + return text_length; + +@@ -3562,7 +3568,7 @@ static int iscsit_send_text_rsp( + u32 tx_size = 0; + int text_length, iov_count = 0, rc; + +- rc = iscsit_build_text_rsp(cmd, conn, hdr); ++ rc = iscsit_build_text_rsp(cmd, conn, hdr, ISCSI_TCP); + if (rc < 0) + return rc; + +--- a/include/target/iscsi/iscsi_transport.h ++++ b/include/target/iscsi/iscsi_transport.h +@@ -70,7 +70,8 @@ extern void iscsit_build_nopin_rsp(struc + extern void iscsit_build_task_mgt_rsp(struct iscsi_cmd *, struct iscsi_conn *, + struct iscsi_tm_rsp *); + extern int iscsit_build_text_rsp(struct iscsi_cmd *, struct iscsi_conn *, +- struct iscsi_text_rsp *); ++ struct iscsi_text_rsp *, ++ enum iscsit_transport_type); + extern void iscsit_build_reject(struct iscsi_cmd *, struct iscsi_conn *, + struct iscsi_reject *); + extern int iscsit_build_logout_rsp(struct iscsi_cmd *, struct iscsi_conn *, diff --git a/queue-3.15/target-iser-fix-a-wrong-dereference-in-case-discovery-session-is-over-iser.patch b/queue-3.15/target-iser-fix-a-wrong-dereference-in-case-discovery-session-is-over-iser.patch new file mode 100644 index 00000000000..b08201a0161 --- /dev/null +++ b/queue-3.15/target-iser-fix-a-wrong-dereference-in-case-discovery-session-is-over-iser.patch @@ -0,0 +1,36 @@ +From e0546fc1ba66c90cb38a5764357366267d3e58e4 Mon Sep 17 00:00:00 2001 +From: Sagi Grimberg +Date: Tue, 10 Jun 2014 13:41:41 +0300 +Subject: Target/iser: Fix a wrong dereference in case discovery session is over iser + +From: Sagi Grimberg + +commit e0546fc1ba66c90cb38a5764357366267d3e58e4 upstream. + +In case the discovery session is carried over iser, we can't +access the assumed network portal since the default portal is +used. In this case we don't really need to allocate the fastreg +pool, just prepare to the text pdu that will follow. + +Signed-off-by: Sagi Grimberg +Reported-by: Alex Tabachnik +Signed-off-by: Nicholas Bellinger +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/infiniband/ulp/isert/ib_isert.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +--- a/drivers/infiniband/ulp/isert/ib_isert.c ++++ b/drivers/infiniband/ulp/isert/ib_isert.c +@@ -1053,7 +1053,9 @@ isert_put_login_tx(struct iscsi_conn *co + } + if (!login->login_failed) { + if (login->login_complete) { +- if (isert_conn->conn_device->use_fastreg) { ++ if (!conn->sess->sess_ops->SessionType && ++ isert_conn->conn_device->use_fastreg) { ++ /* Normal Session and fastreg is used */ + u8 pi_support = login->np->tpg_np->tpg->tpg_attrib.t10_pi; + + ret = isert_conn_create_fastreg_pool(isert_conn, diff --git a/queue-3.15/target-iser-gracefully-reject-t10-pi-enabled-connect-request-if-not-supported.patch b/queue-3.15/target-iser-gracefully-reject-t10-pi-enabled-connect-request-if-not-supported.patch new file mode 100644 index 00000000000..eb54f7808db --- /dev/null +++ b/queue-3.15/target-iser-gracefully-reject-t10-pi-enabled-connect-request-if-not-supported.patch @@ -0,0 +1,35 @@ +From 5f80ff8eccba50832dcc640ac89add4c7fced963 Mon Sep 17 00:00:00 2001 +From: Sagi Grimberg +Date: Tue, 20 May 2014 13:28:11 +0300 +Subject: Target/iser: Gracefully reject T10-PI enabled connect request if not supported + +From: Sagi Grimberg + +commit 5f80ff8eccba50832dcc640ac89add4c7fced963 upstream. + +In case user chose to set T10-PI enable on the target while +the IB device does not support it, gracefully reject the request. + +Reported-by: Slava Shwartsman +Signed-off-by: Sagi Grimberg +Signed-off-by: Nicholas Bellinger +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/infiniband/ulp/isert/ib_isert.c | 5 +++-- + 1 file changed, 3 insertions(+), 2 deletions(-) + +--- a/drivers/infiniband/ulp/isert/ib_isert.c ++++ b/drivers/infiniband/ulp/isert/ib_isert.c +@@ -663,8 +663,9 @@ isert_connect_request(struct rdma_cm_id + + pi_support = np->tpg_np->tpg->tpg_attrib.t10_pi; + if (pi_support && !device->pi_capable) { +- pr_err("Protection information requested but not supported\n"); +- ret = -EINVAL; ++ pr_err("Protection information requested but not supported, " ++ "rejecting connect request\n"); ++ ret = rdma_reject(cma_id, NULL, 0); + goto out_mr; + } + diff --git a/queue-3.15/target-iser-improve-cm-events-handling.patch b/queue-3.15/target-iser-improve-cm-events-handling.patch new file mode 100644 index 00000000000..c12a1550506 --- /dev/null +++ b/queue-3.15/target-iser-improve-cm-events-handling.patch @@ -0,0 +1,113 @@ +From 88c4015fda6d014392f76d3b1688347950d7a12d Mon Sep 17 00:00:00 2001 +From: Sagi Grimberg +Date: Mon, 19 May 2014 17:44:24 +0300 +Subject: Target/iser: Improve cm events handling + +From: Sagi Grimberg + +commit 88c4015fda6d014392f76d3b1688347950d7a12d upstream. + +There are 4 RDMA_CM events that all basically mean that +the user should teardown the IB connection: +- DISCONNECTED +- ADDR_CHANGE +- DEVICE_REMOVAL +- TIMEWAIT_EXIT + +Only in DISCONNECTED/ADDR_CHANGE it makes sense to +call rdma_disconnect (send DREQ/DREP to our initiator). +So we keep the same teardown handler for all of them +but only indicate calling rdma_disconnect for the relevant +events. + +This patch also removes redundant debug prints for each single +event. + +v2 changes: + - Call isert_disconnected_handler() for DEVICE_REMOVAL (Or + Sag) + +Signed-off-by: Sagi Grimberg +Signed-off-by: Nicholas Bellinger +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/infiniband/ulp/isert/ib_isert.c | 26 ++++++++++++++------------ + drivers/infiniband/ulp/isert/ib_isert.h | 1 + + 2 files changed, 15 insertions(+), 12 deletions(-) + +--- a/drivers/infiniband/ulp/isert/ib_isert.c ++++ b/drivers/infiniband/ulp/isert/ib_isert.c +@@ -788,8 +788,10 @@ isert_disconnect_work(struct work_struct + return; + } + +- /* Send DREQ/DREP towards our initiator */ +- rdma_disconnect(isert_conn->conn_cm_id); ++ if (isert_conn->disconnect) { ++ /* Send DREQ/DREP towards our initiator */ ++ rdma_disconnect(isert_conn->conn_cm_id); ++ } + + mutex_unlock(&isert_conn->conn_mutex); + +@@ -799,10 +801,11 @@ wake_up: + } + + static void +-isert_disconnected_handler(struct rdma_cm_id *cma_id) ++isert_disconnected_handler(struct rdma_cm_id *cma_id, bool disconnect) + { + struct isert_conn *isert_conn = (struct isert_conn *)cma_id->context; + ++ isert_conn->disconnect = disconnect; + INIT_WORK(&isert_conn->conn_logout_work, isert_disconnect_work); + schedule_work(&isert_conn->conn_logout_work); + } +@@ -811,29 +814,28 @@ static int + isert_cma_handler(struct rdma_cm_id *cma_id, struct rdma_cm_event *event) + { + int ret = 0; ++ bool disconnect = false; + + pr_debug("isert_cma_handler: event %d status %d conn %p id %p\n", + event->event, event->status, cma_id->context, cma_id); + + switch (event->event) { + case RDMA_CM_EVENT_CONNECT_REQUEST: +- pr_debug("RDMA_CM_EVENT_CONNECT_REQUEST: >>>>>>>>>>>>>>>\n"); + ret = isert_connect_request(cma_id, event); + break; + case RDMA_CM_EVENT_ESTABLISHED: +- pr_debug("RDMA_CM_EVENT_ESTABLISHED >>>>>>>>>>>>>>\n"); + isert_connected_handler(cma_id); + break; +- case RDMA_CM_EVENT_DISCONNECTED: +- pr_debug("RDMA_CM_EVENT_DISCONNECTED: >>>>>>>>>>>>>>\n"); +- isert_disconnected_handler(cma_id); +- break; +- case RDMA_CM_EVENT_DEVICE_REMOVAL: +- case RDMA_CM_EVENT_ADDR_CHANGE: ++ case RDMA_CM_EVENT_ADDR_CHANGE: /* FALLTHRU */ ++ case RDMA_CM_EVENT_DISCONNECTED: /* FALLTHRU */ ++ case RDMA_CM_EVENT_DEVICE_REMOVAL: /* FALLTHRU */ ++ disconnect = true; ++ case RDMA_CM_EVENT_TIMEWAIT_EXIT: /* FALLTHRU */ ++ isert_disconnected_handler(cma_id, disconnect); + break; + case RDMA_CM_EVENT_CONNECT_ERROR: + default: +- pr_err("Unknown RDMA CMA event: %d\n", event->event); ++ pr_err("Unhandled RDMA CMA event: %d\n", event->event); + break; + } + +--- a/drivers/infiniband/ulp/isert/ib_isert.h ++++ b/drivers/infiniband/ulp/isert/ib_isert.h +@@ -150,6 +150,7 @@ struct isert_conn { + #define ISERT_COMP_BATCH_COUNT 8 + int conn_comp_batch; + struct llist_head conn_comp_llist; ++ bool disconnect; + }; + + #define ISERT_MAX_CQ 64 diff --git a/queue-3.15/target-iser-wait-for-proper-cleanup-before-unloading.patch b/queue-3.15/target-iser-wait-for-proper-cleanup-before-unloading.patch new file mode 100644 index 00000000000..36e36bd40c5 --- /dev/null +++ b/queue-3.15/target-iser-wait-for-proper-cleanup-before-unloading.patch @@ -0,0 +1,31 @@ +From f5ebec9629cf78eeeea4b8258882a9f439ab2404 Mon Sep 17 00:00:00 2001 +From: Sagi Grimberg +Date: Mon, 19 May 2014 17:44:25 +0300 +Subject: Target/iser: Wait for proper cleanup before unloading + +From: Sagi Grimberg + +commit f5ebec9629cf78eeeea4b8258882a9f439ab2404 upstream. + +disconnected_handler works are scheduled on system_wq. +When attempting to unload, first make sure all works +have cleaned up. + +Signed-off-by: Sagi Grimberg +Signed-off-by: Nicholas Bellinger +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/infiniband/ulp/isert/ib_isert.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/drivers/infiniband/ulp/isert/ib_isert.c ++++ b/drivers/infiniband/ulp/isert/ib_isert.c +@@ -3289,6 +3289,7 @@ destroy_rx_wq: + + static void __exit isert_exit(void) + { ++ flush_scheduled_work(); + destroy_workqueue(isert_comp_wq); + destroy_workqueue(isert_rx_wq); + iscsit_unregister_transport(&iser_target_transport); diff --git a/queue-3.15/target-report-correct-response-length-for-some-commands.patch b/queue-3.15/target-report-correct-response-length-for-some-commands.patch new file mode 100644 index 00000000000..a4693a982e6 --- /dev/null +++ b/queue-3.15/target-report-correct-response-length-for-some-commands.patch @@ -0,0 +1,145 @@ +From 2426bd456a61407388b6e61fc5f98dbcbebc50e2 Mon Sep 17 00:00:00 2001 +From: Roland Dreier +Date: Tue, 10 Jun 2014 11:07:47 -0700 +Subject: target: Report correct response length for some commands + +From: Roland Dreier + +commit 2426bd456a61407388b6e61fc5f98dbcbebc50e2 upstream. + +When an initiator sends an allocation length bigger than what its +command consumes, the target should only return the actual response data +and set the residual length to the unused part of the allocation length. + +Add a helper function that command handlers (INQUIRY, READ CAPACITY, +etc) can use to do this correctly, and use this code to get the correct +residual for commands that don't use the full initiator allocation in the +handlers for READ CAPACITY, READ CAPACITY(16), INQUIRY, MODE SENSE and +REPORT LUNS. + +This addresses a handful of failures as reported by Christophe with +the Windows Certification Kit: + + http://permalink.gmane.org/gmane.linux.scsi.target.devel/6515 + +Signed-off-by: Roland Dreier +Tested-by: Christophe Vu-Brugier +Signed-off-by: Nicholas Bellinger +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/target/target_core_sbc.c | 4 ++-- + drivers/target/target_core_spc.c | 9 ++++++--- + drivers/target/target_core_transport.c | 17 +++++++++++++++++ + include/target/target_core_backend.h | 1 + + 4 files changed, 26 insertions(+), 5 deletions(-) + +--- a/drivers/target/target_core_sbc.c ++++ b/drivers/target/target_core_sbc.c +@@ -81,7 +81,7 @@ sbc_emulate_readcapacity(struct se_cmd * + transport_kunmap_data_sg(cmd); + } + +- target_complete_cmd(cmd, GOOD); ++ target_complete_cmd_with_length(cmd, GOOD, 8); + return 0; + } + +@@ -137,7 +137,7 @@ sbc_emulate_readcapacity_16(struct se_cm + transport_kunmap_data_sg(cmd); + } + +- target_complete_cmd(cmd, GOOD); ++ target_complete_cmd_with_length(cmd, GOOD, 32); + return 0; + } + +--- a/drivers/target/target_core_spc.c ++++ b/drivers/target/target_core_spc.c +@@ -721,6 +721,7 @@ spc_emulate_inquiry(struct se_cmd *cmd) + unsigned char *buf; + sense_reason_t ret; + int p; ++ int len = 0; + + buf = kzalloc(SE_INQUIRY_BUF, GFP_KERNEL); + if (!buf) { +@@ -742,6 +743,7 @@ spc_emulate_inquiry(struct se_cmd *cmd) + } + + ret = spc_emulate_inquiry_std(cmd, buf); ++ len = buf[4] + 5; + goto out; + } + +@@ -749,6 +751,7 @@ spc_emulate_inquiry(struct se_cmd *cmd) + if (cdb[2] == evpd_handlers[p].page) { + buf[1] = cdb[2]; + ret = evpd_handlers[p].emulate(cmd, buf); ++ len = get_unaligned_be16(&buf[2]) + 4; + goto out; + } + } +@@ -765,7 +768,7 @@ out: + kfree(buf); + + if (!ret) +- target_complete_cmd(cmd, GOOD); ++ target_complete_cmd_with_length(cmd, GOOD, len); + return ret; + } + +@@ -1103,7 +1106,7 @@ set_length: + transport_kunmap_data_sg(cmd); + } + +- target_complete_cmd(cmd, GOOD); ++ target_complete_cmd_with_length(cmd, GOOD, length); + return 0; + } + +@@ -1279,7 +1282,7 @@ done: + buf[3] = (lun_count & 0xff); + transport_kunmap_data_sg(cmd); + +- target_complete_cmd(cmd, GOOD); ++ target_complete_cmd_with_length(cmd, GOOD, 8 + lun_count * 8); + return 0; + } + EXPORT_SYMBOL(spc_emulate_report_luns); +--- a/drivers/target/target_core_transport.c ++++ b/drivers/target/target_core_transport.c +@@ -703,6 +703,23 @@ void target_complete_cmd(struct se_cmd * + } + EXPORT_SYMBOL(target_complete_cmd); + ++void target_complete_cmd_with_length(struct se_cmd *cmd, u8 scsi_status, int length) ++{ ++ if (scsi_status == SAM_STAT_GOOD && length < cmd->data_length) { ++ if (cmd->se_cmd_flags & SCF_UNDERFLOW_BIT) { ++ cmd->residual_count += cmd->data_length - length; ++ } else { ++ cmd->se_cmd_flags |= SCF_UNDERFLOW_BIT; ++ cmd->residual_count = cmd->data_length - length; ++ } ++ ++ cmd->data_length = length; ++ } ++ ++ target_complete_cmd(cmd, scsi_status); ++} ++EXPORT_SYMBOL(target_complete_cmd_with_length); ++ + static void target_add_to_state_list(struct se_cmd *cmd) + { + struct se_device *dev = cmd->se_dev; +--- a/include/target/target_core_backend.h ++++ b/include/target/target_core_backend.h +@@ -59,6 +59,7 @@ int transport_subsystem_register(struct + void transport_subsystem_release(struct se_subsystem_api *); + + void target_complete_cmd(struct se_cmd *, u8); ++void target_complete_cmd_with_length(struct se_cmd *, u8, int); + + sense_reason_t spc_parse_cdb(struct se_cmd *cmd, unsigned int *size); + sense_reason_t spc_emulate_report_luns(struct se_cmd *cmd); diff --git a/queue-3.15/target-sbc-loopback-adjust-command-data-length-in-case-pi-exists-on-the-wire.patch b/queue-3.15/target-sbc-loopback-adjust-command-data-length-in-case-pi-exists-on-the-wire.patch new file mode 100644 index 00000000000..ebfd46fb05e --- /dev/null +++ b/queue-3.15/target-sbc-loopback-adjust-command-data-length-in-case-pi-exists-on-the-wire.patch @@ -0,0 +1,87 @@ +From e2a4f55c6498b59a17a85a1bb6db122a993ffe02 Mon Sep 17 00:00:00 2001 +From: Sagi Grimberg +Date: Wed, 11 Jun 2014 12:09:59 +0300 +Subject: TARGET/sbc,loopback: Adjust command data length in case pi exists on the wire + +From: Sagi Grimberg + +commit e2a4f55c6498b59a17a85a1bb6db122a993ffe02 upstream. + +In various areas of the code, it is assumed that +se_cmd->data_length describes pure data. In case +that protection information exists over the wire +(protect bits is are on) the target core re-calculates +the data length from the CDB and the backed device +block size (instead of each transport peeking in the cdb). + +Modify loopback device to include protection information +in the transferred data length (like other scsi transports). + +Signed-off-by: Sagi Grimberg +Signed-off-by: Nicholas Bellinger +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/target/loopback/tcm_loop.c | 15 ++++++++++++--- + drivers/target/target_core_sbc.c | 15 +++++++++++++-- + 2 files changed, 25 insertions(+), 5 deletions(-) + +--- a/drivers/target/loopback/tcm_loop.c ++++ b/drivers/target/loopback/tcm_loop.c +@@ -179,7 +179,7 @@ static void tcm_loop_submission_work(str + struct tcm_loop_hba *tl_hba; + struct tcm_loop_tpg *tl_tpg; + struct scatterlist *sgl_bidi = NULL; +- u32 sgl_bidi_count = 0; ++ u32 sgl_bidi_count = 0, transfer_length; + int rc; + + tl_hba = *(struct tcm_loop_hba **)shost_priv(sc->device->host); +@@ -213,12 +213,21 @@ static void tcm_loop_submission_work(str + + } + +- if (!scsi_prot_sg_count(sc) && scsi_get_prot_op(sc) != SCSI_PROT_NORMAL) ++ transfer_length = scsi_transfer_length(sc); ++ if (!scsi_prot_sg_count(sc) && ++ scsi_get_prot_op(sc) != SCSI_PROT_NORMAL) { + se_cmd->prot_pto = true; ++ /* ++ * loopback transport doesn't support ++ * WRITE_GENERATE, READ_STRIP protection ++ * information operations, go ahead unprotected. ++ */ ++ transfer_length = scsi_bufflen(sc); ++ } + + 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), ++ transfer_length, tcm_loop_sam_attr(sc), + sc->sc_data_direction, 0, + scsi_sglist(sc), scsi_sg_count(sc), + sgl_bidi, sgl_bidi_count, +--- a/drivers/target/target_core_sbc.c ++++ b/drivers/target/target_core_sbc.c +@@ -665,8 +665,19 @@ sbc_check_prot(struct se_device *dev, st + + cmd->prot_type = dev->dev_attrib.pi_prot_type; + cmd->prot_length = dev->prot_length * sectors; +- pr_debug("%s: prot_type=%d, prot_length=%d prot_op=%d prot_checks=%d\n", +- __func__, cmd->prot_type, cmd->prot_length, ++ ++ /** ++ * In case protection information exists over the wire ++ * we modify command data length to describe pure data. ++ * The actual transfer length is data length + protection ++ * length ++ **/ ++ if (protect) ++ cmd->data_length = sectors * dev->dev_attrib.block_size; ++ ++ pr_debug("%s: prot_type=%d, data_length=%d, prot_length=%d " ++ "prot_op=%d prot_checks=%d\n", ++ __func__, cmd->prot_type, cmd->data_length, cmd->prot_length, + cmd->prot_op, cmd->prot_checks); + + return true; diff --git a/queue-3.15/target-set-cmd_t_active-bit-for-task-management-requests.patch b/queue-3.15/target-set-cmd_t_active-bit-for-task-management-requests.patch new file mode 100644 index 00000000000..e9be61b2392 --- /dev/null +++ b/queue-3.15/target-set-cmd_t_active-bit-for-task-management-requests.patch @@ -0,0 +1,42 @@ +From f15e9cd910c4d9da7de43f2181f362082fc45f0f Mon Sep 17 00:00:00 2001 +From: Nicholas Bellinger +Date: Mon, 9 Jun 2014 23:13:20 +0000 +Subject: target: Set CMD_T_ACTIVE bit for Task Management Requests + +From: Nicholas Bellinger + +commit f15e9cd910c4d9da7de43f2181f362082fc45f0f upstream. + +This patch fixes a bug where se_cmd descriptors associated with a +Task Management Request (TMR) where not setting CMD_T_ACTIVE before +being dispatched into target_tmr_work() process context. + +This is required in order for transport_generic_free_cmd() -> +transport_wait_for_tasks() to wait on se_cmd->t_transport_stop_comp +if a session reset event occurs while an ABORT_TASK is outstanding +waiting for another I/O to complete. + +Cc: Thomas Glanzmann +Cc: Charalampos Pournaris +Signed-off-by: Nicholas Bellinger +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/target/target_core_transport.c | 6 ++++++ + 1 file changed, 6 insertions(+) + +--- a/drivers/target/target_core_transport.c ++++ b/drivers/target/target_core_transport.c +@@ -2938,6 +2938,12 @@ static void target_tmr_work(struct work_ + int transport_generic_handle_tmr( + struct se_cmd *cmd) + { ++ unsigned long flags; ++ ++ spin_lock_irqsave(&cmd->t_state_lock, flags); ++ cmd->transport_state |= CMD_T_ACTIVE; ++ spin_unlock_irqrestore(&cmd->t_state_lock, flags); ++ + INIT_WORK(&cmd->work, target_tmr_work); + queue_work(cmd->se_dev->tmr_wq, &cmd->work); + return 0; diff --git a/queue-3.15/target-use-complete_all-for-se_cmd-t_transport_stop_comp.patch b/queue-3.15/target-use-complete_all-for-se_cmd-t_transport_stop_comp.patch new file mode 100644 index 00000000000..57be4307763 --- /dev/null +++ b/queue-3.15/target-use-complete_all-for-se_cmd-t_transport_stop_comp.patch @@ -0,0 +1,56 @@ +From a95d6511303b848da45ee27b35018bb58087bdc6 Mon Sep 17 00:00:00 2001 +From: Nicholas Bellinger +Date: Mon, 9 Jun 2014 23:36:51 +0000 +Subject: target: Use complete_all for se_cmd->t_transport_stop_comp + +From: Nicholas Bellinger + +commit a95d6511303b848da45ee27b35018bb58087bdc6 upstream. + +This patch fixes a bug where multiple waiters on ->t_transport_stop_comp +occurs due to a concurrent ABORT_TASK and session reset both invoking +transport_wait_for_tasks(), while waiting for the associated se_cmd +descriptor backend processing to complete. + +For this case, complete_all() should be invoked in order to wake up +both waiters in core_tmr_abort_task() + transport_generic_free_cmd() +process contexts. + +Cc: Thomas Glanzmann +Cc: Charalampos Pournaris +Signed-off-by: Nicholas Bellinger +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/target/target_core_transport.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +--- a/drivers/target/target_core_transport.c ++++ b/drivers/target/target_core_transport.c +@@ -562,7 +562,7 @@ static int transport_cmd_check_stop(stru + + spin_unlock_irqrestore(&cmd->t_state_lock, flags); + +- complete(&cmd->t_transport_stop_comp); ++ complete_all(&cmd->t_transport_stop_comp); + return 1; + } + +@@ -687,7 +687,7 @@ void target_complete_cmd(struct se_cmd * + if (cmd->transport_state & CMD_T_ABORTED && + cmd->transport_state & CMD_T_STOP) { + spin_unlock_irqrestore(&cmd->t_state_lock, flags); +- complete(&cmd->t_transport_stop_comp); ++ complete_all(&cmd->t_transport_stop_comp); + return; + } else if (!success) { + INIT_WORK(&cmd->work, target_complete_failure_work); +@@ -1761,7 +1761,7 @@ void target_execute_cmd(struct se_cmd *c + cmd->se_tfo->get_task_tag(cmd)); + + spin_unlock_irq(&cmd->t_state_lock); +- complete(&cmd->t_transport_stop_comp); ++ complete_all(&cmd->t_transport_stop_comp); + return; + } + -- 2.47.3