From: Greg Kroah-Hartman Date: Tue, 30 Jul 2013 00:24:54 +0000 (-0700) Subject: 3.10-stable patches X-Git-Tag: v3.0.89~23 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=98198e3b71ebf718059974e55107d518c9a29837;p=thirdparty%2Fkernel%2Fstable-queue.git 3.10-stable patches added patches: iscsi-target-fix-iscsi_op_scsi_tmfunc-handling-for-iser.patch iscsi-target-fix-tfc_tpg_nacl_auth_cit-configfs-length-overflow.patch iser-target-fix-isert_put_reject-payload-buffer-post.patch iser-target-fix-session-reset-bug-with-rdma_cm_event_disconnected.patch usb-storage-add-microvault-flash-drive-to-unusual_devs.patch --- diff --git a/queue-3.10/iscsi-target-fix-iscsi_op_scsi_tmfunc-handling-for-iser.patch b/queue-3.10/iscsi-target-fix-iscsi_op_scsi_tmfunc-handling-for-iser.patch new file mode 100644 index 00000000000..ab3da6e1075 --- /dev/null +++ b/queue-3.10/iscsi-target-fix-iscsi_op_scsi_tmfunc-handling-for-iser.patch @@ -0,0 +1,102 @@ +From 186a9647019587b3784694894c4d136fd00cfd7b Mon Sep 17 00:00:00 2001 +From: Nicholas Bellinger +Date: Wed, 3 Jul 2013 03:11:48 -0700 +Subject: iscsi-target: Fix ISCSI_OP_SCSI_TMFUNC handling for iser + +From: Nicholas Bellinger + +commit 186a9647019587b3784694894c4d136fd00cfd7b upstream. + +This patch adds target_get_sess_cmd reference counting for +iscsit_handle_task_mgt_cmd(), and adds a target_put_sess_cmd() +for the failure case. + +It also fixes a bug where ISCSI_OP_SCSI_TMFUNC type commands +where leaking iscsi_cmd->i_conn_node and eventually triggering +an OOPs during struct isert_conn shutdown. + +Signed-off-by: Nicholas Bellinger +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/infiniband/ulp/isert/ib_isert.c | 16 ++++++++-------- + drivers/target/iscsi/iscsi_target.c | 12 ++++++++++-- + 2 files changed, 18 insertions(+), 10 deletions(-) + +--- a/drivers/infiniband/ulp/isert/ib_isert.c ++++ b/drivers/infiniband/ulp/isert/ib_isert.c +@@ -1202,14 +1202,12 @@ isert_put_cmd(struct isert_cmd *isert_cm + { + struct iscsi_cmd *cmd = &isert_cmd->iscsi_cmd; + struct isert_conn *isert_conn = isert_cmd->conn; +- struct iscsi_conn *conn; ++ struct iscsi_conn *conn = isert_conn->conn; + + pr_debug("Entering isert_put_cmd: %p\n", isert_cmd); + + switch (cmd->iscsi_opcode) { + case ISCSI_OP_SCSI_CMD: +- conn = isert_conn->conn; +- + spin_lock_bh(&conn->cmd_lock); + if (!list_empty(&cmd->i_conn_node)) + list_del(&cmd->i_conn_node); +@@ -1219,16 +1217,18 @@ isert_put_cmd(struct isert_cmd *isert_cm + iscsit_stop_dataout_timer(cmd); + + isert_unmap_cmd(isert_cmd, isert_conn); +- /* +- * Fall-through +- */ ++ transport_generic_free_cmd(&cmd->se_cmd, 0); ++ break; + case ISCSI_OP_SCSI_TMFUNC: ++ spin_lock_bh(&conn->cmd_lock); ++ if (!list_empty(&cmd->i_conn_node)) ++ list_del(&cmd->i_conn_node); ++ spin_unlock_bh(&conn->cmd_lock); ++ + transport_generic_free_cmd(&cmd->se_cmd, 0); + break; + case ISCSI_OP_REJECT: + case ISCSI_OP_NOOP_OUT: +- conn = isert_conn->conn; +- + spin_lock_bh(&conn->cmd_lock); + if (!list_empty(&cmd->i_conn_node)) + list_del(&cmd->i_conn_node); +--- a/drivers/target/iscsi/iscsi_target.c ++++ b/drivers/target/iscsi/iscsi_target.c +@@ -1757,8 +1757,8 @@ iscsit_handle_task_mgt_cmd(struct iscsi_ + struct se_tmr_req *se_tmr; + struct iscsi_tmr_req *tmr_req; + struct iscsi_tm *hdr; +- int out_of_order_cmdsn = 0; +- int ret; ++ int out_of_order_cmdsn = 0, ret; ++ bool sess_ref = false; + u8 function; + + hdr = (struct iscsi_tm *) buf; +@@ -1814,6 +1814,9 @@ iscsit_handle_task_mgt_cmd(struct iscsi_ + conn->sess->se_sess, 0, DMA_NONE, + MSG_SIMPLE_TAG, cmd->sense_buffer + 2); + ++ target_get_sess_cmd(conn->sess->se_sess, &cmd->se_cmd, true); ++ sess_ref = true; ++ + switch (function) { + case ISCSI_TM_FUNC_ABORT_TASK: + tcm_function = TMR_ABORT_TASK; +@@ -1956,6 +1959,11 @@ attach: + * For connection recovery, this is also the default action for + * TMR TASK_REASSIGN. + */ ++ if (sess_ref) { ++ pr_debug("Handle TMR, using sess_ref=true check\n"); ++ target_put_sess_cmd(conn->sess->se_sess, &cmd->se_cmd); ++ } ++ + iscsit_add_cmd_to_response_queue(cmd, conn, cmd->i_state); + return 0; + } diff --git a/queue-3.10/iscsi-target-fix-tfc_tpg_nacl_auth_cit-configfs-length-overflow.patch b/queue-3.10/iscsi-target-fix-tfc_tpg_nacl_auth_cit-configfs-length-overflow.patch new file mode 100644 index 00000000000..49e22a7193d --- /dev/null +++ b/queue-3.10/iscsi-target-fix-tfc_tpg_nacl_auth_cit-configfs-length-overflow.patch @@ -0,0 +1,32 @@ +From 0fbfc46fb0b2f543a8b539e94c6c293ebc0b05a6 Mon Sep 17 00:00:00 2001 +From: Joern Engel +Date: Wed, 3 Jul 2013 11:35:11 -0400 +Subject: iscsi-target: Fix tfc_tpg_nacl_auth_cit configfs length overflow + +From: Joern Engel + +commit 0fbfc46fb0b2f543a8b539e94c6c293ebc0b05a6 upstream. + +This patch fixes a potential buffer overflow while processing +iscsi_node_auth input for configfs attributes within NodeACL +tfc_tpg_nacl_auth_cit context. + +Signed-off-by: Joern Engel +Signed-off-by: Nicholas Bellinger +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/target/iscsi/iscsi_target_configfs.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/target/iscsi/iscsi_target_configfs.c ++++ b/drivers/target/iscsi/iscsi_target_configfs.c +@@ -474,7 +474,7 @@ static ssize_t __iscsi_##prefix##_store_ + if (!capable(CAP_SYS_ADMIN)) \ + return -EPERM; \ + \ +- snprintf(auth->name, PAGE_SIZE, "%s", page); \ ++ snprintf(auth->name, sizeof(auth->name), "%s", page); \ + if (!strncmp("NULL", auth->name, 4)) \ + auth->naf_flags &= ~flags; \ + else \ diff --git a/queue-3.10/iser-target-fix-isert_put_reject-payload-buffer-post.patch b/queue-3.10/iser-target-fix-isert_put_reject-payload-buffer-post.patch new file mode 100644 index 00000000000..f379ef515dd --- /dev/null +++ b/queue-3.10/iser-target-fix-isert_put_reject-payload-buffer-post.patch @@ -0,0 +1,86 @@ +From 3df8f68aaf7ebe3d136a22262b41b350b0a1858b Mon Sep 17 00:00:00 2001 +From: Nicholas Bellinger +Date: Wed, 26 Jun 2013 02:31:42 -0700 +Subject: iser-target: Fix isert_put_reject payload buffer post + +From: Nicholas Bellinger + +commit 3df8f68aaf7ebe3d136a22262b41b350b0a1858b upstream. + +This patch adds the missing isert_put_reject() logic to post +a outgoing payload buffer to hold the 48 bytes of original PDU +header request payload for the rejected cmd. + +It also fixes ISTATE_SEND_REJECT handling in isert_response_completion() +-> isert_do_control_comp() code, and drops incorrect iscsi_cmd_t->reject_comp +usage. + +Signed-off-by: Nicholas Bellinger +Cc: Or Gerlitz +Cc: Mike Christie +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/infiniband/ulp/isert/ib_isert.c | 26 ++++++++++++++++++++++---- + 1 file changed, 22 insertions(+), 4 deletions(-) + +--- a/drivers/infiniband/ulp/isert/ib_isert.c ++++ b/drivers/infiniband/ulp/isert/ib_isert.c +@@ -1222,6 +1222,9 @@ isert_put_cmd(struct isert_cmd *isert_cm + * associated cmd->se_cmd needs to be released. + */ + if (cmd->se_cmd.se_tfo != NULL) { ++ pr_debug("Calling transport_generic_free_cmd from" ++ " isert_put_cmd for 0x%02x\n", ++ cmd->iscsi_opcode); + transport_generic_free_cmd(&cmd->se_cmd, 0); + break; + } +@@ -1318,8 +1321,8 @@ isert_do_control_comp(struct work_struct + atomic_dec(&isert_conn->post_send_buf_count); + + cmd->i_state = ISTATE_SENT_STATUS; +- complete(&cmd->reject_comp); + isert_completion_put(&isert_cmd->tx_desc, isert_cmd, ib_dev); ++ break; + case ISTATE_SEND_LOGOUTRSP: + pr_debug("Calling iscsit_logout_post_handler >>>>>>>>>>>>>>\n"); + /* +@@ -1345,7 +1348,8 @@ isert_response_completion(struct iser_tx + struct iscsi_cmd *cmd = &isert_cmd->iscsi_cmd; + + if (cmd->i_state == ISTATE_SEND_TASKMGTRSP || +- cmd->i_state == ISTATE_SEND_LOGOUTRSP) { ++ cmd->i_state == ISTATE_SEND_LOGOUTRSP || ++ cmd->i_state == ISTATE_SEND_REJECT) { + isert_unmap_tx_desc(tx_desc, ib_dev); + + INIT_WORK(&isert_cmd->comp_work, isert_do_control_comp); +@@ -1637,11 +1641,25 @@ isert_put_reject(struct iscsi_cmd *cmd, + struct isert_cmd, iscsi_cmd); + struct isert_conn *isert_conn = (struct isert_conn *)conn->context; + struct ib_send_wr *send_wr = &isert_cmd->tx_desc.send_wr; ++ struct ib_device *ib_dev = isert_conn->conn_cm_id->device; ++ struct ib_sge *tx_dsg = &isert_cmd->tx_desc.tx_sg[1]; ++ struct iscsi_reject *hdr = ++ (struct iscsi_reject *)&isert_cmd->tx_desc.iscsi_header; + + isert_create_send_desc(isert_conn, isert_cmd, &isert_cmd->tx_desc); +- iscsit_build_reject(cmd, conn, (struct iscsi_reject *) +- &isert_cmd->tx_desc.iscsi_header); ++ iscsit_build_reject(cmd, conn, hdr); + isert_init_tx_hdrs(isert_conn, &isert_cmd->tx_desc); ++ ++ hton24(hdr->dlength, ISCSI_HDR_LEN); ++ isert_cmd->sense_buf_dma = ib_dma_map_single(ib_dev, ++ (void *)cmd->buf_ptr, ISCSI_HDR_LEN, ++ DMA_TO_DEVICE); ++ isert_cmd->sense_buf_len = ISCSI_HDR_LEN; ++ tx_dsg->addr = isert_cmd->sense_buf_dma; ++ tx_dsg->length = ISCSI_HDR_LEN; ++ tx_dsg->lkey = isert_conn->conn_mr->lkey; ++ isert_cmd->tx_desc.num_sge = 2; ++ + isert_init_send_wr(isert_cmd, send_wr); + + pr_debug("Posting Reject IB_WR_SEND >>>>>>>>>>>>>>>>>>>>>>\n"); diff --git a/queue-3.10/iser-target-fix-session-reset-bug-with-rdma_cm_event_disconnected.patch b/queue-3.10/iser-target-fix-session-reset-bug-with-rdma_cm_event_disconnected.patch new file mode 100644 index 00000000000..d0857fd988c --- /dev/null +++ b/queue-3.10/iser-target-fix-session-reset-bug-with-rdma_cm_event_disconnected.patch @@ -0,0 +1,195 @@ +From b2cb96494d83b894a43ba8b9023eead8ff50684b Mon Sep 17 00:00:00 2001 +From: Nicholas Bellinger +Date: Wed, 3 Jul 2013 03:05:37 -0700 +Subject: iser-target: Fix session reset bug with RDMA_CM_EVENT_DISCONNECTED + +From: Nicholas Bellinger + +commit b2cb96494d83b894a43ba8b9023eead8ff50684b upstream. + +This patch addresses a bug where RDMA_CM_EVENT_DISCONNECTED may occur +before the connection shutdown has been completed by rx/tx threads, +that causes isert_free_conn() to wait indefinately on ->conn_wait. + +This patch allows isert_disconnect_work code to invoke rdma_disconnect +when isert_disconnect_work() process context is started by client +session reset before isert_free_conn() code has been reached. + +It also adds isert_conn->conn_mutex protection for ->state within +isert_disconnect_work(), isert_cq_comp_err() and isert_free_conn() +code, along with isert_check_state() for wait_event usage. + +(v2: Add explicit iscsit_cause_connection_reinstatement call + during isert_disconnect_work() to force conn reset) + +Cc: Or Gerlitz +Signed-off-by: Nicholas Bellinger +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/infiniband/ulp/isert/ib_isert.c | 70 ++++++++++++++++++++++++++----- + drivers/infiniband/ulp/isert/ib_isert.h | 1 + drivers/target/iscsi/iscsi_target_erl0.c | 1 + include/target/iscsi/iscsi_transport.h | 4 + + 4 files changed, 66 insertions(+), 10 deletions(-) + +--- a/drivers/infiniband/ulp/isert/ib_isert.c ++++ b/drivers/infiniband/ulp/isert/ib_isert.c +@@ -388,6 +388,7 @@ isert_connect_request(struct rdma_cm_id + init_waitqueue_head(&isert_conn->conn_wait_comp_err); + kref_init(&isert_conn->conn_kref); + kref_get(&isert_conn->conn_kref); ++ mutex_init(&isert_conn->conn_mutex); + + cma_id->context = isert_conn; + isert_conn->conn_cm_id = cma_id; +@@ -540,15 +541,32 @@ isert_disconnect_work(struct work_struct + struct isert_conn, conn_logout_work); + + pr_debug("isert_disconnect_work(): >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>\n"); +- ++ mutex_lock(&isert_conn->conn_mutex); + isert_conn->state = ISER_CONN_DOWN; + + if (isert_conn->post_recv_buf_count == 0 && + atomic_read(&isert_conn->post_send_buf_count) == 0) { + pr_debug("Calling wake_up(&isert_conn->conn_wait);\n"); +- wake_up(&isert_conn->conn_wait); ++ mutex_unlock(&isert_conn->conn_mutex); ++ goto wake_up; ++ } ++ if (!isert_conn->conn_cm_id) { ++ mutex_unlock(&isert_conn->conn_mutex); ++ isert_put_conn(isert_conn); ++ return; ++ } ++ if (!isert_conn->logout_posted) { ++ pr_debug("Calling rdma_disconnect for !logout_posted from" ++ " isert_disconnect_work\n"); ++ rdma_disconnect(isert_conn->conn_cm_id); ++ mutex_unlock(&isert_conn->conn_mutex); ++ iscsit_cause_connection_reinstatement(isert_conn->conn, 0); ++ goto wake_up; + } ++ mutex_unlock(&isert_conn->conn_mutex); + ++wake_up: ++ wake_up(&isert_conn->conn_wait); + isert_put_conn(isert_conn); + } + +@@ -1423,7 +1441,11 @@ isert_cq_comp_err(struct iser_tx_desc *t + pr_debug("isert_cq_comp_err >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>\n"); + pr_debug("Calling wake_up from isert_cq_comp_err\n"); + +- isert_conn->state = ISER_CONN_TERMINATING; ++ mutex_lock(&isert_conn->conn_mutex); ++ if (isert_conn->state != ISER_CONN_DOWN) ++ isert_conn->state = ISER_CONN_TERMINATING; ++ mutex_unlock(&isert_conn->conn_mutex); ++ + wake_up(&isert_conn->conn_wait_comp_err); + } + } +@@ -2193,6 +2215,17 @@ isert_free_np(struct iscsi_np *np) + kfree(isert_np); + } + ++static int isert_check_state(struct isert_conn *isert_conn, int state) ++{ ++ int ret; ++ ++ mutex_lock(&isert_conn->conn_mutex); ++ ret = (isert_conn->state == state); ++ mutex_unlock(&isert_conn->conn_mutex); ++ ++ return ret; ++} ++ + static void isert_free_conn(struct iscsi_conn *conn) + { + struct isert_conn *isert_conn = conn->context; +@@ -2202,26 +2235,43 @@ static void isert_free_conn(struct iscsi + * Decrement post_send_buf_count for special case when called + * from isert_do_control_comp() -> iscsit_logout_post_handler() + */ ++ mutex_lock(&isert_conn->conn_mutex); + if (isert_conn->logout_posted) + atomic_dec(&isert_conn->post_send_buf_count); + +- if (isert_conn->conn_cm_id) ++ if (isert_conn->conn_cm_id && isert_conn->state != ISER_CONN_DOWN) { ++ pr_debug("Calling rdma_disconnect from isert_free_conn\n"); + rdma_disconnect(isert_conn->conn_cm_id); ++ } + /* + * Only wait for conn_wait_comp_err if the isert_conn made it + * into full feature phase.. + */ +- if (isert_conn->state > ISER_CONN_INIT) { ++ if (isert_conn->state == ISER_CONN_UP) { + pr_debug("isert_free_conn: Before wait_event comp_err %d\n", + isert_conn->state); ++ mutex_unlock(&isert_conn->conn_mutex); ++ + wait_event(isert_conn->conn_wait_comp_err, +- isert_conn->state == ISER_CONN_TERMINATING); +- pr_debug("isert_free_conn: After wait_event #1 >>>>>>>>>>>>\n"); ++ (isert_check_state(isert_conn, ISER_CONN_TERMINATING))); ++ ++ wait_event(isert_conn->conn_wait, ++ (isert_check_state(isert_conn, ISER_CONN_DOWN))); ++ ++ isert_put_conn(isert_conn); ++ return; ++ } ++ if (isert_conn->state == ISER_CONN_INIT) { ++ mutex_unlock(&isert_conn->conn_mutex); ++ isert_put_conn(isert_conn); ++ return; + } ++ pr_debug("isert_free_conn: wait_event conn_wait %d\n", ++ isert_conn->state); ++ mutex_unlock(&isert_conn->conn_mutex); + +- pr_debug("isert_free_conn: wait_event conn_wait %d\n", isert_conn->state); +- wait_event(isert_conn->conn_wait, isert_conn->state == ISER_CONN_DOWN); +- pr_debug("isert_free_conn: After wait_event #2 >>>>>>>>>>>>>>>>>>>>\n"); ++ wait_event(isert_conn->conn_wait, ++ (isert_check_state(isert_conn, ISER_CONN_DOWN))); + + isert_put_conn(isert_conn); + } +--- a/drivers/infiniband/ulp/isert/ib_isert.h ++++ b/drivers/infiniband/ulp/isert/ib_isert.h +@@ -102,6 +102,7 @@ struct isert_conn { + struct ib_qp *conn_qp; + struct isert_device *conn_device; + struct work_struct conn_logout_work; ++ struct mutex conn_mutex; + wait_queue_head_t conn_wait; + wait_queue_head_t conn_wait_comp_err; + struct kref conn_kref; +--- a/drivers/target/iscsi/iscsi_target_erl0.c ++++ b/drivers/target/iscsi/iscsi_target_erl0.c +@@ -909,6 +909,7 @@ void iscsit_cause_connection_reinstateme + wait_for_completion(&conn->conn_wait_comp); + complete(&conn->conn_post_wait_comp); + } ++EXPORT_SYMBOL(iscsit_cause_connection_reinstatement); + + void iscsit_fall_back_to_erl0(struct iscsi_session *sess) + { +--- a/include/target/iscsi/iscsi_transport.h ++++ b/include/target/iscsi/iscsi_transport.h +@@ -67,6 +67,10 @@ extern int iscsit_logout_post_handler(st + */ + extern void iscsit_increment_maxcmdsn(struct iscsi_cmd *, struct iscsi_session *); + /* ++ * From iscsi_target_erl0.c ++ */ ++extern void iscsit_cause_connection_reinstatement(struct iscsi_conn *, int); ++/* + * From iscsi_target_erl1.c + */ + extern void iscsit_stop_dataout_timer(struct iscsi_cmd *); diff --git a/queue-3.10/series b/queue-3.10/series index 8fd21d26bdb..9054f82f401 100644 --- a/queue-3.10/series +++ b/queue-3.10/series @@ -1 +1,6 @@ mm-fix-the-tlb-range-flushed-when-__tlb_remove_page-runs-out-of-slots.patch +iser-target-fix-isert_put_reject-payload-buffer-post.patch +iscsi-target-fix-tfc_tpg_nacl_auth_cit-configfs-length-overflow.patch +iser-target-fix-session-reset-bug-with-rdma_cm_event_disconnected.patch +iscsi-target-fix-iscsi_op_scsi_tmfunc-handling-for-iser.patch +usb-storage-add-microvault-flash-drive-to-unusual_devs.patch diff --git a/queue-3.10/usb-storage-add-microvault-flash-drive-to-unusual_devs.patch b/queue-3.10/usb-storage-add-microvault-flash-drive-to-unusual_devs.patch new file mode 100644 index 00000000000..0585e93f64a --- /dev/null +++ b/queue-3.10/usb-storage-add-microvault-flash-drive-to-unusual_devs.patch @@ -0,0 +1,37 @@ +From e7a6121f4929c17215f0cdca3726f4bf3e4e9529 Mon Sep 17 00:00:00 2001 +From: Ren Bigcren +Date: Tue, 2 Jul 2013 13:34:30 +0200 +Subject: USB: storage: Add MicroVault Flash Drive to unusual_devs + +From: Ren Bigcren + +commit e7a6121f4929c17215f0cdca3726f4bf3e4e9529 upstream. + +The device report an error capacity when read_capacity_16(). +Using read_capacity_10() can get the correct capacity. + +Signed-off-by: Ren Bigcren +Cc: Matthew Dharm +Signed-off-by: Oskar Andero +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/storage/unusual_devs.h | 7 +++++++ + 1 file changed, 7 insertions(+) + +--- a/drivers/usb/storage/unusual_devs.h ++++ b/drivers/usb/storage/unusual_devs.h +@@ -665,6 +665,13 @@ UNUSUAL_DEV( 0x054c, 0x016a, 0x0000, 0x + USB_SC_DEVICE, USB_PR_DEVICE, NULL, + US_FL_FIX_INQUIRY ), + ++/* Submitted by Ren Bigcren */ ++UNUSUAL_DEV( 0x054c, 0x02a5, 0x0100, 0x0100, ++ "Sony Corp.", ++ "MicroVault Flash Drive", ++ USB_SC_DEVICE, USB_PR_DEVICE, NULL, ++ US_FL_NO_READ_CAPACITY_16 ), ++ + /* floppy reports multiple luns */ + UNUSUAL_DEV( 0x055d, 0x2020, 0x0000, 0x0210, + "SAMSUNG",