diff options
Diffstat (limited to 'drivers/target/iscsi/iscsi_target_util.c')
| -rw-r--r-- | drivers/target/iscsi/iscsi_target_util.c | 385 |
1 files changed, 170 insertions, 215 deletions
diff --git a/drivers/target/iscsi/iscsi_target_util.c b/drivers/target/iscsi/iscsi_target_util.c index 86987da86dd6..5e6cf34929b5 100644 --- a/drivers/target/iscsi/iscsi_target_util.c +++ b/drivers/target/iscsi/iscsi_target_util.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0-or-later /******************************************************************************* * This file contains the iSCSI Target specific utility functions. * @@ -5,15 +6,6 @@ * * Author: Nicholas A. Bellinger <nab@linux-iscsi.org> * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. ******************************************************************************/ #include <linux/list.h> @@ -36,31 +28,11 @@ #include "iscsi_target_util.h" #include "iscsi_target.h" -#define PRINT_BUFF(buff, len) \ -{ \ - int zzz; \ - \ - pr_debug("%d:\n", __LINE__); \ - for (zzz = 0; zzz < len; zzz++) { \ - if (zzz % 16 == 0) { \ - if (zzz) \ - pr_debug("\n"); \ - pr_debug("%4i: ", zzz); \ - } \ - pr_debug("%02x ", (unsigned char) (buff)[zzz]); \ - } \ - if ((len + 1) % 16) \ - pr_debug("\n"); \ -} - extern struct list_head g_tiqn_list; extern spinlock_t tiqn_lock; -/* - * Called with cmd->r2t_lock held. - */ int iscsit_add_r2t_to_list( - struct iscsi_cmd *cmd, + struct iscsit_cmd *cmd, u32 offset, u32 xfer_len, int recovery, @@ -68,6 +40,10 @@ int iscsit_add_r2t_to_list( { struct iscsi_r2t *r2t; + lockdep_assert_held(&cmd->r2t_lock); + + WARN_ON_ONCE((s32)xfer_len < 0); + r2t = kmem_cache_zalloc(lio_r2t_cache, GFP_ATOMIC); if (!r2t) { pr_err("Unable to allocate memory for struct iscsi_r2t.\n"); @@ -89,7 +65,7 @@ int iscsit_add_r2t_to_list( } struct iscsi_r2t *iscsit_get_r2t_for_eos( - struct iscsi_cmd *cmd, + struct iscsit_cmd *cmd, u32 offset, u32 length) { @@ -110,7 +86,7 @@ struct iscsi_r2t *iscsit_get_r2t_for_eos( return NULL; } -struct iscsi_r2t *iscsit_get_r2t_from_list(struct iscsi_cmd *cmd) +struct iscsi_r2t *iscsit_get_r2t_from_list(struct iscsit_cmd *cmd) { struct iscsi_r2t *r2t; @@ -128,16 +104,15 @@ struct iscsi_r2t *iscsit_get_r2t_from_list(struct iscsi_cmd *cmd) return NULL; } -/* - * Called with cmd->r2t_lock held. - */ -void iscsit_free_r2t(struct iscsi_r2t *r2t, struct iscsi_cmd *cmd) +void iscsit_free_r2t(struct iscsi_r2t *r2t, struct iscsit_cmd *cmd) { + lockdep_assert_held(&cmd->r2t_lock); + list_del(&r2t->r2t_list); kmem_cache_free(lio_r2t_cache, r2t); } -void iscsit_free_r2ts_from_list(struct iscsi_cmd *cmd) +void iscsit_free_r2ts_from_list(struct iscsit_cmd *cmd) { struct iscsi_r2t *r2t, *r2t_tmp; @@ -177,9 +152,9 @@ static int iscsit_wait_for_tag(struct se_session *se_sess, int state, int *cpup) * May be called from software interrupt (timer) context for allocating * iSCSI NopINs. */ -struct iscsi_cmd *iscsit_allocate_cmd(struct iscsi_conn *conn, int state) +struct iscsit_cmd *iscsit_allocate_cmd(struct iscsit_conn *conn, int state) { - struct iscsi_cmd *cmd; + struct iscsit_cmd *cmd; struct se_session *se_sess = conn->sess->se_sess; int size, tag, cpu; @@ -189,8 +164,8 @@ struct iscsi_cmd *iscsit_allocate_cmd(struct iscsi_conn *conn, int state) if (tag < 0) return NULL; - size = sizeof(struct iscsi_cmd) + conn->conn_transport->priv_size; - cmd = (struct iscsi_cmd *)(se_sess->sess_cmd_map + (tag * size)); + size = sizeof(struct iscsit_cmd) + conn->conn_transport->priv_size; + cmd = (struct iscsit_cmd *)(se_sess->sess_cmd_map + (tag * size)); memset(cmd, 0, size); cmd->se_cmd.map_tag = tag; @@ -212,7 +187,7 @@ struct iscsi_cmd *iscsit_allocate_cmd(struct iscsi_conn *conn, int state) EXPORT_SYMBOL(iscsit_allocate_cmd); struct iscsi_seq *iscsit_get_seq_holder_for_datain( - struct iscsi_cmd *cmd, + struct iscsit_cmd *cmd, u32 seq_send_order) { u32 i; @@ -224,12 +199,12 @@ struct iscsi_seq *iscsit_get_seq_holder_for_datain( return NULL; } -struct iscsi_seq *iscsit_get_seq_holder_for_r2t(struct iscsi_cmd *cmd) +struct iscsi_seq *iscsit_get_seq_holder_for_r2t(struct iscsit_cmd *cmd) { u32 i; if (!cmd->seq_list) { - pr_err("struct iscsi_cmd->seq_list is NULL!\n"); + pr_err("struct iscsit_cmd->seq_list is NULL!\n"); return NULL; } @@ -246,7 +221,7 @@ struct iscsi_seq *iscsit_get_seq_holder_for_r2t(struct iscsi_cmd *cmd) } struct iscsi_r2t *iscsit_get_holder_for_r2tsn( - struct iscsi_cmd *cmd, + struct iscsit_cmd *cmd, u32 r2t_sn) { struct iscsi_r2t *r2t; @@ -263,7 +238,7 @@ struct iscsi_r2t *iscsit_get_holder_for_r2tsn( return NULL; } -static inline int iscsit_check_received_cmdsn(struct iscsi_session *sess, u32 cmdsn) +static inline int iscsit_check_received_cmdsn(struct iscsit_session *sess, u32 cmdsn) { u32 max_cmdsn; int ret; @@ -307,7 +282,7 @@ static inline int iscsit_check_received_cmdsn(struct iscsi_session *sess, u32 cm * Commands may be received out of order if MC/S is in use. * Ensure they are executed in CmdSN order. */ -int iscsit_sequence_cmd(struct iscsi_conn *conn, struct iscsi_cmd *cmd, +int iscsit_sequence_cmd(struct iscsit_conn *conn, struct iscsit_cmd *cmd, unsigned char *buf, __be32 cmdsn) { int ret, cmdsn_ret; @@ -358,55 +333,11 @@ int iscsit_sequence_cmd(struct iscsi_conn *conn, struct iscsi_cmd *cmd, } EXPORT_SYMBOL(iscsit_sequence_cmd); -int iscsit_check_unsolicited_dataout(struct iscsi_cmd *cmd, unsigned char *buf) -{ - struct iscsi_conn *conn = cmd->conn; - struct se_cmd *se_cmd = &cmd->se_cmd; - struct iscsi_data *hdr = (struct iscsi_data *) buf; - u32 payload_length = ntoh24(hdr->dlength); - - if (conn->sess->sess_ops->InitialR2T) { - pr_err("Received unexpected unsolicited data" - " while InitialR2T=Yes, protocol error.\n"); - transport_send_check_condition_and_sense(se_cmd, - TCM_UNEXPECTED_UNSOLICITED_DATA, 0); - return -1; - } - - if ((cmd->first_burst_len + payload_length) > - conn->sess->sess_ops->FirstBurstLength) { - pr_err("Total %u bytes exceeds FirstBurstLength: %u" - " for this Unsolicited DataOut Burst.\n", - (cmd->first_burst_len + payload_length), - conn->sess->sess_ops->FirstBurstLength); - transport_send_check_condition_and_sense(se_cmd, - TCM_INCORRECT_AMOUNT_OF_DATA, 0); - return -1; - } - - if (!(hdr->flags & ISCSI_FLAG_CMD_FINAL)) - return 0; - - if (((cmd->first_burst_len + payload_length) != cmd->se_cmd.data_length) && - ((cmd->first_burst_len + payload_length) != - conn->sess->sess_ops->FirstBurstLength)) { - pr_err("Unsolicited non-immediate data received %u" - " does not equal FirstBurstLength: %u, and does" - " not equal ExpXferLen %u.\n", - (cmd->first_burst_len + payload_length), - conn->sess->sess_ops->FirstBurstLength, cmd->se_cmd.data_length); - transport_send_check_condition_and_sense(se_cmd, - TCM_INCORRECT_AMOUNT_OF_DATA, 0); - return -1; - } - return 0; -} - -struct iscsi_cmd *iscsit_find_cmd_from_itt( - struct iscsi_conn *conn, +struct iscsit_cmd *iscsit_find_cmd_from_itt( + struct iscsit_conn *conn, itt_t init_task_tag) { - struct iscsi_cmd *cmd; + struct iscsit_cmd *cmd; spin_lock_bh(&conn->cmd_lock); list_for_each_entry(cmd, &conn->conn_cmd_list, i_conn_node) { @@ -423,12 +354,12 @@ struct iscsi_cmd *iscsit_find_cmd_from_itt( } EXPORT_SYMBOL(iscsit_find_cmd_from_itt); -struct iscsi_cmd *iscsit_find_cmd_from_itt_or_dump( - struct iscsi_conn *conn, +struct iscsit_cmd *iscsit_find_cmd_from_itt_or_dump( + struct iscsit_conn *conn, itt_t init_task_tag, u32 length) { - struct iscsi_cmd *cmd; + struct iscsit_cmd *cmd; spin_lock_bh(&conn->cmd_lock); list_for_each_entry(cmd, &conn->conn_cmd_list, i_conn_node) { @@ -450,11 +381,11 @@ struct iscsi_cmd *iscsit_find_cmd_from_itt_or_dump( } EXPORT_SYMBOL(iscsit_find_cmd_from_itt_or_dump); -struct iscsi_cmd *iscsit_find_cmd_from_ttt( - struct iscsi_conn *conn, +struct iscsit_cmd *iscsit_find_cmd_from_ttt( + struct iscsit_conn *conn, u32 targ_xfer_tag) { - struct iscsi_cmd *cmd = NULL; + struct iscsit_cmd *cmd = NULL; spin_lock_bh(&conn->cmd_lock); list_for_each_entry(cmd, &conn->conn_cmd_list, i_conn_node) { @@ -471,12 +402,12 @@ struct iscsi_cmd *iscsit_find_cmd_from_ttt( } int iscsit_find_cmd_for_recovery( - struct iscsi_session *sess, - struct iscsi_cmd **cmd_ptr, + struct iscsit_session *sess, + struct iscsit_cmd **cmd_ptr, struct iscsi_conn_recovery **cr_ptr, itt_t init_task_tag) { - struct iscsi_cmd *cmd = NULL; + struct iscsit_cmd *cmd = NULL; struct iscsi_conn_recovery *cr; /* * Scan through the inactive connection recovery list's command list. @@ -523,8 +454,8 @@ int iscsit_find_cmd_for_recovery( } void iscsit_add_cmd_to_immediate_queue( - struct iscsi_cmd *cmd, - struct iscsi_conn *conn, + struct iscsit_cmd *cmd, + struct iscsit_conn *conn, u8 state) { struct iscsi_queue_req *qr; @@ -549,7 +480,7 @@ void iscsit_add_cmd_to_immediate_queue( } EXPORT_SYMBOL(iscsit_add_cmd_to_immediate_queue); -struct iscsi_queue_req *iscsit_get_cmd_from_immediate_queue(struct iscsi_conn *conn) +struct iscsi_queue_req *iscsit_get_cmd_from_immediate_queue(struct iscsit_conn *conn) { struct iscsi_queue_req *qr; @@ -570,8 +501,8 @@ struct iscsi_queue_req *iscsit_get_cmd_from_immediate_queue(struct iscsi_conn *c } static void iscsit_remove_cmd_from_immediate_queue( - struct iscsi_cmd *cmd, - struct iscsi_conn *conn) + struct iscsit_cmd *cmd, + struct iscsit_conn *conn) { struct iscsi_queue_req *qr, *qr_tmp; @@ -599,8 +530,8 @@ static void iscsit_remove_cmd_from_immediate_queue( } int iscsit_add_cmd_to_response_queue( - struct iscsi_cmd *cmd, - struct iscsi_conn *conn, + struct iscsit_cmd *cmd, + struct iscsit_conn *conn, u8 state) { struct iscsi_queue_req *qr; @@ -624,7 +555,7 @@ int iscsit_add_cmd_to_response_queue( return 0; } -struct iscsi_queue_req *iscsit_get_cmd_from_response_queue(struct iscsi_conn *conn) +struct iscsi_queue_req *iscsit_get_cmd_from_response_queue(struct iscsit_conn *conn) { struct iscsi_queue_req *qr; @@ -646,8 +577,8 @@ struct iscsi_queue_req *iscsit_get_cmd_from_response_queue(struct iscsi_conn *co } static void iscsit_remove_cmd_from_response_queue( - struct iscsi_cmd *cmd, - struct iscsi_conn *conn) + struct iscsit_cmd *cmd, + struct iscsit_conn *conn) { struct iscsi_queue_req *qr, *qr_tmp; @@ -675,7 +606,7 @@ static void iscsit_remove_cmd_from_response_queue( } } -bool iscsit_conn_all_queues_empty(struct iscsi_conn *conn) +bool iscsit_conn_all_queues_empty(struct iscsit_conn *conn) { bool empty; @@ -693,7 +624,7 @@ bool iscsit_conn_all_queues_empty(struct iscsi_conn *conn) return empty; } -void iscsit_free_queue_reqs_for_conn(struct iscsi_conn *conn) +void iscsit_free_queue_reqs_for_conn(struct iscsit_conn *conn) { struct iscsi_queue_req *qr, *qr_tmp; @@ -719,9 +650,9 @@ void iscsit_free_queue_reqs_for_conn(struct iscsi_conn *conn) spin_unlock_bh(&conn->response_queue_lock); } -void iscsit_release_cmd(struct iscsi_cmd *cmd) +void iscsit_release_cmd(struct iscsit_cmd *cmd) { - struct iscsi_session *sess; + struct iscsit_session *sess; struct se_cmd *se_cmd = &cmd->se_cmd; WARN_ON(!list_empty(&cmd->i_conn_node)); @@ -737,6 +668,7 @@ void iscsit_release_cmd(struct iscsi_cmd *cmd) kfree(cmd->pdu_list); kfree(cmd->seq_list); kfree(cmd->tmr_req); + kfree(cmd->overflow_buf); kfree(cmd->iov_data); kfree(cmd->text_in_ptr); @@ -744,9 +676,9 @@ void iscsit_release_cmd(struct iscsi_cmd *cmd) } EXPORT_SYMBOL(iscsit_release_cmd); -void __iscsit_free_cmd(struct iscsi_cmd *cmd, bool check_queues) +void __iscsit_free_cmd(struct iscsit_cmd *cmd, bool check_queues) { - struct iscsi_conn *conn = cmd->conn; + struct iscsit_conn *conn = cmd->conn; WARN_ON(!list_empty(&cmd->i_conn_node)); @@ -762,15 +694,17 @@ void __iscsit_free_cmd(struct iscsi_cmd *cmd, bool check_queues) iscsit_remove_cmd_from_response_queue(cmd, conn); } - if (conn && conn->conn_transport->iscsit_release_cmd) - conn->conn_transport->iscsit_release_cmd(conn, cmd); + if (conn && conn->conn_transport->iscsit_unmap_cmd) + conn->conn_transport->iscsit_unmap_cmd(conn, cmd); } -void iscsit_free_cmd(struct iscsi_cmd *cmd, bool shutdown) +void iscsit_free_cmd(struct iscsit_cmd *cmd, bool shutdown) { struct se_cmd *se_cmd = cmd->se_cmd.se_tfo ? &cmd->se_cmd : NULL; int rc; + WARN_ON(!list_empty(&cmd->i_conn_node)); + __iscsit_free_cmd(cmd, shutdown); if (se_cmd) { rc = transport_generic_free_cmd(se_cmd, shutdown); @@ -784,24 +718,25 @@ void iscsit_free_cmd(struct iscsi_cmd *cmd, bool shutdown) } EXPORT_SYMBOL(iscsit_free_cmd); -int iscsit_check_session_usage_count(struct iscsi_session *sess) +bool iscsit_check_session_usage_count(struct iscsit_session *sess, + bool can_sleep) { spin_lock_bh(&sess->session_usage_lock); if (sess->session_usage_count != 0) { sess->session_waiting_on_uc = 1; spin_unlock_bh(&sess->session_usage_lock); - if (in_interrupt()) - return 2; + if (!can_sleep) + return true; wait_for_completion(&sess->session_waiting_on_uc_comp); - return 1; + return false; } spin_unlock_bh(&sess->session_usage_lock); - return 0; + return false; } -void iscsit_dec_session_usage_count(struct iscsi_session *sess) +void iscsit_dec_session_usage_count(struct iscsit_session *sess) { spin_lock_bh(&sess->session_usage_lock); sess->session_usage_count--; @@ -812,16 +747,16 @@ void iscsit_dec_session_usage_count(struct iscsi_session *sess) spin_unlock_bh(&sess->session_usage_lock); } -void iscsit_inc_session_usage_count(struct iscsi_session *sess) +void iscsit_inc_session_usage_count(struct iscsit_session *sess) { spin_lock_bh(&sess->session_usage_lock); sess->session_usage_count++; spin_unlock_bh(&sess->session_usage_lock); } -struct iscsi_conn *iscsit_get_conn_from_cid(struct iscsi_session *sess, u16 cid) +struct iscsit_conn *iscsit_get_conn_from_cid(struct iscsit_session *sess, u16 cid) { - struct iscsi_conn *conn; + struct iscsit_conn *conn; spin_lock_bh(&sess->conn_lock); list_for_each_entry(conn, &sess->sess_conn_list, conn_list) { @@ -837,9 +772,9 @@ struct iscsi_conn *iscsit_get_conn_from_cid(struct iscsi_session *sess, u16 cid) return NULL; } -struct iscsi_conn *iscsit_get_conn_from_cid_rcfr(struct iscsi_session *sess, u16 cid) +struct iscsit_conn *iscsit_get_conn_from_cid_rcfr(struct iscsit_session *sess, u16 cid) { - struct iscsi_conn *conn; + struct iscsit_conn *conn; spin_lock_bh(&sess->conn_lock); list_for_each_entry(conn, &sess->sess_conn_list, conn_list) { @@ -857,7 +792,7 @@ struct iscsi_conn *iscsit_get_conn_from_cid_rcfr(struct iscsi_session *sess, u16 return NULL; } -void iscsit_check_conn_usage_count(struct iscsi_conn *conn) +void iscsit_check_conn_usage_count(struct iscsit_conn *conn) { spin_lock_bh(&conn->conn_usage_lock); if (conn->conn_usage_count != 0) { @@ -870,7 +805,7 @@ void iscsit_check_conn_usage_count(struct iscsi_conn *conn) spin_unlock_bh(&conn->conn_usage_lock); } -void iscsit_dec_conn_usage_count(struct iscsi_conn *conn) +void iscsit_dec_conn_usage_count(struct iscsit_conn *conn) { spin_lock_bh(&conn->conn_usage_lock); conn->conn_usage_count--; @@ -881,17 +816,17 @@ void iscsit_dec_conn_usage_count(struct iscsi_conn *conn) spin_unlock_bh(&conn->conn_usage_lock); } -void iscsit_inc_conn_usage_count(struct iscsi_conn *conn) +void iscsit_inc_conn_usage_count(struct iscsit_conn *conn) { spin_lock_bh(&conn->conn_usage_lock); conn->conn_usage_count++; spin_unlock_bh(&conn->conn_usage_lock); } -static int iscsit_add_nopin(struct iscsi_conn *conn, int want_response) +static int iscsit_add_nopin(struct iscsit_conn *conn, int want_response) { u8 state; - struct iscsi_cmd *cmd; + struct iscsit_cmd *cmd; cmd = iscsit_allocate_cmd(conn, TASK_RUNNING); if (!cmd) @@ -916,8 +851,9 @@ static int iscsit_add_nopin(struct iscsi_conn *conn, int want_response) void iscsit_handle_nopin_response_timeout(struct timer_list *t) { - struct iscsi_conn *conn = from_timer(conn, t, nopin_response_timer); - struct iscsi_session *sess = conn->sess; + struct iscsit_conn *conn = timer_container_of(conn, t, + nopin_response_timer); + struct iscsit_session *sess = conn->sess; iscsit_inc_conn_usage_count(conn); @@ -940,9 +876,9 @@ void iscsit_handle_nopin_response_timeout(struct timer_list *t) iscsit_dec_conn_usage_count(conn); } -void iscsit_mod_nopin_response_timer(struct iscsi_conn *conn) +void iscsit_mod_nopin_response_timer(struct iscsit_conn *conn) { - struct iscsi_session *sess = conn->sess; + struct iscsit_session *sess = conn->sess; struct iscsi_node_attrib *na = iscsit_tpg_get_node_attrib(sess); spin_lock_bh(&conn->nopin_timer_lock); @@ -956,12 +892,9 @@ void iscsit_mod_nopin_response_timer(struct iscsi_conn *conn) spin_unlock_bh(&conn->nopin_timer_lock); } -/* - * Called with conn->nopin_timer_lock held. - */ -void iscsit_start_nopin_response_timer(struct iscsi_conn *conn) +void iscsit_start_nopin_response_timer(struct iscsit_conn *conn) { - struct iscsi_session *sess = conn->sess; + struct iscsit_session *sess = conn->sess; struct iscsi_node_attrib *na = iscsit_tpg_get_node_attrib(sess); spin_lock_bh(&conn->nopin_timer_lock); @@ -980,7 +913,7 @@ void iscsit_start_nopin_response_timer(struct iscsi_conn *conn) spin_unlock_bh(&conn->nopin_timer_lock); } -void iscsit_stop_nopin_response_timer(struct iscsi_conn *conn) +void iscsit_stop_nopin_response_timer(struct iscsit_conn *conn) { spin_lock_bh(&conn->nopin_timer_lock); if (!(conn->nopin_response_timer_flags & ISCSI_TF_RUNNING)) { @@ -990,7 +923,7 @@ void iscsit_stop_nopin_response_timer(struct iscsi_conn *conn) conn->nopin_response_timer_flags |= ISCSI_TF_STOP; spin_unlock_bh(&conn->nopin_timer_lock); - del_timer_sync(&conn->nopin_response_timer); + timer_delete_sync(&conn->nopin_response_timer); spin_lock_bh(&conn->nopin_timer_lock); conn->nopin_response_timer_flags &= ~ISCSI_TF_RUNNING; @@ -999,7 +932,7 @@ void iscsit_stop_nopin_response_timer(struct iscsi_conn *conn) void iscsit_handle_nopin_timeout(struct timer_list *t) { - struct iscsi_conn *conn = from_timer(conn, t, nopin_timer); + struct iscsit_conn *conn = timer_container_of(conn, t, nopin_timer); iscsit_inc_conn_usage_count(conn); @@ -1016,13 +949,13 @@ void iscsit_handle_nopin_timeout(struct timer_list *t) iscsit_dec_conn_usage_count(conn); } -/* - * Called with conn->nopin_timer_lock held. - */ -void __iscsit_start_nopin_timer(struct iscsi_conn *conn) +void __iscsit_start_nopin_timer(struct iscsit_conn *conn) { - struct iscsi_session *sess = conn->sess; + struct iscsit_session *sess = conn->sess; struct iscsi_node_attrib *na = iscsit_tpg_get_node_attrib(sess); + + lockdep_assert_held(&conn->nopin_timer_lock); + /* * NOPIN timeout is disabled. */ @@ -1040,14 +973,14 @@ void __iscsit_start_nopin_timer(struct iscsi_conn *conn) " interval\n", conn->cid, na->nopin_timeout); } -void iscsit_start_nopin_timer(struct iscsi_conn *conn) +void iscsit_start_nopin_timer(struct iscsit_conn *conn) { spin_lock_bh(&conn->nopin_timer_lock); __iscsit_start_nopin_timer(conn); spin_unlock_bh(&conn->nopin_timer_lock); } -void iscsit_stop_nopin_timer(struct iscsi_conn *conn) +void iscsit_stop_nopin_timer(struct iscsit_conn *conn) { spin_lock_bh(&conn->nopin_timer_lock); if (!(conn->nopin_timer_flags & ISCSI_TF_RUNNING)) { @@ -1057,16 +990,67 @@ void iscsit_stop_nopin_timer(struct iscsi_conn *conn) conn->nopin_timer_flags |= ISCSI_TF_STOP; spin_unlock_bh(&conn->nopin_timer_lock); - del_timer_sync(&conn->nopin_timer); + timer_delete_sync(&conn->nopin_timer); spin_lock_bh(&conn->nopin_timer_lock); conn->nopin_timer_flags &= ~ISCSI_TF_RUNNING; spin_unlock_bh(&conn->nopin_timer_lock); } +void iscsit_login_timeout(struct timer_list *t) +{ + struct iscsit_conn *conn = timer_container_of(conn, t, login_timer); + struct iscsi_login *login = conn->login; + + pr_debug("Entering iscsi_target_login_timeout >>>>>>>>>>>>>>>>>>>\n"); + + spin_lock_bh(&conn->login_timer_lock); + login->login_failed = 1; + + if (conn->login_kworker) { + pr_debug("Sending SIGINT to conn->login_kworker %s/%d\n", + conn->login_kworker->comm, conn->login_kworker->pid); + send_sig(SIGINT, conn->login_kworker, 1); + } else { + schedule_delayed_work(&conn->login_work, 0); + } + spin_unlock_bh(&conn->login_timer_lock); +} + +void iscsit_start_login_timer(struct iscsit_conn *conn, struct task_struct *kthr) +{ + pr_debug("Login timer started\n"); + + conn->login_kworker = kthr; + mod_timer(&conn->login_timer, jiffies + TA_LOGIN_TIMEOUT * HZ); +} + +int iscsit_set_login_timer_kworker(struct iscsit_conn *conn, struct task_struct *kthr) +{ + struct iscsi_login *login = conn->login; + int ret = 0; + + spin_lock_bh(&conn->login_timer_lock); + if (login->login_failed) { + /* The timer has already expired */ + ret = -1; + } else { + conn->login_kworker = kthr; + } + spin_unlock_bh(&conn->login_timer_lock); + + return ret; +} + +void iscsit_stop_login_timer(struct iscsit_conn *conn) +{ + pr_debug("Login timer stopped\n"); + timer_delete_sync(&conn->login_timer); +} + int iscsit_send_tx_data( - struct iscsi_cmd *cmd, - struct iscsi_conn *conn, + struct iscsit_cmd *cmd, + struct iscsit_conn *conn, int use_misc) { int tx_sent, tx_size; @@ -1098,10 +1082,12 @@ send_data: } int iscsit_fe_sendpage_sg( - struct iscsi_cmd *cmd, - struct iscsi_conn *conn) + struct iscsit_cmd *cmd, + struct iscsit_conn *conn) { struct scatterlist *sg = cmd->first_data_sg; + struct bio_vec bvec; + struct msghdr msghdr = { .msg_flags = MSG_SPLICE_PAGES, }; struct kvec iov; u32 tx_hdr_size, data_len; u32 offset = cmd->first_data_sg_off; @@ -1145,17 +1131,18 @@ send_hdr: u32 space = (sg->length - offset); u32 sub_len = min_t(u32, data_len, space); send_pg: - tx_sent = conn->sock->ops->sendpage(conn->sock, - sg_page(sg), sg->offset + offset, sub_len, 0); + bvec_set_page(&bvec, sg_page(sg), sub_len, sg->offset + offset); + iov_iter_bvec(&msghdr.msg_iter, ITER_SOURCE, &bvec, 1, sub_len); + + tx_sent = conn->sock->ops->sendmsg(conn->sock, &msghdr, + sub_len); if (tx_sent != sub_len) { if (tx_sent == -EAGAIN) { - pr_err("tcp_sendpage() returned" - " -EAGAIN\n"); + pr_err("sendmsg/splice returned -EAGAIN\n"); goto send_pg; } - pr_err("tcp_sendpage() failure: %d\n", - tx_sent); + pr_err("sendmsg/splice failure: %d\n", tx_sent); return -1; } @@ -1203,7 +1190,7 @@ send_datacrc: * Parameters: iSCSI Connection, Status Class, Status Detail. * Returns: 0 on success, -1 on error. */ -int iscsit_tx_login_rsp(struct iscsi_conn *conn, u8 status_class, u8 status_detail) +int iscsit_tx_login_rsp(struct iscsit_conn *conn, u8 status_class, u8 status_detail) { struct iscsi_login_rsp *hdr; struct iscsi_login *login = conn->conn_login; @@ -1222,32 +1209,20 @@ int iscsit_tx_login_rsp(struct iscsi_conn *conn, u8 status_class, u8 status_deta return conn->conn_transport->iscsit_put_login_tx(conn, login, 0); } -void iscsit_print_session_params(struct iscsi_session *sess) -{ - struct iscsi_conn *conn; - - pr_debug("-----------------------------[Session Params for" - " SID: %u]-----------------------------\n", sess->sid); - spin_lock_bh(&sess->conn_lock); - list_for_each_entry(conn, &sess->sess_conn_list, conn_list) - iscsi_dump_conn_ops(conn->conn_ops); - spin_unlock_bh(&sess->conn_lock); - - iscsi_dump_sess_ops(sess->sess_ops); -} - -static int iscsit_do_rx_data( - struct iscsi_conn *conn, - struct iscsi_data_count *count) +int rx_data( + struct iscsit_conn *conn, + struct kvec *iov, + int iov_count, + int data) { - int data = count->data_length, rx_loop = 0, total_rx = 0; + int rx_loop = 0, total_rx = 0; struct msghdr msg; if (!conn || !conn->sock || !conn->conn_ops) return -1; memset(&msg, 0, sizeof(struct msghdr)); - iov_iter_kvec(&msg.msg_iter, READ, count->iov, count->iov_count, data); + iov_iter_kvec(&msg.msg_iter, ITER_DEST, iov, iov_count, data); while (msg_data_left(&msg)) { rx_loop = sock_recvmsg(conn->sock, &msg, MSG_WAITALL); @@ -1264,28 +1239,8 @@ static int iscsit_do_rx_data( return total_rx; } -int rx_data( - struct iscsi_conn *conn, - struct kvec *iov, - int iov_count, - int data) -{ - struct iscsi_data_count c; - - if (!conn || !conn->sock || !conn->conn_ops) - return -1; - - memset(&c, 0, sizeof(struct iscsi_data_count)); - c.iov = iov; - c.iov_count = iov_count; - c.data_length = data; - c.type = ISCSI_RX_DATA; - - return iscsit_do_rx_data(conn, &c); -} - int tx_data( - struct iscsi_conn *conn, + struct iscsit_conn *conn, struct kvec *iov, int iov_count, int data) @@ -1303,7 +1258,7 @@ int tx_data( memset(&msg, 0, sizeof(struct msghdr)); - iov_iter_kvec(&msg.msg_iter, WRITE, iov, iov_count, data); + iov_iter_kvec(&msg.msg_iter, ITER_SOURCE, iov, iov_count, data); while (msg_data_left(&msg)) { int tx_loop = sock_sendmsg(conn->sock, &msg); @@ -1321,7 +1276,7 @@ int tx_data( } void iscsit_collect_login_stats( - struct iscsi_conn *conn, + struct iscsit_conn *conn, u8 status_class, u8 status_detail) { @@ -1363,7 +1318,7 @@ void iscsit_collect_login_stats( if (conn->param_list) intrname = iscsi_find_param_from_key(INITIATORNAME, conn->param_list); - strlcpy(ls->last_intr_fail_name, + strscpy(ls->last_intr_fail_name, (intrname ? intrname->value : "Unknown"), sizeof(ls->last_intr_fail_name)); @@ -1376,7 +1331,7 @@ void iscsit_collect_login_stats( spin_unlock(&ls->lock); } -struct iscsi_tiqn *iscsit_snmp_get_tiqn(struct iscsi_conn *conn) +struct iscsi_tiqn *iscsit_snmp_get_tiqn(struct iscsit_conn *conn) { struct iscsi_portal_group *tpg; @@ -1393,7 +1348,7 @@ struct iscsi_tiqn *iscsit_snmp_get_tiqn(struct iscsi_conn *conn) return tpg->tpg_tiqn; } -void iscsit_fill_cxn_timeout_err_stats(struct iscsi_session *sess) +void iscsit_fill_cxn_timeout_err_stats(struct iscsit_session *sess) { struct iscsi_portal_group *tpg = sess->tpg; struct iscsi_tiqn *tiqn = tpg->tpg_tiqn; @@ -1402,7 +1357,7 @@ void iscsit_fill_cxn_timeout_err_stats(struct iscsi_session *sess) return; spin_lock_bh(&tiqn->sess_err_stats.lock); - strlcpy(tiqn->sess_err_stats.last_sess_fail_rem_name, + strscpy(tiqn->sess_err_stats.last_sess_fail_rem_name, sess->sess_ops->InitiatorName, sizeof(tiqn->sess_err_stats.last_sess_fail_rem_name)); tiqn->sess_err_stats.last_sess_failure_type = |
