if (err)
return err;
- if (conn->stop_stage != STOP_CONN_SUSPEND) {
- /* bind iSCSI connection and socket */
- tcp_conn->sock = sock;
+ /* bind iSCSI connection and socket */
+ tcp_conn->sock = sock;
- /* setup Socket parameters */
- sk = sock->sk;
- sk->sk_reuse = 1;
- sk->sk_sndtimeo = 15 * HZ; /* FIXME: make it configurable */
- sk->sk_allocation = GFP_ATOMIC;
+ /* setup Socket parameters */
+ sk = sock->sk;
+ sk->sk_reuse = 1;
+ sk->sk_sndtimeo = 15 * HZ; /* FIXME: make it configurable */
+ sk->sk_allocation = GFP_ATOMIC;
- /* FIXME: disable Nagle's algorithm */
+ /* FIXME: disable Nagle's algorithm */
- /*
- * Intercept TCP callbacks for sendfile like receive
- * processing.
- */
- conn->recv_lock = &sk->sk_callback_lock;
- iscsi_conn_set_callbacks(conn);
- tcp_conn->sendpage = tcp_conn->sock->ops->sendpage;
- /*
- * set receive state machine into initial state
- */
- tcp_conn->in_progress = IN_PROGRESS_WAIT_HEADER;
- }
+ /*
+ * Intercept TCP callbacks for sendfile like receive
+ * processing.
+ */
+ conn->recv_lock = &sk->sk_callback_lock;
+ iscsi_conn_set_callbacks(conn);
+ tcp_conn->sendpage = tcp_conn->sock->ops->sendpage;
+ /*
+ * set receive state machine into initial state
+ */
+ tcp_conn->in_progress = IN_PROGRESS_WAIT_HEADER;
return 0;
}
return;
}
- if (session->conn_cnt == 1 || session->leadconn == conn)
+ if (conn->stop_stage == 0)
session->state = ISCSI_STATE_FAILED;
spin_unlock_irqrestore(&session->lock, flags);
set_bit(ISCSI_SUSPEND_BIT, &conn->suspend_tx);
*/
if (session->state == ISCSI_STATE_IN_RECOVERY) {
reason = FAILURE_SESSION_IN_RECOVERY;
- goto fault;
+ goto reject;
}
if (session->state == ISCSI_STATE_RECOVERY_FAILED)
struct iscsi_session *session = conn->session;
unsigned long flags;
- mutex_lock(&conn->xmitmutex);
set_bit(ISCSI_SUSPEND_BIT, &conn->suspend_tx);
+ mutex_lock(&conn->xmitmutex);
if (conn->c_stage == ISCSI_CONN_INITIAL_STAGE) {
if (session->tt->suspend_conn_recv)
session->tt->suspend_conn_recv(conn);
* unblock eh_abort() if it is blocked. re-try all
* commands after successful recovery
*/
- session->conn_cnt++;
conn->stop_stage = 0;
conn->tmabort_state = TMABORT_INITIAL;
session->age++;
wake_up(&conn->ehwait);
return 0;
case STOP_CONN_TERM:
- session->conn_cnt++;
- conn->stop_stage = 0;
- break;
- case STOP_CONN_SUSPEND:
conn->stop_stage = 0;
- clear_bit(ISCSI_SUSPEND_BIT, &conn->suspend_rx);
- clear_bit(ISCSI_SUSPEND_BIT, &conn->suspend_tx);
break;
default:
break;
/*
* When this is called for the in_login state, we only want to clean
- * up the login task and connection.
+ * up the login task and connection. We do not need to block and set
+ * the recovery state again
*/
- if (conn->stop_stage != STOP_CONN_RECOVER)
- session->conn_cnt--;
+ if (flag == STOP_CONN_TERM)
+ session->state = ISCSI_STATE_TERMINATE;
+ else if (conn->stop_stage != STOP_CONN_RECOVER)
+ session->state = ISCSI_STATE_IN_RECOVERY;
old_stop_stage = conn->stop_stage;
conn->stop_stage = flag;
+ conn->c_stage = ISCSI_CONN_STOPPED;
+ set_bit(ISCSI_SUSPEND_BIT, &conn->suspend_tx);
spin_unlock_bh(&session->lock);
if (session->tt->suspend_conn_recv)
session->tt->suspend_conn_recv(conn);
mutex_lock(&conn->xmitmutex);
- spin_lock_bh(&session->lock);
- conn->c_stage = ISCSI_CONN_STOPPED;
- set_bit(ISCSI_SUSPEND_BIT, &conn->suspend_tx);
-
- if (session->conn_cnt == 0 || session->leadconn == conn)
- session->state = ISCSI_STATE_IN_RECOVERY;
-
- spin_unlock_bh(&session->lock);
-
/*
* for connection level recovery we should not calculate
* header digest. conn->hdr_size used for optimization
if (flag == STOP_CONN_RECOVER) {
conn->hdrdgst_en = 0;
conn->datadgst_en = 0;
- /*
- * if this is called from the eh and and from userspace
- * then we only need to block once.
- */
if (session->state == ISCSI_STATE_IN_RECOVERY &&
- old_stop_stage != STOP_CONN_RECOVER)
+ old_stop_stage != STOP_CONN_RECOVER) {
+ debug_scsi("blocking session\n");
iscsi_block_session(session_to_cls(session));
+ }
}
session->tt->terminate_conn(conn);
case STOP_CONN_TERM:
iscsi_start_session_recovery(session, conn, flag);
break;
- case STOP_CONN_SUSPEND:
- if (session->tt->suspend_conn_recv)
- session->tt->suspend_conn_recv(conn);
-
- mutex_lock(&conn->xmitmutex);
- spin_lock_bh(&session->lock);
-
- conn->stop_stage = flag;
- conn->c_stage = ISCSI_CONN_STOPPED;
- set_bit(ISCSI_SUSPEND_BIT, &conn->suspend_tx);
-
- spin_unlock_bh(&session->lock);
- mutex_unlock(&conn->xmitmutex);
- break;
default:
printk(KERN_ERR "iscsi: invalid stop flag %d\n", flag);
}