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;
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)) {
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;
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;
{
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)
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;
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);
}
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;
}
}