diff options
Diffstat (limited to 'drivers/scsi')
-rw-r--r-- | drivers/scsi/iscsi_tcp.c | 40 | ||||
-rw-r--r-- | drivers/scsi/libiscsi.c | 55 |
2 files changed, 33 insertions, 62 deletions
diff --git a/drivers/scsi/iscsi_tcp.c b/drivers/scsi/iscsi_tcp.c index c66faee07ca5..2abda804a924 100644 --- a/drivers/scsi/iscsi_tcp.c +++ b/drivers/scsi/iscsi_tcp.c @@ -1955,30 +1955,28 @@ iscsi_tcp_conn_bind(struct iscsi_cls_session *cls_session, 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; } diff --git a/drivers/scsi/libiscsi.c b/drivers/scsi/libiscsi.c index d810acae45f7..963002598995 100644 --- a/drivers/scsi/libiscsi.c +++ b/drivers/scsi/libiscsi.c @@ -492,7 +492,7 @@ void iscsi_conn_failure(struct iscsi_conn *conn, enum iscsi_err err) 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); @@ -652,7 +652,7 @@ int iscsi_queuecommand(struct scsi_cmnd *sc, void (*done)(struct scsi_cmnd *)) */ if (session->state == ISCSI_STATE_IN_RECOVERY) { reason = FAILURE_SESSION_IN_RECOVERY; - goto fault; + goto reject; } if (session->state == ISCSI_STATE_RECOVERY_FAILED) @@ -1411,8 +1411,8 @@ void iscsi_conn_teardown(struct iscsi_cls_conn *cls_conn) 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); @@ -1498,7 +1498,6 @@ int iscsi_conn_start(struct iscsi_cls_conn *cls_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++; @@ -1508,13 +1507,7 @@ int iscsi_conn_start(struct iscsi_cls_conn *cls_conn) 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; @@ -1589,28 +1582,24 @@ static void iscsi_start_session_recovery(struct iscsi_session *session, /* * 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 @@ -1620,13 +1609,11 @@ static void iscsi_start_session_recovery(struct iscsi_session *session, 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); @@ -1651,20 +1638,6 @@ void iscsi_conn_stop(struct iscsi_cls_conn *cls_conn, int flag) 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); } |