diff options
-rw-r--r-- | drivers/scsi/iscsi_tcp.c | 40 | ||||
-rw-r--r-- | drivers/scsi/libiscsi.c | 55 | ||||
-rw-r--r-- | include/scsi/libiscsi.h | 1 |
3 files changed, 33 insertions, 63 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, | |||
1955 | if (err) | 1955 | if (err) |
1956 | return err; | 1956 | return err; |
1957 | 1957 | ||
1958 | if (conn->stop_stage != STOP_CONN_SUSPEND) { | 1958 | /* bind iSCSI connection and socket */ |
1959 | /* bind iSCSI connection and socket */ | 1959 | tcp_conn->sock = sock; |
1960 | tcp_conn->sock = sock; | ||
1961 | 1960 | ||
1962 | /* setup Socket parameters */ | 1961 | /* setup Socket parameters */ |
1963 | sk = sock->sk; | 1962 | sk = sock->sk; |
1964 | sk->sk_reuse = 1; | 1963 | sk->sk_reuse = 1; |
1965 | sk->sk_sndtimeo = 15 * HZ; /* FIXME: make it configurable */ | 1964 | sk->sk_sndtimeo = 15 * HZ; /* FIXME: make it configurable */ |
1966 | sk->sk_allocation = GFP_ATOMIC; | 1965 | sk->sk_allocation = GFP_ATOMIC; |
1967 | 1966 | ||
1968 | /* FIXME: disable Nagle's algorithm */ | 1967 | /* FIXME: disable Nagle's algorithm */ |
1969 | 1968 | ||
1970 | /* | 1969 | /* |
1971 | * Intercept TCP callbacks for sendfile like receive | 1970 | * Intercept TCP callbacks for sendfile like receive |
1972 | * processing. | 1971 | * processing. |
1973 | */ | 1972 | */ |
1974 | conn->recv_lock = &sk->sk_callback_lock; | 1973 | conn->recv_lock = &sk->sk_callback_lock; |
1975 | iscsi_conn_set_callbacks(conn); | 1974 | iscsi_conn_set_callbacks(conn); |
1976 | tcp_conn->sendpage = tcp_conn->sock->ops->sendpage; | 1975 | tcp_conn->sendpage = tcp_conn->sock->ops->sendpage; |
1977 | /* | 1976 | /* |
1978 | * set receive state machine into initial state | 1977 | * set receive state machine into initial state |
1979 | */ | 1978 | */ |
1980 | tcp_conn->in_progress = IN_PROGRESS_WAIT_HEADER; | 1979 | tcp_conn->in_progress = IN_PROGRESS_WAIT_HEADER; |
1981 | } | ||
1982 | 1980 | ||
1983 | return 0; | 1981 | return 0; |
1984 | } | 1982 | } |
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) | |||
492 | return; | 492 | return; |
493 | } | 493 | } |
494 | 494 | ||
495 | if (session->conn_cnt == 1 || session->leadconn == conn) | 495 | if (conn->stop_stage == 0) |
496 | session->state = ISCSI_STATE_FAILED; | 496 | session->state = ISCSI_STATE_FAILED; |
497 | spin_unlock_irqrestore(&session->lock, flags); | 497 | spin_unlock_irqrestore(&session->lock, flags); |
498 | set_bit(ISCSI_SUSPEND_BIT, &conn->suspend_tx); | 498 | set_bit(ISCSI_SUSPEND_BIT, &conn->suspend_tx); |
@@ -652,7 +652,7 @@ int iscsi_queuecommand(struct scsi_cmnd *sc, void (*done)(struct scsi_cmnd *)) | |||
652 | */ | 652 | */ |
653 | if (session->state == ISCSI_STATE_IN_RECOVERY) { | 653 | if (session->state == ISCSI_STATE_IN_RECOVERY) { |
654 | reason = FAILURE_SESSION_IN_RECOVERY; | 654 | reason = FAILURE_SESSION_IN_RECOVERY; |
655 | goto fault; | 655 | goto reject; |
656 | } | 656 | } |
657 | 657 | ||
658 | if (session->state == ISCSI_STATE_RECOVERY_FAILED) | 658 | if (session->state == ISCSI_STATE_RECOVERY_FAILED) |
@@ -1411,8 +1411,8 @@ void iscsi_conn_teardown(struct iscsi_cls_conn *cls_conn) | |||
1411 | struct iscsi_session *session = conn->session; | 1411 | struct iscsi_session *session = conn->session; |
1412 | unsigned long flags; | 1412 | unsigned long flags; |
1413 | 1413 | ||
1414 | mutex_lock(&conn->xmitmutex); | ||
1415 | set_bit(ISCSI_SUSPEND_BIT, &conn->suspend_tx); | 1414 | set_bit(ISCSI_SUSPEND_BIT, &conn->suspend_tx); |
1415 | mutex_lock(&conn->xmitmutex); | ||
1416 | if (conn->c_stage == ISCSI_CONN_INITIAL_STAGE) { | 1416 | if (conn->c_stage == ISCSI_CONN_INITIAL_STAGE) { |
1417 | if (session->tt->suspend_conn_recv) | 1417 | if (session->tt->suspend_conn_recv) |
1418 | session->tt->suspend_conn_recv(conn); | 1418 | session->tt->suspend_conn_recv(conn); |
@@ -1498,7 +1498,6 @@ int iscsi_conn_start(struct iscsi_cls_conn *cls_conn) | |||
1498 | * unblock eh_abort() if it is blocked. re-try all | 1498 | * unblock eh_abort() if it is blocked. re-try all |
1499 | * commands after successful recovery | 1499 | * commands after successful recovery |
1500 | */ | 1500 | */ |
1501 | session->conn_cnt++; | ||
1502 | conn->stop_stage = 0; | 1501 | conn->stop_stage = 0; |
1503 | conn->tmabort_state = TMABORT_INITIAL; | 1502 | conn->tmabort_state = TMABORT_INITIAL; |
1504 | session->age++; | 1503 | session->age++; |
@@ -1508,13 +1507,7 @@ int iscsi_conn_start(struct iscsi_cls_conn *cls_conn) | |||
1508 | wake_up(&conn->ehwait); | 1507 | wake_up(&conn->ehwait); |
1509 | return 0; | 1508 | return 0; |
1510 | case STOP_CONN_TERM: | 1509 | case STOP_CONN_TERM: |
1511 | session->conn_cnt++; | ||
1512 | conn->stop_stage = 0; | ||
1513 | break; | ||
1514 | case STOP_CONN_SUSPEND: | ||
1515 | conn->stop_stage = 0; | 1510 | conn->stop_stage = 0; |
1516 | clear_bit(ISCSI_SUSPEND_BIT, &conn->suspend_rx); | ||
1517 | clear_bit(ISCSI_SUSPEND_BIT, &conn->suspend_tx); | ||
1518 | break; | 1511 | break; |
1519 | default: | 1512 | default: |
1520 | break; | 1513 | break; |
@@ -1589,28 +1582,24 @@ static void iscsi_start_session_recovery(struct iscsi_session *session, | |||
1589 | 1582 | ||
1590 | /* | 1583 | /* |
1591 | * When this is called for the in_login state, we only want to clean | 1584 | * When this is called for the in_login state, we only want to clean |
1592 | * up the login task and connection. | 1585 | * up the login task and connection. We do not need to block and set |
1586 | * the recovery state again | ||
1593 | */ | 1587 | */ |
1594 | if (conn->stop_stage != STOP_CONN_RECOVER) | 1588 | if (flag == STOP_CONN_TERM) |
1595 | session->conn_cnt--; | 1589 | session->state = ISCSI_STATE_TERMINATE; |
1590 | else if (conn->stop_stage != STOP_CONN_RECOVER) | ||
1591 | session->state = ISCSI_STATE_IN_RECOVERY; | ||
1596 | 1592 | ||
1597 | old_stop_stage = conn->stop_stage; | 1593 | old_stop_stage = conn->stop_stage; |
1598 | conn->stop_stage = flag; | 1594 | conn->stop_stage = flag; |
1595 | conn->c_stage = ISCSI_CONN_STOPPED; | ||
1596 | set_bit(ISCSI_SUSPEND_BIT, &conn->suspend_tx); | ||
1599 | spin_unlock_bh(&session->lock); | 1597 | spin_unlock_bh(&session->lock); |
1600 | 1598 | ||
1601 | if (session->tt->suspend_conn_recv) | 1599 | if (session->tt->suspend_conn_recv) |
1602 | session->tt->suspend_conn_recv(conn); | 1600 | session->tt->suspend_conn_recv(conn); |
1603 | 1601 | ||
1604 | mutex_lock(&conn->xmitmutex); | 1602 | mutex_lock(&conn->xmitmutex); |
1605 | spin_lock_bh(&session->lock); | ||
1606 | conn->c_stage = ISCSI_CONN_STOPPED; | ||
1607 | set_bit(ISCSI_SUSPEND_BIT, &conn->suspend_tx); | ||
1608 | |||
1609 | if (session->conn_cnt == 0 || session->leadconn == conn) | ||
1610 | session->state = ISCSI_STATE_IN_RECOVERY; | ||
1611 | |||
1612 | spin_unlock_bh(&session->lock); | ||
1613 | |||
1614 | /* | 1603 | /* |
1615 | * for connection level recovery we should not calculate | 1604 | * for connection level recovery we should not calculate |
1616 | * header digest. conn->hdr_size used for optimization | 1605 | * header digest. conn->hdr_size used for optimization |
@@ -1620,13 +1609,11 @@ static void iscsi_start_session_recovery(struct iscsi_session *session, | |||
1620 | if (flag == STOP_CONN_RECOVER) { | 1609 | if (flag == STOP_CONN_RECOVER) { |
1621 | conn->hdrdgst_en = 0; | 1610 | conn->hdrdgst_en = 0; |
1622 | conn->datadgst_en = 0; | 1611 | conn->datadgst_en = 0; |
1623 | /* | ||
1624 | * if this is called from the eh and and from userspace | ||
1625 | * then we only need to block once. | ||
1626 | */ | ||
1627 | if (session->state == ISCSI_STATE_IN_RECOVERY && | 1612 | if (session->state == ISCSI_STATE_IN_RECOVERY && |
1628 | old_stop_stage != STOP_CONN_RECOVER) | 1613 | old_stop_stage != STOP_CONN_RECOVER) { |
1614 | debug_scsi("blocking session\n"); | ||
1629 | iscsi_block_session(session_to_cls(session)); | 1615 | iscsi_block_session(session_to_cls(session)); |
1616 | } | ||
1630 | } | 1617 | } |
1631 | 1618 | ||
1632 | session->tt->terminate_conn(conn); | 1619 | session->tt->terminate_conn(conn); |
@@ -1651,20 +1638,6 @@ void iscsi_conn_stop(struct iscsi_cls_conn *cls_conn, int flag) | |||
1651 | case STOP_CONN_TERM: | 1638 | case STOP_CONN_TERM: |
1652 | iscsi_start_session_recovery(session, conn, flag); | 1639 | iscsi_start_session_recovery(session, conn, flag); |
1653 | break; | 1640 | break; |
1654 | case STOP_CONN_SUSPEND: | ||
1655 | if (session->tt->suspend_conn_recv) | ||
1656 | session->tt->suspend_conn_recv(conn); | ||
1657 | |||
1658 | mutex_lock(&conn->xmitmutex); | ||
1659 | spin_lock_bh(&session->lock); | ||
1660 | |||
1661 | conn->stop_stage = flag; | ||
1662 | conn->c_stage = ISCSI_CONN_STOPPED; | ||
1663 | set_bit(ISCSI_SUSPEND_BIT, &conn->suspend_tx); | ||
1664 | |||
1665 | spin_unlock_bh(&session->lock); | ||
1666 | mutex_unlock(&conn->xmitmutex); | ||
1667 | break; | ||
1668 | default: | 1641 | default: |
1669 | printk(KERN_ERR "iscsi: invalid stop flag %d\n", flag); | 1642 | printk(KERN_ERR "iscsi: invalid stop flag %d\n", flag); |
1670 | } | 1643 | } |
diff --git a/include/scsi/libiscsi.h b/include/scsi/libiscsi.h index 17b28f08b692..cbf7e58bd6f9 100644 --- a/include/scsi/libiscsi.h +++ b/include/scsi/libiscsi.h | |||
@@ -211,7 +211,6 @@ struct iscsi_session { | |||
211 | * - r2tpool */ | 211 | * - r2tpool */ |
212 | int state; /* session state */ | 212 | int state; /* session state */ |
213 | struct list_head item; | 213 | struct list_head item; |
214 | int conn_cnt; | ||
215 | int age; /* counts session re-opens */ | 214 | int age; /* counts session re-opens */ |
216 | 215 | ||
217 | struct list_head connections; /* list of connections */ | 216 | struct list_head connections; /* list of connections */ |