aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/libiscsi.c
diff options
context:
space:
mode:
authorMike Christie <michaelc@cs.wisc.edu>2006-05-30 01:37:20 -0400
committerJames Bottomley <jejb@mulgrave.il.steeleye.com>2006-06-05 19:10:45 -0400
commit67a611149b2ac5f4af1e36bfffbfe3198cd3712c (patch)
treef74b70aefc16544901a3a3191bee8be8c467747d /drivers/scsi/libiscsi.c
parent9bf0a28c9a24e2cee5deecf89d118254374c75ba (diff)
[SCSI] iscsi: don't switch states when just cleaning up
If recovery failed or we are in recovery only overwrite the state if we are going to terminate the session or if we logged back in. STOP_CONN_SUSPEND and conn_cnt are not used. We only support a single connection session ATM, so cleanup that code while we are working around it. Signed-off-by: Mike Christie <michaelc@cs.wisc.edu> Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com>
Diffstat (limited to 'drivers/scsi/libiscsi.c')
-rw-r--r--drivers/scsi/libiscsi.c55
1 files changed, 14 insertions, 41 deletions
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 }