diff options
Diffstat (limited to 'drivers/target/iscsi/iscsi_target_tpg.c')
-rw-r--r-- | drivers/target/iscsi/iscsi_target_tpg.c | 39 |
1 files changed, 39 insertions, 0 deletions
diff --git a/drivers/target/iscsi/iscsi_target_tpg.c b/drivers/target/iscsi/iscsi_target_tpg.c index de9ea32b6104..ee8f8c66248d 100644 --- a/drivers/target/iscsi/iscsi_target_tpg.c +++ b/drivers/target/iscsi/iscsi_target_tpg.c @@ -422,6 +422,35 @@ struct iscsi_tpg_np *iscsit_tpg_locate_child_np( return NULL; } +static bool iscsit_tpg_check_network_portal( + struct iscsi_tiqn *tiqn, + struct __kernel_sockaddr_storage *sockaddr, + int network_transport) +{ + struct iscsi_portal_group *tpg; + struct iscsi_tpg_np *tpg_np; + struct iscsi_np *np; + bool match = false; + + spin_lock(&tiqn->tiqn_tpg_lock); + list_for_each_entry(tpg, &tiqn->tiqn_tpg_list, tpg_list) { + + spin_lock(&tpg->tpg_np_lock); + list_for_each_entry(tpg_np, &tpg->tpg_gnp_list, tpg_np_list) { + np = tpg_np->tpg_np; + + match = iscsit_check_np_match(sockaddr, np, + network_transport); + if (match == true) + break; + } + spin_unlock(&tpg->tpg_np_lock); + } + spin_unlock(&tiqn->tiqn_tpg_lock); + + return match; +} + struct iscsi_tpg_np *iscsit_tpg_add_network_portal( struct iscsi_portal_group *tpg, struct __kernel_sockaddr_storage *sockaddr, @@ -432,6 +461,16 @@ struct iscsi_tpg_np *iscsit_tpg_add_network_portal( struct iscsi_np *np; struct iscsi_tpg_np *tpg_np; + if (!tpg_np_parent) { + if (iscsit_tpg_check_network_portal(tpg->tpg_tiqn, sockaddr, + network_transport) == true) { + pr_err("Network Portal: %s already exists on a" + " different TPG on %s\n", ip_str, + tpg->tpg_tiqn->tiqn); + return ERR_PTR(-EEXIST); + } + } + tpg_np = kzalloc(sizeof(struct iscsi_tpg_np), GFP_KERNEL); if (!tpg_np) { pr_err("Unable to allocate memory for" |