|
@@ -52,7 +52,7 @@
|
|
|
static LIST_HEAD(g_tiqn_list);
|
|
|
static LIST_HEAD(g_np_list);
|
|
|
static DEFINE_SPINLOCK(tiqn_lock);
|
|
|
-static DEFINE_SPINLOCK(np_lock);
|
|
|
+static DEFINE_MUTEX(np_lock);
|
|
|
|
|
|
static struct idr tiqn_idr;
|
|
|
struct idr sess_idr;
|
|
@@ -307,6 +307,9 @@ bool iscsit_check_np_match(
|
|
|
return false;
|
|
|
}
|
|
|
|
|
|
+/*
|
|
|
+ * Called with mutex np_lock held
|
|
|
+ */
|
|
|
static struct iscsi_np *iscsit_get_np(
|
|
|
struct __kernel_sockaddr_storage *sockaddr,
|
|
|
int network_transport)
|
|
@@ -314,11 +317,10 @@ static struct iscsi_np *iscsit_get_np(
|
|
|
struct iscsi_np *np;
|
|
|
bool match;
|
|
|
|
|
|
- spin_lock_bh(&np_lock);
|
|
|
list_for_each_entry(np, &g_np_list, np_list) {
|
|
|
- spin_lock(&np->np_thread_lock);
|
|
|
+ spin_lock_bh(&np->np_thread_lock);
|
|
|
if (np->np_thread_state != ISCSI_NP_THREAD_ACTIVE) {
|
|
|
- spin_unlock(&np->np_thread_lock);
|
|
|
+ spin_unlock_bh(&np->np_thread_lock);
|
|
|
continue;
|
|
|
}
|
|
|
|
|
@@ -330,13 +332,11 @@ static struct iscsi_np *iscsit_get_np(
|
|
|
* while iscsi_tpg_add_network_portal() is called.
|
|
|
*/
|
|
|
np->np_exports++;
|
|
|
- spin_unlock(&np->np_thread_lock);
|
|
|
- spin_unlock_bh(&np_lock);
|
|
|
+ spin_unlock_bh(&np->np_thread_lock);
|
|
|
return np;
|
|
|
}
|
|
|
- spin_unlock(&np->np_thread_lock);
|
|
|
+ spin_unlock_bh(&np->np_thread_lock);
|
|
|
}
|
|
|
- spin_unlock_bh(&np_lock);
|
|
|
|
|
|
return NULL;
|
|
|
}
|
|
@@ -350,16 +350,22 @@ struct iscsi_np *iscsit_add_np(
|
|
|
struct sockaddr_in6 *sock_in6;
|
|
|
struct iscsi_np *np;
|
|
|
int ret;
|
|
|
+
|
|
|
+ mutex_lock(&np_lock);
|
|
|
+
|
|
|
/*
|
|
|
* Locate the existing struct iscsi_np if already active..
|
|
|
*/
|
|
|
np = iscsit_get_np(sockaddr, network_transport);
|
|
|
- if (np)
|
|
|
+ if (np) {
|
|
|
+ mutex_unlock(&np_lock);
|
|
|
return np;
|
|
|
+ }
|
|
|
|
|
|
np = kzalloc(sizeof(struct iscsi_np), GFP_KERNEL);
|
|
|
if (!np) {
|
|
|
pr_err("Unable to allocate memory for struct iscsi_np\n");
|
|
|
+ mutex_unlock(&np_lock);
|
|
|
return ERR_PTR(-ENOMEM);
|
|
|
}
|
|
|
|
|
@@ -382,6 +388,7 @@ struct iscsi_np *iscsit_add_np(
|
|
|
ret = iscsi_target_setup_login_socket(np, sockaddr);
|
|
|
if (ret != 0) {
|
|
|
kfree(np);
|
|
|
+ mutex_unlock(&np_lock);
|
|
|
return ERR_PTR(ret);
|
|
|
}
|
|
|
|
|
@@ -390,6 +397,7 @@ struct iscsi_np *iscsit_add_np(
|
|
|
pr_err("Unable to create kthread: iscsi_np\n");
|
|
|
ret = PTR_ERR(np->np_thread);
|
|
|
kfree(np);
|
|
|
+ mutex_unlock(&np_lock);
|
|
|
return ERR_PTR(ret);
|
|
|
}
|
|
|
/*
|
|
@@ -400,10 +408,10 @@ struct iscsi_np *iscsit_add_np(
|
|
|
* point because iscsi_np has not been added to g_np_list yet.
|
|
|
*/
|
|
|
np->np_exports = 1;
|
|
|
+ np->np_thread_state = ISCSI_NP_THREAD_ACTIVE;
|
|
|
|
|
|
- spin_lock_bh(&np_lock);
|
|
|
list_add_tail(&np->np_list, &g_np_list);
|
|
|
- spin_unlock_bh(&np_lock);
|
|
|
+ mutex_unlock(&np_lock);
|
|
|
|
|
|
pr_debug("CORE[0] - Added Network Portal: %s:%hu on %s\n",
|
|
|
np->np_ip, np->np_port, np->np_transport->name);
|
|
@@ -469,9 +477,9 @@ int iscsit_del_np(struct iscsi_np *np)
|
|
|
|
|
|
np->np_transport->iscsit_free_np(np);
|
|
|
|
|
|
- spin_lock_bh(&np_lock);
|
|
|
+ mutex_lock(&np_lock);
|
|
|
list_del(&np->np_list);
|
|
|
- spin_unlock_bh(&np_lock);
|
|
|
+ mutex_unlock(&np_lock);
|
|
|
|
|
|
pr_debug("CORE[0] - Removed Network Portal: %s:%hu on %s\n",
|
|
|
np->np_ip, np->np_port, np->np_transport->name);
|