cmnd->scst_state = ISCSI_CMD_STATE_RESTARTED;
scst_restart_cmd(cmnd->scst_cmd, SCST_PREPROCESS_STATUS_SUCCESS,
SCST_CONTEXT_THREAD);
+ return;
}
static inline void iscsi_restart_waiting_cmnd(struct iscsi_cmnd *cmnd)
cmnd->data_waiting = 0;
iscsi_restart_cmnd(cmnd);
+ return;
}
static inline void iscsi_fail_waiting_cmnd(struct iscsi_cmnd *cmnd)
ISCSI_INIT_WRITE_WAKE);
cmnd_prepare_get_rejected_cmd_data(req);
+ return;
}
static inline int iscsi_get_allowed_cmds(struct iscsi_session *sess)
/* free pdu resources */
cmnd->conn->exp_stat_sn = exp_stat_sn;
}
+ return;
}
static inline void update_stat_sn(struct iscsi_cmnd *cmnd)
spin_lock(&cmnd->conn->session->sn_lock);
__update_stat_sn(cmnd);
spin_unlock(&cmnd->conn->session->sn_lock);
+ return;
}
/* Called under sn_lock */
}
spin_unlock(&session->cmnd_hash_lock);
+ return;
}
static void cmnd_prepare_get_rejected_cmd_data(struct iscsi_cmnd *cmnd)
req_cmnd_release(req);
} else
cmnd_put(req);
+ return;
}
static void logout_exec(struct iscsi_cmnd *req)
iscsi_cmnd_init_write(rsp,
ISCSI_INIT_WRITE_REMOVE_HASH | ISCSI_INIT_WRITE_WAKE);
req_cmnd_release(req);
+ return;
}
static void iscsi_cmnd_exec(struct iscsi_cmnd *cmnd)
conn->write_offset = offset;
conn->write_size += size;
+ return;
}
static void cmnd_send_pdu(struct iscsi_conn *conn, struct iscsi_cmnd *cmnd)
sBUG_ON(cmnd->sg == NULL);
sBUG_ON(cmnd->bufflen != size);
__cmnd_send_pdu(conn, cmnd, 0, size);
+ return;
}
/*
sock->ops->setsockopt(sock, SOL_TCP, TCP_CORK,
(void __force __user *)&opt, sizeof(opt));
set_fs(oldfs);
+ return;
}
void cmnd_tx_start(struct iscsi_cmnd *cmnd)
/* move this? */
conn->write_size = (conn->write_size + 3) & -4;
iscsi_dump_pdu(&cmnd->pdu);
+ return;
}
void cmnd_tx_end(struct iscsi_cmnd *cmnd)
{
struct iscsi_conn *conn = cmnd->conn;
- TRACE_DBG("%p:%x (should_close_conn %d)", cmnd, cmnd_opcode(cmnd),
- cmnd->should_close_conn);
+ TRACE_DBG("%p:%x (should_close_conn %d, should_close_all_conn %d)",
+ cmnd, cmnd_opcode(cmnd), cmnd->should_close_conn,
+ cmnd->should_close_all_conn);
switch (cmnd_opcode(cmnd)) {
case ISCSI_OP_NOOP_IN:
break;
}
- if (cmnd->should_close_conn) {
- PRINT_INFO("Closing connection at initiator %s request",
- conn->session->initiator_name);
- mark_conn_closed(conn);
+ if (unlikely(cmnd->should_close_conn)) {
+ if (cmnd->should_close_all_conn) {
+ PRINT_INFO("Closing all connections for target %x at "
+ "initiator's %s request",
+ cmnd->conn->session->target->tid,
+ conn->session->initiator_name);
+ target_del_all_sess(cmnd->conn->session->target, false);
+ } else {
+ PRINT_INFO("Closing connection at initiator's %s "
+ "request", conn->session->initiator_name);
+ mark_conn_closed(conn);
+ }
}
set_cork(cmnd->conn->sock, 0);
+ return;
}
/*
rsp_hdr->itt = req_hdr->itt;
rsp_hdr->response = status;
- if (fn == ISCSI_FUNCTION_TARGET_COLD_RESET)
+ if (fn == ISCSI_FUNCTION_TARGET_COLD_RESET) {
rsp->should_close_conn = 1;
+ rsp->should_close_all_conn = 1;
+ }
sBUG_ON(sess->tm_rsp != NULL);
list_del(&t->threads_list_entry);
kfree(t);
}
+ return;
}
static int __init iscsi_init(void)
*/
unsigned int hashed:1;
unsigned int should_close_conn:1;
+ unsigned int should_close_all_conn:1;
unsigned int pending:1;
unsigned int own_sg:1;
unsigned int on_write_list:1;
struct iscsi_target *target_lookup_by_id(u32);
extern int target_add(struct target_info *);
extern int target_del(u32 id);
+extern void target_del_all_sess(struct iscsi_target *target, bool deleting);
extern void target_del_all(void);
/* config.c */
}
} while (req_freed);
spin_unlock(&session->sn_lock);
+ return;
}
static void free_orphaned_pending_commands(struct iscsi_conn *conn)
}
} while (req_freed);
spin_unlock(&session->sn_lock);
+ return;
}
#ifdef CONFIG_SCST_DEBUG
#endif /* CONFIG_TCP_ZERO_COPY_TRANSFER_COMPLETION_NOTIFICATION */
}
spin_unlock_bh(&conn->cmd_list_lock);
+ return;
}
#else /* CONFIG_SCST_DEBUG */
static void trace_conn_close(struct iscsi_conn *conn) {}
conn->read_msg.msg_iov = conn->read_iov;
conn->read_msg.msg_iovlen = 1;
conn->read_size = (len + 3) & -4;
+ return;
}
static void iscsi_conn_read_ahs(struct iscsi_conn *conn,
sBUG_ON(cmnd->pdu.ahs == NULL);
iscsi_conn_init_read(conn, (void __force __user *)cmnd->pdu.ahs,
cmnd->pdu.ahssize);
+ return;
}
static struct iscsi_cmnd *iscsi_get_send_cmnd(struct iscsi_conn *conn)
TRACE_NET_PAGE("getting cmd %p", cmd);
cmnd_get(cmd);
}
+ return;
}
void iscsi_get_page_callback(struct page *page)
atomic_read(&page->_count));
__iscsi_get_page_callback(cmd);
+ return;
}
static inline void __iscsi_put_page_callback(struct iscsi_cmnd *cmd)
}
cmnd_put(cmd);
}
+ return;
}
void iscsi_put_page_callback(struct page *page)
atomic_read(&page->_count));
__iscsi_put_page_callback(cmd);
+ return;
}
static void check_net_priv(struct iscsi_cmnd *cmd, struct page *page)
"%p (page %p)", page->net_priv, page);
page->net_priv = NULL;
}
+ return;
}
#else
static inline void check_net_priv(struct iscsi_cmnd *cmd, struct page *page) {}
list_for_each_entry(session, &target->session_list,
session_list_entry) {
- seq_printf(seq, "\tsid:%llu initiator:%s shutting down %d\n",
+ seq_printf(seq, "\tsid:%llx initiator:%s shutting down %d\n",
(long long unsigned int)session->sid,
session->initiator_name,
session->shutting_down);
conn_info_show(seq, session);
}
+ return;
}
static int iscsi_sessions_info_show(struct seq_file *seq, void *v)
}
static void target_del_session(struct iscsi_target *target,
- struct iscsi_session *session)
+ struct iscsi_session *session, bool deleting)
{
+ int flags = ISCSI_CONN_ACTIVE_CLOSE;
+
+ if (deleting)
+ flags |= ISCSI_CONN_DELETING;
+
TRACE_MGMT_DBG("Cleaning up session %p", session);
if (!list_empty(&session->conn_list)) {
struct iscsi_conn *conn, *tc;
list_for_each_entry_safe(conn, tc, &session->conn_list,
conn_list_entry) {
TRACE_MGMT_DBG("Mark conn %p closing", conn);
- __mark_conn_closed(conn,
- ISCSI_CONN_ACTIVE_CLOSE|ISCSI_CONN_DELETING);
+ __mark_conn_closed(conn, flags);
}
} else {
TRACE_MGMT_DBG("Freeing session %p without connections",
}
}
+/* target_mutex supposed to be locked */
+void target_del_all_sess(struct iscsi_target *target, bool deleting)
+{
+ struct iscsi_session *session, *ts;
+
+ TRACE_ENTRY();
+
+ if (!list_empty(&target->session_list)) {
+ TRACE_MGMT_DBG("Deleting all sessions from target %p", target);
+ list_for_each_entry_safe(session, ts, &target->session_list,
+ session_list_entry) {
+ target_del_session(target, session, deleting);
+ }
+ }
+
+ TRACE_EXIT();
+ return;
+}
+
void target_del_all(void)
{
struct iscsi_target *target, *t;
list_for_each_entry_safe(target, t, &target_list,
target_list_entry) {
- struct iscsi_session *session, *ts;
mutex_lock(&target->target_mutex);
if (!list_empty(&target->session_list)) {
- TRACE_MGMT_DBG("Cleaning up target %p",
- target);
- list_for_each_entry_safe(session, ts,
- &target->session_list,
- session_list_entry) {
- target_del_session(target, session);
- }
+ target_del_all_sess(target, true);
mutex_unlock(&target->target_mutex);
} else {
TRACE_MGMT_DBG("Deleting target %p", target);