This separation will allow for future removal of the current listen-while-disabled behaviour. Signed-off-by: David Disseldorp <ddiss@xxxxxxx> --- drivers/target/iscsi/iscsi_target.c | 53 +++++++++++++++++++++------------ drivers/target/iscsi/iscsi_target.h | 1 + drivers/target/iscsi/iscsi_target_tpg.c | 9 ++++++ 3 files changed, 44 insertions(+), 19 deletions(-) diff --git a/drivers/target/iscsi/iscsi_target.c b/drivers/target/iscsi/iscsi_target.c index faaeef2..dc0110c 100644 --- a/drivers/target/iscsi/iscsi_target.c +++ b/drivers/target/iscsi/iscsi_target.c @@ -347,7 +347,6 @@ struct iscsi_np *iscsit_add_np( struct sockaddr_in *sock_in; struct sockaddr_in6 *sock_in6; struct iscsi_np *np; - int ret; struct iscsit_transport *t; mutex_lock(&np_lock); @@ -401,23 +400,6 @@ struct iscsi_np *iscsit_add_np( init_completion(&np->np_restart_comp); INIT_LIST_HEAD(&np->np_list); - ret = iscsi_target_setup_login_socket(np, sockaddr); - if (ret != 0) { - iscsit_put_transport(np->np_transport); - kfree(np); - mutex_unlock(&np_lock); - return ERR_PTR(ret); - } - - np->np_thread = kthread_run(iscsi_target_login_thread, np, "iscsi_np"); - if (IS_ERR(np->np_thread)) { - pr_err("Unable to create kthread: iscsi_np\n"); - ret = PTR_ERR(np->np_thread); - iscsit_put_transport(np->np_transport); - kfree(np); - mutex_unlock(&np_lock); - return ERR_PTR(ret); - } /* * Increment the np_exports reference count now to prevent * iscsit_del_np() below from being run while a new call to @@ -426,7 +408,8 @@ 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; + /* np_thread is started later, depending on TPGT enable attribute */ + np->np_thread_state = ISCSI_NP_THREAD_INACTIVE; list_add_tail(&np->np_list, &g_np_list); mutex_unlock(&np_lock); @@ -467,6 +450,38 @@ int iscsit_reset_np_thread( return 0; } +int iscsit_enable_np_thread( + struct iscsi_np *np) +{ + int ret; + + spin_lock_bh(&np->np_thread_lock); + if (np->np_thread_state == ISCSI_NP_THREAD_ACTIVE) { + pr_info("iscsi NP already enabled\n"); + spin_unlock_bh(&np->np_thread_lock); + return 0; + } + ret = iscsi_target_setup_login_socket(np, &np->np_sockaddr); + if (ret != 0) { + spin_unlock_bh(&np->np_thread_lock); + return ret; + } + + spin_unlock_bh(&np->np_thread_lock); + + np->np_thread = kthread_run(iscsi_target_login_thread, np, "iscsi_np"); + if (IS_ERR(np->np_thread)) { + np->np_transport->iscsit_free_np(np); + pr_err("Unable to create kthread: iscsi_np\n"); + ret = PTR_ERR(np->np_thread); + return ret; + } + + /* thread sets np_thread_state = ISCSI_NP_THREAD_ACTIVE on startup */ + + return 0; +} + static void iscsit_free_np(struct iscsi_np *np) { if (!np->np_socket) diff --git a/drivers/target/iscsi/iscsi_target.h b/drivers/target/iscsi/iscsi_target.h index 7d0f9c0..398a23d 100644 --- a/drivers/target/iscsi/iscsi_target.h +++ b/drivers/target/iscsi/iscsi_target.h @@ -16,6 +16,7 @@ extern struct iscsi_np *iscsit_add_np(struct __kernel_sockaddr_storage *, char *, int); extern int iscsit_reset_np_thread(struct iscsi_np *, struct iscsi_tpg_np *, struct iscsi_portal_group *, bool); +int iscsit_enable_np_thread(struct iscsi_np *); extern int iscsit_del_np(struct iscsi_np *); extern int iscsit_reject_cmd(struct iscsi_cmd *cmd, u8, unsigned char *); extern void iscsit_set_unsoliticed_dataout(struct iscsi_cmd *); diff --git a/drivers/target/iscsi/iscsi_target_tpg.c b/drivers/target/iscsi/iscsi_target_tpg.c index 91c2e7f..f2dc9b0 100644 --- a/drivers/target/iscsi/iscsi_target_tpg.c +++ b/drivers/target/iscsi/iscsi_target_tpg.c @@ -467,6 +467,7 @@ struct iscsi_tpg_np *iscsit_tpg_add_network_portal( { struct iscsi_np *np; struct iscsi_tpg_np *tpg_np; + int ret; if (!tpg_np_parent) { if (iscsit_tpg_check_network_portal(tpg->tpg_tiqn, sockaddr, @@ -491,6 +492,14 @@ struct iscsi_tpg_np *iscsit_tpg_add_network_portal( return ERR_CAST(np); } + ret = iscsit_enable_np_thread(np); + if (ret < 0) { + pr_err("Failed to enable network portal\n"); + iscsit_del_np(np); + kfree(tpg_np); + return ERR_PTR(ret); + } + INIT_LIST_HEAD(&tpg_np->tpg_np_list); INIT_LIST_HEAD(&tpg_np->tpg_np_child_list); INIT_LIST_HEAD(&tpg_np->tpg_np_parent_list); -- 2.1.4 -- To unsubscribe from this list: send the line "unsubscribe target-devel" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html