Session and connection reinstation fixes for cases when they are shutting down and...
authorvlnb <vlnb@d57e44dd-8a1f-0410-8b47-8ef2f437770f>
Fri, 6 Mar 2009 19:04:48 +0000 (19:04 +0000)
committervlnb <vlnb@d57e44dd-8a1f-0410-8b47-8ef2f437770f>
Fri, 6 Mar 2009 19:04:48 +0000 (19:04 +0000)
git-svn-id: https://scst.svn.sourceforge.net/svnroot/scst/trunk@692 d57e44dd-8a1f-0410-8b47-8ef2f437770f

iscsi-scst/kernel/conn.c
iscsi-scst/kernel/iscsi.h
iscsi-scst/kernel/nthread.c
iscsi-scst/kernel/session.c

index 40e05db..238464f 100644 (file)
@@ -394,6 +394,7 @@ int conn_free(struct iscsi_conn *conn)
        sBUG_ON(!list_empty(&conn->write_list));
        sBUG_ON(!list_empty(&conn->written_list));
        sBUG_ON(conn->conn_reinst_successor != NULL);
+       sBUG_ON(!conn->conn_shutting_down);
 
        if (conn->conn_reinstating) {
                struct iscsi_conn *c;
@@ -504,7 +505,7 @@ int conn_add(struct iscsi_session *session, struct iscsi_kern_conn_info *info)
        bool reinstatement = false;
 
        conn = conn_lookup(session, info->cid);
-       if (conn != NULL) {
+       if ((conn != NULL) && !conn->conn_shutting_down) {
                /* conn reinstatement */
                reinstatement = true;
        } else if (!list_empty(&session->conn_list)) {
index 6049cf7..a57fc62 100644 (file)
@@ -114,9 +114,10 @@ struct iscsi_session {
 
        struct list_head session_list_entry;
 
-       /* All don't need any protection */
+       /* All protected by target_mutex, where necessary */
        struct iscsi_session *sess_reinst_successor;
        unsigned int sess_reinstating:1;
+       unsigned int sess_shutting_down:1;
 
        /* All don't need any protection */
        char *initiator_name;
@@ -218,9 +219,10 @@ struct iscsi_conn {
 
        struct list_head conn_list_entry; /* list entry in session conn_list */
 
-       /* All don't need any protection */
+       /* All protected by target_mutex, where necessary */
        struct iscsi_conn *conn_reinst_successor;
        unsigned int conn_reinstating:1;
+       unsigned int conn_shutting_down:1;
 
        struct completion ready_to_free;
 
index 5a629d5..98336ec 100644 (file)
@@ -358,10 +358,11 @@ static void close_conn(struct iscsi_conn *conn)
 {
        struct iscsi_session *session = conn->session;
        struct iscsi_target *target = conn->target;
+       struct iscsi_conn *c;
        typeof(jiffies) start_waiting = jiffies;
        typeof(jiffies) shut_start_waiting = start_waiting;
        bool pending_reported = 0, wait_expired = 0, shut_expired = 0;
-       bool free_sess;
+       bool reinst;
 
 #define CONN_PENDING_TIMEOUT   ((typeof(jiffies))10*HZ)
 #define CONN_WAIT_TIMEOUT      ((typeof(jiffies))10*HZ)
@@ -385,7 +386,22 @@ static void close_conn(struct iscsi_conn *conn)
                        RCV_SHUTDOWN|SEND_SHUTDOWN);
        }
 
-       if (conn->conn_reinst_successor != NULL) {
+       mutex_lock(&session->target->target_mutex);
+
+       conn->conn_shutting_down = 1;
+       reinst = (conn->conn_reinst_successor != NULL);
+
+       session->sess_shutting_down = 1;
+       list_for_each_entry(c, &session->conn_list, conn_list_entry) {
+               if (!c->conn_shutting_down) {
+                       session->sess_shutting_down = 0;
+                       break;
+               }
+       }
+
+       mutex_unlock(&session->target->target_mutex);
+
+       if (reinst) {
                int rc;
                int lun = 0;
 
@@ -525,14 +541,11 @@ static void close_conn(struct iscsi_conn *conn)
 
        mutex_lock(&target->target_mutex);
 
-       free_sess = (conn->conn_reinst_successor == NULL);
        conn->conn_reinst_successor = NULL;
-
        conn_free(conn);
 
-       if (free_sess) {
+       if (list_empty(&session->conn_list)) {
                sBUG_ON(session->sess_reinst_successor != NULL);
-               /* ToDo: this is incompatible with MC/S */
                session_free(session);
        }
 
index f81688d..821ad94 100644 (file)
@@ -184,8 +184,10 @@ int session_add(struct iscsi_target *target,
                i.id.tsih = 0;
                if ((sid.id64 == i.id64) &&
                    (strcmp(info->initiator_name, session->initiator_name) == 0)) {
-                       /* session reinstatement */
-                       old_sess = session;
+                       if (!session->sess_shutting_down) {
+                               /* session reinstatement */
+                               old_sess = session;
+                       }
                        break;
                }
        }