|
@@ -1593,7 +1593,8 @@ static int lio_tpg_check_prot_fabric_only(
|
|
|
}
|
|
|
|
|
|
/*
|
|
|
- * Called with spin_lock_bh(struct se_portal_group->session_lock) held..
|
|
|
+ * Called with spin_lock_irq(struct se_portal_group->session_lock) held
|
|
|
+ * or not held.
|
|
|
*
|
|
|
* Also, this function calls iscsit_inc_session_usage_count() on the
|
|
|
* struct iscsi_session in question.
|
|
@@ -1601,19 +1602,32 @@ static int lio_tpg_check_prot_fabric_only(
|
|
|
static int lio_tpg_shutdown_session(struct se_session *se_sess)
|
|
|
{
|
|
|
struct iscsi_session *sess = se_sess->fabric_sess_ptr;
|
|
|
+ struct se_portal_group *se_tpg = se_sess->se_tpg;
|
|
|
+ bool local_lock = false;
|
|
|
+
|
|
|
+ if (!spin_is_locked(&se_tpg->session_lock)) {
|
|
|
+ spin_lock_irq(&se_tpg->session_lock);
|
|
|
+ local_lock = true;
|
|
|
+ }
|
|
|
|
|
|
spin_lock(&sess->conn_lock);
|
|
|
if (atomic_read(&sess->session_fall_back_to_erl0) ||
|
|
|
atomic_read(&sess->session_logout) ||
|
|
|
(sess->time2retain_timer_flags & ISCSI_TF_EXPIRED)) {
|
|
|
spin_unlock(&sess->conn_lock);
|
|
|
+ if (local_lock)
|
|
|
+ spin_unlock_irq(&sess->conn_lock);
|
|
|
return 0;
|
|
|
}
|
|
|
atomic_set(&sess->session_reinstatement, 1);
|
|
|
spin_unlock(&sess->conn_lock);
|
|
|
|
|
|
iscsit_stop_time2retain_timer(sess);
|
|
|
+ spin_unlock_irq(&se_tpg->session_lock);
|
|
|
+
|
|
|
iscsit_stop_session(sess, 1, 1);
|
|
|
+ if (!local_lock)
|
|
|
+ spin_lock_irq(&se_tpg->session_lock);
|
|
|
|
|
|
return 1;
|
|
|
}
|