提交 a91eb7d9 编写于 作者: N Nicholas Bellinger

iscsi-target: Prepare login code for multi-plexing support

This patch prepares the iscsi-target login code for multi-plexing
support.  This includes:

 - Adding iscsi_tpg_np->tpg_np_kref + iscsit_login_kref_put() for
   handling callback of iscsi_tpg_np->tpg_np_comp
 - Adding kref_put() in iscsit_deaccess_np()
 - Adding kref_put() and wait_for_completion() in
   iscsit_reset_np_thread()
 - Refactor login failure path release logic into
   iscsi_target_login_sess_out()
 - Update __iscsi_target_login_thread() to handle
   iscsi_post_login_handler() asynchronous completion
 - Add shutdown parameter for iscsit_clear_tpg_np_login_thread*()

v3 changes:
 - Convert iscsi_portal_group->np_login_lock to ->np_login_sem
 - Add LOGIN_FLAGS definitions

v2 changes:
 - Remove duplicate call to iscsi_post_login_handler() in
   __iscsi_target_login_thread()
 - Drop unused iscsi_np->np_login_tpg
Signed-off-by: NNicholas Bellinger <nab@linux-iscsi.org>
上级 dfecf611
...@@ -220,11 +220,6 @@ int iscsit_access_np(struct iscsi_np *np, struct iscsi_portal_group *tpg) ...@@ -220,11 +220,6 @@ int iscsit_access_np(struct iscsi_np *np, struct iscsi_portal_group *tpg)
spin_unlock_bh(&np->np_thread_lock); spin_unlock_bh(&np->np_thread_lock);
return -1; return -1;
} }
if (np->np_login_tpg) {
pr_err("np->np_login_tpg() is not NULL!\n");
spin_unlock_bh(&np->np_thread_lock);
return -1;
}
spin_unlock_bh(&np->np_thread_lock); spin_unlock_bh(&np->np_thread_lock);
/* /*
* Determine if the portal group is accepting storage traffic. * Determine if the portal group is accepting storage traffic.
...@@ -239,26 +234,38 @@ int iscsit_access_np(struct iscsi_np *np, struct iscsi_portal_group *tpg) ...@@ -239,26 +234,38 @@ int iscsit_access_np(struct iscsi_np *np, struct iscsi_portal_group *tpg)
/* /*
* Here we serialize access across the TIQN+TPG Tuple. * Here we serialize access across the TIQN+TPG Tuple.
*/ */
ret = mutex_lock_interruptible(&tpg->np_login_lock); ret = down_interruptible(&tpg->np_login_sem);
if ((ret != 0) || signal_pending(current)) if ((ret != 0) || signal_pending(current))
return -1; return -1;
spin_lock_bh(&np->np_thread_lock); spin_lock_bh(&tpg->tpg_state_lock);
np->np_login_tpg = tpg; if (tpg->tpg_state != TPG_STATE_ACTIVE) {
spin_unlock_bh(&np->np_thread_lock); spin_unlock_bh(&tpg->tpg_state_lock);
up(&tpg->np_login_sem);
return -1;
}
spin_unlock_bh(&tpg->tpg_state_lock);
return 0; return 0;
} }
int iscsit_deaccess_np(struct iscsi_np *np, struct iscsi_portal_group *tpg) void iscsit_login_kref_put(struct kref *kref)
{
struct iscsi_tpg_np *tpg_np = container_of(kref,
struct iscsi_tpg_np, tpg_np_kref);
complete(&tpg_np->tpg_np_comp);
}
int iscsit_deaccess_np(struct iscsi_np *np, struct iscsi_portal_group *tpg,
struct iscsi_tpg_np *tpg_np)
{ {
struct iscsi_tiqn *tiqn = tpg->tpg_tiqn; struct iscsi_tiqn *tiqn = tpg->tpg_tiqn;
spin_lock_bh(&np->np_thread_lock); up(&tpg->np_login_sem);
np->np_login_tpg = NULL;
spin_unlock_bh(&np->np_thread_lock);
mutex_unlock(&tpg->np_login_lock); if (tpg_np)
kref_put(&tpg_np->tpg_np_kref, iscsit_login_kref_put);
if (tiqn) if (tiqn)
iscsit_put_tiqn_for_login(tiqn); iscsit_put_tiqn_for_login(tiqn);
...@@ -410,20 +417,10 @@ struct iscsi_np *iscsit_add_np( ...@@ -410,20 +417,10 @@ struct iscsi_np *iscsit_add_np(
int iscsit_reset_np_thread( int iscsit_reset_np_thread(
struct iscsi_np *np, struct iscsi_np *np,
struct iscsi_tpg_np *tpg_np, struct iscsi_tpg_np *tpg_np,
struct iscsi_portal_group *tpg) struct iscsi_portal_group *tpg,
bool shutdown)
{ {
spin_lock_bh(&np->np_thread_lock); spin_lock_bh(&np->np_thread_lock);
if (tpg && tpg_np) {
/*
* The reset operation need only be performed when the
* passed struct iscsi_portal_group has a login in progress
* to one of the network portals.
*/
if (tpg_np->tpg_np->np_login_tpg != tpg) {
spin_unlock_bh(&np->np_thread_lock);
return 0;
}
}
if (np->np_thread_state == ISCSI_NP_THREAD_INACTIVE) { if (np->np_thread_state == ISCSI_NP_THREAD_INACTIVE) {
spin_unlock_bh(&np->np_thread_lock); spin_unlock_bh(&np->np_thread_lock);
return 0; return 0;
...@@ -438,6 +435,12 @@ int iscsit_reset_np_thread( ...@@ -438,6 +435,12 @@ int iscsit_reset_np_thread(
} }
spin_unlock_bh(&np->np_thread_lock); spin_unlock_bh(&np->np_thread_lock);
if (tpg_np && shutdown) {
kref_put(&tpg_np->tpg_np_kref, iscsit_login_kref_put);
wait_for_completion(&tpg_np->tpg_np_comp);
}
return 0; return 0;
} }
......
...@@ -7,13 +7,15 @@ extern void iscsit_put_tiqn_for_login(struct iscsi_tiqn *); ...@@ -7,13 +7,15 @@ extern void iscsit_put_tiqn_for_login(struct iscsi_tiqn *);
extern struct iscsi_tiqn *iscsit_add_tiqn(unsigned char *); extern struct iscsi_tiqn *iscsit_add_tiqn(unsigned char *);
extern void iscsit_del_tiqn(struct iscsi_tiqn *); extern void iscsit_del_tiqn(struct iscsi_tiqn *);
extern int iscsit_access_np(struct iscsi_np *, struct iscsi_portal_group *); extern int iscsit_access_np(struct iscsi_np *, struct iscsi_portal_group *);
extern int iscsit_deaccess_np(struct iscsi_np *, struct iscsi_portal_group *); extern void iscsit_login_kref_put(struct kref *);
extern int iscsit_deaccess_np(struct iscsi_np *, struct iscsi_portal_group *,
struct iscsi_tpg_np *);
extern bool iscsit_check_np_match(struct __kernel_sockaddr_storage *, extern bool iscsit_check_np_match(struct __kernel_sockaddr_storage *,
struct iscsi_np *, int); struct iscsi_np *, int);
extern struct iscsi_np *iscsit_add_np(struct __kernel_sockaddr_storage *, extern struct iscsi_np *iscsit_add_np(struct __kernel_sockaddr_storage *,
char *, int); char *, int);
extern int iscsit_reset_np_thread(struct iscsi_np *, struct iscsi_tpg_np *, extern int iscsit_reset_np_thread(struct iscsi_np *, struct iscsi_tpg_np *,
struct iscsi_portal_group *); struct iscsi_portal_group *, bool);
extern int iscsit_del_np(struct iscsi_np *); extern int iscsit_del_np(struct iscsi_np *);
extern int iscsit_reject_cmd(struct iscsi_cmd *cmd, u8, unsigned char *); extern int iscsit_reject_cmd(struct iscsi_cmd *cmd, u8, unsigned char *);
extern void iscsit_set_unsoliticed_dataout(struct iscsi_cmd *); extern void iscsit_set_unsoliticed_dataout(struct iscsi_cmd *);
......
...@@ -554,6 +554,13 @@ struct iscsi_conn { ...@@ -554,6 +554,13 @@ struct iscsi_conn {
struct completion rx_half_close_comp; struct completion rx_half_close_comp;
/* socket used by this connection */ /* socket used by this connection */
struct socket *sock; struct socket *sock;
void (*orig_data_ready)(struct sock *, int);
#define LOGIN_FLAGS_READ_ACTIVE 1
#define LOGIN_FLAGS_CLOSED 2
#define LOGIN_FLAGS_READY 4
unsigned long login_flags;
struct delayed_work login_work;
struct iscsi_login *login;
struct timer_list nopin_timer; struct timer_list nopin_timer;
struct timer_list nopin_response_timer; struct timer_list nopin_response_timer;
struct timer_list transport_timer; struct timer_list transport_timer;
...@@ -584,6 +591,7 @@ struct iscsi_conn { ...@@ -584,6 +591,7 @@ struct iscsi_conn {
void *context; void *context;
struct iscsi_login_thread_s *login_thread; struct iscsi_login_thread_s *login_thread;
struct iscsi_portal_group *tpg; struct iscsi_portal_group *tpg;
struct iscsi_tpg_np *tpg_np;
/* Pointer to parent session */ /* Pointer to parent session */
struct iscsi_session *sess; struct iscsi_session *sess;
/* Pointer to thread_set in use for this conn's threads */ /* Pointer to thread_set in use for this conn's threads */
...@@ -682,6 +690,7 @@ struct iscsi_login { ...@@ -682,6 +690,7 @@ struct iscsi_login {
u8 version_max; u8 version_max;
u8 login_complete; u8 login_complete;
u8 login_failed; u8 login_failed;
bool zero_tsih;
char isid[6]; char isid[6];
u32 cmd_sn; u32 cmd_sn;
itt_t init_task_tag; itt_t init_task_tag;
...@@ -694,6 +703,7 @@ struct iscsi_login { ...@@ -694,6 +703,7 @@ struct iscsi_login {
char *req_buf; char *req_buf;
char *rsp_buf; char *rsp_buf;
struct iscsi_conn *conn; struct iscsi_conn *conn;
struct iscsi_np *np;
} ____cacheline_aligned; } ____cacheline_aligned;
struct iscsi_node_attrib { struct iscsi_node_attrib {
...@@ -773,7 +783,6 @@ struct iscsi_np { ...@@ -773,7 +783,6 @@ struct iscsi_np {
struct __kernel_sockaddr_storage np_sockaddr; struct __kernel_sockaddr_storage np_sockaddr;
struct task_struct *np_thread; struct task_struct *np_thread;
struct timer_list np_login_timer; struct timer_list np_login_timer;
struct iscsi_portal_group *np_login_tpg;
void *np_context; void *np_context;
struct iscsit_transport *np_transport; struct iscsit_transport *np_transport;
struct list_head np_list; struct list_head np_list;
...@@ -788,6 +797,8 @@ struct iscsi_tpg_np { ...@@ -788,6 +797,8 @@ struct iscsi_tpg_np {
struct list_head tpg_np_parent_list; struct list_head tpg_np_parent_list;
struct se_tpg_np se_tpg_np; struct se_tpg_np se_tpg_np;
spinlock_t tpg_np_parent_lock; spinlock_t tpg_np_parent_lock;
struct completion tpg_np_comp;
struct kref tpg_np_kref;
}; };
struct iscsi_portal_group { struct iscsi_portal_group {
...@@ -809,7 +820,7 @@ struct iscsi_portal_group { ...@@ -809,7 +820,7 @@ struct iscsi_portal_group {
spinlock_t tpg_state_lock; spinlock_t tpg_state_lock;
struct se_portal_group tpg_se_tpg; struct se_portal_group tpg_se_tpg;
struct mutex tpg_access_lock; struct mutex tpg_access_lock;
struct mutex np_login_lock; struct semaphore np_login_sem;
struct iscsi_tpg_attrib tpg_attrib; struct iscsi_tpg_attrib tpg_attrib;
struct iscsi_node_auth tpg_demo_auth; struct iscsi_node_auth tpg_demo_auth;
/* Pointer to default list of iSCSI parameters for TPG */ /* Pointer to default list of iSCSI parameters for TPG */
......
...@@ -50,6 +50,7 @@ static struct iscsi_login *iscsi_login_init_conn(struct iscsi_conn *conn) ...@@ -50,6 +50,7 @@ static struct iscsi_login *iscsi_login_init_conn(struct iscsi_conn *conn)
pr_err("Unable to allocate memory for struct iscsi_login.\n"); pr_err("Unable to allocate memory for struct iscsi_login.\n");
return NULL; return NULL;
} }
conn->login = login;
login->conn = conn; login->conn = conn;
login->first_request = 1; login->first_request = 1;
...@@ -684,7 +685,7 @@ static void iscsi_post_login_start_timers(struct iscsi_conn *conn) ...@@ -684,7 +685,7 @@ static void iscsi_post_login_start_timers(struct iscsi_conn *conn)
iscsit_start_nopin_timer(conn); iscsit_start_nopin_timer(conn);
} }
static int iscsi_post_login_handler( int iscsi_post_login_handler(
struct iscsi_np *np, struct iscsi_np *np,
struct iscsi_conn *conn, struct iscsi_conn *conn,
u8 zero_tsih) u8 zero_tsih)
...@@ -1124,6 +1125,77 @@ iscsit_conn_set_transport(struct iscsi_conn *conn, struct iscsit_transport *t) ...@@ -1124,6 +1125,77 @@ iscsit_conn_set_transport(struct iscsi_conn *conn, struct iscsit_transport *t)
return 0; return 0;
} }
void iscsi_target_login_sess_out(struct iscsi_conn *conn,
struct iscsi_np *np, bool zero_tsih, bool new_sess)
{
if (new_sess == false)
goto old_sess_out;
pr_err("iSCSI Login negotiation failed.\n");
iscsit_collect_login_stats(conn, ISCSI_STATUS_CLS_INITIATOR_ERR,
ISCSI_LOGIN_STATUS_INIT_ERR);
if (!zero_tsih || !conn->sess)
goto old_sess_out;
if (conn->sess->se_sess)
transport_free_session(conn->sess->se_sess);
if (conn->sess->session_index != 0) {
spin_lock_bh(&sess_idr_lock);
idr_remove(&sess_idr, conn->sess->session_index);
spin_unlock_bh(&sess_idr_lock);
}
kfree(conn->sess->sess_ops);
kfree(conn->sess);
old_sess_out:
iscsi_stop_login_thread_timer(np);
/*
* If login negotiation fails check if the Time2Retain timer
* needs to be restarted.
*/
if (!zero_tsih && conn->sess) {
spin_lock_bh(&conn->sess->conn_lock);
if (conn->sess->session_state == TARG_SESS_STATE_FAILED) {
struct se_portal_group *se_tpg =
&ISCSI_TPG_C(conn)->tpg_se_tpg;
atomic_set(&conn->sess->session_continuation, 0);
spin_unlock_bh(&conn->sess->conn_lock);
spin_lock_bh(&se_tpg->session_lock);
iscsit_start_time2retain_handler(conn->sess);
spin_unlock_bh(&se_tpg->session_lock);
} else
spin_unlock_bh(&conn->sess->conn_lock);
iscsit_dec_session_usage_count(conn->sess);
}
if (!IS_ERR(conn->conn_rx_hash.tfm))
crypto_free_hash(conn->conn_rx_hash.tfm);
if (!IS_ERR(conn->conn_tx_hash.tfm))
crypto_free_hash(conn->conn_tx_hash.tfm);
if (conn->conn_cpumask)
free_cpumask_var(conn->conn_cpumask);
kfree(conn->conn_ops);
if (conn->param_list) {
iscsi_release_param_list(conn->param_list);
conn->param_list = NULL;
}
iscsi_target_nego_release(conn);
if (conn->sock) {
sock_release(conn->sock);
conn->sock = NULL;
}
if (conn->conn_transport->iscsit_free_conn)
conn->conn_transport->iscsit_free_conn(conn);
iscsit_put_transport(conn->conn_transport);
kfree(conn);
}
static int __iscsi_target_login_thread(struct iscsi_np *np) static int __iscsi_target_login_thread(struct iscsi_np *np)
{ {
u8 *buffer, zero_tsih = 0; u8 *buffer, zero_tsih = 0;
...@@ -1132,6 +1204,8 @@ static int __iscsi_target_login_thread(struct iscsi_np *np) ...@@ -1132,6 +1204,8 @@ static int __iscsi_target_login_thread(struct iscsi_np *np)
struct iscsi_login *login; struct iscsi_login *login;
struct iscsi_portal_group *tpg = NULL; struct iscsi_portal_group *tpg = NULL;
struct iscsi_login_req *pdu; struct iscsi_login_req *pdu;
struct iscsi_tpg_np *tpg_np;
bool new_sess = false;
flush_signals(current); flush_signals(current);
...@@ -1273,6 +1347,7 @@ static int __iscsi_target_login_thread(struct iscsi_np *np) ...@@ -1273,6 +1347,7 @@ static int __iscsi_target_login_thread(struct iscsi_np *np)
tpg = conn->tpg; tpg = conn->tpg;
goto new_sess_out; goto new_sess_out;
} }
login->zero_tsih = zero_tsih;
tpg = conn->tpg; tpg = conn->tpg;
if (!tpg) { if (!tpg) {
...@@ -1288,7 +1363,8 @@ static int __iscsi_target_login_thread(struct iscsi_np *np) ...@@ -1288,7 +1363,8 @@ static int __iscsi_target_login_thread(struct iscsi_np *np)
goto old_sess_out; goto old_sess_out;
} }
if (iscsi_target_start_negotiation(login, conn) < 0) ret = iscsi_target_start_negotiation(login, conn);
if (ret < 0)
goto new_sess_out; goto new_sess_out;
if (!conn->sess) { if (!conn->sess) {
...@@ -1301,84 +1377,32 @@ static int __iscsi_target_login_thread(struct iscsi_np *np) ...@@ -1301,84 +1377,32 @@ static int __iscsi_target_login_thread(struct iscsi_np *np)
if (signal_pending(current)) if (signal_pending(current))
goto new_sess_out; goto new_sess_out;
ret = iscsi_post_login_handler(np, conn, zero_tsih); if (ret == 1) {
tpg_np = conn->tpg_np;
ret = iscsi_post_login_handler(np, conn, zero_tsih);
if (ret < 0) if (ret < 0)
goto new_sess_out; goto new_sess_out;
iscsit_deaccess_np(np, tpg); iscsit_deaccess_np(np, tpg, tpg_np);
}
tpg = NULL; tpg = NULL;
tpg_np = NULL;
/* Get another socket */ /* Get another socket */
return 1; return 1;
new_sess_out: new_sess_out:
pr_err("iSCSI Login negotiation failed.\n"); new_sess = true;
iscsit_collect_login_stats(conn, ISCSI_STATUS_CLS_INITIATOR_ERR,
ISCSI_LOGIN_STATUS_INIT_ERR);
if (!zero_tsih || !conn->sess)
goto old_sess_out;
if (conn->sess->se_sess)
transport_free_session(conn->sess->se_sess);
if (conn->sess->session_index != 0) {
spin_lock_bh(&sess_idr_lock);
idr_remove(&sess_idr, conn->sess->session_index);
spin_unlock_bh(&sess_idr_lock);
}
kfree(conn->sess->sess_ops);
kfree(conn->sess);
old_sess_out: old_sess_out:
iscsi_stop_login_thread_timer(np); tpg_np = conn->tpg_np;
/* iscsi_target_login_sess_out(conn, np, zero_tsih, new_sess);
* If login negotiation fails check if the Time2Retain timer new_sess = false;
* needs to be restarted.
*/
if (!zero_tsih && conn->sess) {
spin_lock_bh(&conn->sess->conn_lock);
if (conn->sess->session_state == TARG_SESS_STATE_FAILED) {
struct se_portal_group *se_tpg =
&ISCSI_TPG_C(conn)->tpg_se_tpg;
atomic_set(&conn->sess->session_continuation, 0);
spin_unlock_bh(&conn->sess->conn_lock);
spin_lock_bh(&se_tpg->session_lock);
iscsit_start_time2retain_handler(conn->sess);
spin_unlock_bh(&se_tpg->session_lock);
} else
spin_unlock_bh(&conn->sess->conn_lock);
iscsit_dec_session_usage_count(conn->sess);
}
if (!IS_ERR(conn->conn_rx_hash.tfm))
crypto_free_hash(conn->conn_rx_hash.tfm);
if (!IS_ERR(conn->conn_tx_hash.tfm))
crypto_free_hash(conn->conn_tx_hash.tfm);
if (conn->conn_cpumask)
free_cpumask_var(conn->conn_cpumask);
kfree(conn->conn_ops);
if (conn->param_list) {
iscsi_release_param_list(conn->param_list);
conn->param_list = NULL;
}
iscsi_target_nego_release(conn);
if (conn->sock) {
sock_release(conn->sock);
conn->sock = NULL;
}
if (conn->conn_transport->iscsit_free_conn)
conn->conn_transport->iscsit_free_conn(conn);
iscsit_put_transport(conn->conn_transport);
kfree(conn);
if (tpg) { if (tpg) {
iscsit_deaccess_np(np, tpg); iscsit_deaccess_np(np, tpg, tpg_np);
tpg = NULL; tpg = NULL;
tpg_np = NULL;
} }
out: out:
......
...@@ -12,6 +12,9 @@ extern int iscsit_accept_np(struct iscsi_np *, struct iscsi_conn *); ...@@ -12,6 +12,9 @@ extern int iscsit_accept_np(struct iscsi_np *, struct iscsi_conn *);
extern int iscsit_get_login_rx(struct iscsi_conn *, struct iscsi_login *); extern int iscsit_get_login_rx(struct iscsi_conn *, struct iscsi_login *);
extern int iscsit_put_login_tx(struct iscsi_conn *, struct iscsi_login *, u32); extern int iscsit_put_login_tx(struct iscsi_conn *, struct iscsi_login *, u32);
extern void iscsit_free_conn(struct iscsi_np *, struct iscsi_conn *); extern void iscsit_free_conn(struct iscsi_np *, struct iscsi_conn *);
extern int iscsi_post_login_handler(struct iscsi_np *, struct iscsi_conn *, u8);
extern void iscsi_target_login_sess_out(struct iscsi_conn *, struct iscsi_np *,
bool, bool);
extern int iscsi_target_login_thread(void *); extern int iscsi_target_login_thread(void *);
extern int iscsi_login_disable_FIM_keys(struct iscsi_param_list *, struct iscsi_conn *); extern int iscsi_login_disable_FIM_keys(struct iscsi_param_list *, struct iscsi_conn *);
......
...@@ -49,7 +49,7 @@ struct iscsi_portal_group *iscsit_alloc_portal_group(struct iscsi_tiqn *tiqn, u1 ...@@ -49,7 +49,7 @@ struct iscsi_portal_group *iscsit_alloc_portal_group(struct iscsi_tiqn *tiqn, u1
INIT_LIST_HEAD(&tpg->tpg_gnp_list); INIT_LIST_HEAD(&tpg->tpg_gnp_list);
INIT_LIST_HEAD(&tpg->tpg_list); INIT_LIST_HEAD(&tpg->tpg_list);
mutex_init(&tpg->tpg_access_lock); mutex_init(&tpg->tpg_access_lock);
mutex_init(&tpg->np_login_lock); sema_init(&tpg->np_login_sem, 1);
spin_lock_init(&tpg->tpg_state_lock); spin_lock_init(&tpg->tpg_state_lock);
spin_lock_init(&tpg->tpg_np_lock); spin_lock_init(&tpg->tpg_np_lock);
...@@ -175,18 +175,20 @@ void iscsit_put_tpg(struct iscsi_portal_group *tpg) ...@@ -175,18 +175,20 @@ void iscsit_put_tpg(struct iscsi_portal_group *tpg)
static void iscsit_clear_tpg_np_login_thread( static void iscsit_clear_tpg_np_login_thread(
struct iscsi_tpg_np *tpg_np, struct iscsi_tpg_np *tpg_np,
struct iscsi_portal_group *tpg) struct iscsi_portal_group *tpg,
bool shutdown)
{ {
if (!tpg_np->tpg_np) { if (!tpg_np->tpg_np) {
pr_err("struct iscsi_tpg_np->tpg_np is NULL!\n"); pr_err("struct iscsi_tpg_np->tpg_np is NULL!\n");
return; return;
} }
iscsit_reset_np_thread(tpg_np->tpg_np, tpg_np, tpg); iscsit_reset_np_thread(tpg_np->tpg_np, tpg_np, tpg, shutdown);
} }
void iscsit_clear_tpg_np_login_threads( void iscsit_clear_tpg_np_login_threads(
struct iscsi_portal_group *tpg) struct iscsi_portal_group *tpg,
bool shutdown)
{ {
struct iscsi_tpg_np *tpg_np; struct iscsi_tpg_np *tpg_np;
...@@ -197,7 +199,7 @@ void iscsit_clear_tpg_np_login_threads( ...@@ -197,7 +199,7 @@ void iscsit_clear_tpg_np_login_threads(
continue; continue;
} }
spin_unlock(&tpg->tpg_np_lock); spin_unlock(&tpg->tpg_np_lock);
iscsit_clear_tpg_np_login_thread(tpg_np, tpg); iscsit_clear_tpg_np_login_thread(tpg_np, tpg, shutdown);
spin_lock(&tpg->tpg_np_lock); spin_lock(&tpg->tpg_np_lock);
} }
spin_unlock(&tpg->tpg_np_lock); spin_unlock(&tpg->tpg_np_lock);
...@@ -268,6 +270,8 @@ int iscsit_tpg_del_portal_group( ...@@ -268,6 +270,8 @@ int iscsit_tpg_del_portal_group(
tpg->tpg_state = TPG_STATE_INACTIVE; tpg->tpg_state = TPG_STATE_INACTIVE;
spin_unlock(&tpg->tpg_state_lock); spin_unlock(&tpg->tpg_state_lock);
iscsit_clear_tpg_np_login_threads(tpg, true);
if (iscsit_release_sessions_for_tpg(tpg, force) < 0) { if (iscsit_release_sessions_for_tpg(tpg, force) < 0) {
pr_err("Unable to delete iSCSI Target Portal Group:" pr_err("Unable to delete iSCSI Target Portal Group:"
" %hu while active sessions exist, and force=0\n", " %hu while active sessions exist, and force=0\n",
...@@ -368,7 +372,7 @@ int iscsit_tpg_disable_portal_group(struct iscsi_portal_group *tpg, int force) ...@@ -368,7 +372,7 @@ int iscsit_tpg_disable_portal_group(struct iscsi_portal_group *tpg, int force)
tpg->tpg_state = TPG_STATE_INACTIVE; tpg->tpg_state = TPG_STATE_INACTIVE;
spin_unlock(&tpg->tpg_state_lock); spin_unlock(&tpg->tpg_state_lock);
iscsit_clear_tpg_np_login_threads(tpg); iscsit_clear_tpg_np_login_threads(tpg, false);
if (iscsit_release_sessions_for_tpg(tpg, force) < 0) { if (iscsit_release_sessions_for_tpg(tpg, force) < 0) {
spin_lock(&tpg->tpg_state_lock); spin_lock(&tpg->tpg_state_lock);
...@@ -520,7 +524,7 @@ static int iscsit_tpg_release_np( ...@@ -520,7 +524,7 @@ static int iscsit_tpg_release_np(
struct iscsi_portal_group *tpg, struct iscsi_portal_group *tpg,
struct iscsi_np *np) struct iscsi_np *np)
{ {
iscsit_clear_tpg_np_login_thread(tpg_np, tpg); iscsit_clear_tpg_np_login_thread(tpg_np, tpg, true);
pr_debug("CORE[%s] - Removed Network Portal: %s:%hu,%hu on %s\n", pr_debug("CORE[%s] - Removed Network Portal: %s:%hu,%hu on %s\n",
tpg->tpg_tiqn->tiqn, np->np_ip, np->np_port, tpg->tpgt, tpg->tpg_tiqn->tiqn, np->np_ip, np->np_port, tpg->tpgt,
......
...@@ -8,7 +8,7 @@ extern struct iscsi_portal_group *iscsit_get_tpg_from_np(struct iscsi_tiqn *, ...@@ -8,7 +8,7 @@ extern struct iscsi_portal_group *iscsit_get_tpg_from_np(struct iscsi_tiqn *,
struct iscsi_np *); struct iscsi_np *);
extern int iscsit_get_tpg(struct iscsi_portal_group *); extern int iscsit_get_tpg(struct iscsi_portal_group *);
extern void iscsit_put_tpg(struct iscsi_portal_group *); extern void iscsit_put_tpg(struct iscsi_portal_group *);
extern void iscsit_clear_tpg_np_login_threads(struct iscsi_portal_group *); extern void iscsit_clear_tpg_np_login_threads(struct iscsi_portal_group *, bool);
extern void iscsit_tpg_dump_params(struct iscsi_portal_group *); extern void iscsit_tpg_dump_params(struct iscsi_portal_group *);
extern int iscsit_tpg_add_portal_group(struct iscsi_tiqn *, struct iscsi_portal_group *); extern int iscsit_tpg_add_portal_group(struct iscsi_tiqn *, struct iscsi_portal_group *);
extern int iscsit_tpg_del_portal_group(struct iscsi_tiqn *, struct iscsi_portal_group *, extern int iscsit_tpg_del_portal_group(struct iscsi_tiqn *, struct iscsi_portal_group *,
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册