Skip to content

Commit 2bce1a6

Browse files
Bart Van Asschedledford
authored andcommitted
IB/srpt: Accept GUIDs as port names
Port and ACL information must be configured before an initiator logs in. Make it possible to configure this information before a subnet prefix has been assigned to a port by not only accepting GIDs as target port and initiator port names but by also accepting port GUIDs. Add a 'priv' member to struct se_wwn to allow target drivers to associate their own data with struct se_wwn. Reported-by: Doug Ledford <[email protected]> References: http://www.spinics.net/lists/linux-rdma/msg39505.html Signed-off-by: Bart Van Assche <[email protected]> Cc: Christoph Hellwig <[email protected]> Cc: Nicholas Bellinger <[email protected]> Signed-off-by: Doug Ledford <[email protected]>
1 parent a3dd3a4 commit 2bce1a6

File tree

4 files changed

+98
-61
lines changed

4 files changed

+98
-61
lines changed

drivers/infiniband/ulp/srpt/ib_srpt.c

Lines changed: 83 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -500,6 +500,7 @@ static int srpt_refresh_port(struct srpt_port *sport)
500500
struct ib_mad_reg_req reg_req;
501501
struct ib_port_modify port_modify;
502502
struct ib_port_attr port_attr;
503+
__be16 *guid;
503504
int ret;
504505

505506
memset(&port_modify, 0, sizeof(port_modify));
@@ -522,10 +523,17 @@ static int srpt_refresh_port(struct srpt_port *sport)
522523
if (ret)
523524
goto err_query_port;
524525

526+
sport->port_guid_wwn.priv = sport;
527+
guid = (__be16 *)&sport->gid.global.interface_id;
525528
snprintf(sport->port_guid, sizeof(sport->port_guid),
526-
"0x%016llx%016llx",
527-
be64_to_cpu(sport->gid.global.subnet_prefix),
528-
be64_to_cpu(sport->gid.global.interface_id));
529+
"%04x:%04x:%04x:%04x",
530+
be16_to_cpu(guid[0]), be16_to_cpu(guid[1]),
531+
be16_to_cpu(guid[2]), be16_to_cpu(guid[3]));
532+
sport->port_gid_wwn.priv = sport;
533+
snprintf(sport->port_gid, sizeof(sport->port_gid),
534+
"0x%016llx%016llx",
535+
be64_to_cpu(sport->gid.global.subnet_prefix),
536+
be64_to_cpu(sport->gid.global.interface_id));
529537

530538
if (!sport->mad_agent) {
531539
memset(&reg_req, 0, sizeof(reg_req));
@@ -1838,6 +1846,7 @@ static int srpt_cm_req_recv(struct ib_cm_id *cm_id,
18381846
struct srp_login_rej *rej;
18391847
struct ib_cm_rep_param *rep_param;
18401848
struct srpt_rdma_ch *ch, *tmp_ch;
1849+
__be16 *guid;
18411850
u32 it_iu_len;
18421851
int i, ret = 0;
18431852

@@ -1983,26 +1992,30 @@ static int srpt_cm_req_recv(struct ib_cm_id *cm_id,
19831992
goto destroy_ib;
19841993
}
19851994

1986-
/*
1987-
* Use the initator port identifier as the session name, when
1988-
* checking against se_node_acl->initiatorname[] this can be
1989-
* with or without preceeding '0x'.
1990-
*/
1995+
guid = (__be16 *)&param->primary_path->sgid.global.interface_id;
1996+
snprintf(ch->ini_guid, sizeof(ch->ini_guid), "%04x:%04x:%04x:%04x",
1997+
be16_to_cpu(guid[0]), be16_to_cpu(guid[1]),
1998+
be16_to_cpu(guid[2]), be16_to_cpu(guid[3]));
19911999
snprintf(ch->sess_name, sizeof(ch->sess_name), "0x%016llx%016llx",
19922000
be64_to_cpu(*(__be64 *)ch->i_port_id),
19932001
be64_to_cpu(*(__be64 *)(ch->i_port_id + 8)));
19942002

19952003
pr_debug("registering session %s\n", ch->sess_name);
19962004

1997-
ch->sess = target_alloc_session(&sport->port_tpg_1, 0, 0,
2005+
if (sport->port_guid_tpg.se_tpg_wwn)
2006+
ch->sess = target_alloc_session(&sport->port_guid_tpg, 0, 0,
2007+
TARGET_PROT_NORMAL,
2008+
ch->ini_guid, ch, NULL);
2009+
if (sport->port_gid_tpg.se_tpg_wwn && IS_ERR_OR_NULL(ch->sess))
2010+
ch->sess = target_alloc_session(&sport->port_gid_tpg, 0, 0,
19982011
TARGET_PROT_NORMAL, ch->sess_name, ch,
19992012
NULL);
20002013
/* Retry without leading "0x" */
2001-
if (IS_ERR(ch->sess))
2002-
ch->sess = target_alloc_session(&sport->port_tpg_1, 0, 0,
2014+
if (sport->port_gid_tpg.se_tpg_wwn && IS_ERR_OR_NULL(ch->sess))
2015+
ch->sess = target_alloc_session(&sport->port_gid_tpg, 0, 0,
20032016
TARGET_PROT_NORMAL,
20042017
ch->sess_name + 2, ch, NULL);
2005-
if (IS_ERR(ch->sess)) {
2018+
if (IS_ERR_OR_NULL(ch->sess)) {
20062019
pr_info("Rejected login because no ACL has been configured yet for initiator %s.\n",
20072020
ch->sess_name);
20082021
rej->reason = cpu_to_be32((PTR_ERR(ch->sess) == -ENOMEM) ?
@@ -2420,7 +2433,7 @@ static int srpt_release_sdev(struct srpt_device *sdev)
24202433
return 0;
24212434
}
24222435

2423-
static struct srpt_port *__srpt_lookup_port(const char *name)
2436+
static struct se_wwn *__srpt_lookup_wwn(const char *name)
24242437
{
24252438
struct ib_device *dev;
24262439
struct srpt_device *sdev;
@@ -2435,23 +2448,25 @@ static struct srpt_port *__srpt_lookup_port(const char *name)
24352448
for (i = 0; i < dev->phys_port_cnt; i++) {
24362449
sport = &sdev->port[i];
24372450

2438-
if (!strcmp(sport->port_guid, name))
2439-
return sport;
2451+
if (strcmp(sport->port_guid, name) == 0)
2452+
return &sport->port_guid_wwn;
2453+
if (strcmp(sport->port_gid, name) == 0)
2454+
return &sport->port_gid_wwn;
24402455
}
24412456
}
24422457

24432458
return NULL;
24442459
}
24452460

2446-
static struct srpt_port *srpt_lookup_port(const char *name)
2461+
static struct se_wwn *srpt_lookup_wwn(const char *name)
24472462
{
2448-
struct srpt_port *sport;
2463+
struct se_wwn *wwn;
24492464

24502465
spin_lock(&srpt_dev_lock);
2451-
sport = __srpt_lookup_port(name);
2466+
wwn = __srpt_lookup_wwn(name);
24522467
spin_unlock(&srpt_dev_lock);
24532468

2454-
return sport;
2469+
return wwn;
24552470
}
24562471

24572472
/**
@@ -2643,11 +2658,19 @@ static char *srpt_get_fabric_name(void)
26432658
return "srpt";
26442659
}
26452660

2661+
static struct srpt_port *srpt_tpg_to_sport(struct se_portal_group *tpg)
2662+
{
2663+
return tpg->se_tpg_wwn->priv;
2664+
}
2665+
26462666
static char *srpt_get_fabric_wwn(struct se_portal_group *tpg)
26472667
{
2648-
struct srpt_port *sport = container_of(tpg, struct srpt_port, port_tpg_1);
2668+
struct srpt_port *sport = srpt_tpg_to_sport(tpg);
26492669

2650-
return sport->port_guid;
2670+
WARN_ON_ONCE(tpg != &sport->port_guid_tpg &&
2671+
tpg != &sport->port_gid_tpg);
2672+
return tpg == &sport->port_guid_tpg ? sport->port_guid :
2673+
sport->port_gid;
26512674
}
26522675

26532676
static u16 srpt_get_tag(struct se_portal_group *tpg)
@@ -2737,6 +2760,19 @@ static int srpt_get_tcm_cmd_state(struct se_cmd *se_cmd)
27372760
return srpt_get_cmd_state(ioctx);
27382761
}
27392762

2763+
static int srpt_parse_guid(u64 *guid, const char *name)
2764+
{
2765+
u16 w[4];
2766+
int ret = -EINVAL;
2767+
2768+
if (sscanf(name, "%hx:%hx:%hx:%hx", &w[0], &w[1], &w[2], &w[3]) != 4)
2769+
goto out;
2770+
*guid = get_unaligned_be64(w);
2771+
ret = 0;
2772+
out:
2773+
return ret;
2774+
}
2775+
27402776
/**
27412777
* srpt_parse_i_port_id() - Parse an initiator port ID.
27422778
* @name: ASCII representation of a 128-bit initiator port ID.
@@ -2772,20 +2808,23 @@ static int srpt_parse_i_port_id(u8 i_port_id[16], const char *name)
27722808
*/
27732809
static int srpt_init_nodeacl(struct se_node_acl *se_nacl, const char *name)
27742810
{
2811+
u64 guid;
27752812
u8 i_port_id[16];
2813+
int ret;
27762814

2777-
if (srpt_parse_i_port_id(i_port_id, name) < 0) {
2815+
ret = srpt_parse_guid(&guid, name);
2816+
if (ret < 0)
2817+
ret = srpt_parse_i_port_id(i_port_id, name);
2818+
if (ret < 0)
27782819
pr_err("invalid initiator port ID %s\n", name);
2779-
return -EINVAL;
2780-
}
2781-
return 0;
2820+
return ret;
27822821
}
27832822

27842823
static ssize_t srpt_tpg_attrib_srp_max_rdma_size_show(struct config_item *item,
27852824
char *page)
27862825
{
27872826
struct se_portal_group *se_tpg = attrib_to_tpg(item);
2788-
struct srpt_port *sport = container_of(se_tpg, struct srpt_port, port_tpg_1);
2827+
struct srpt_port *sport = srpt_tpg_to_sport(se_tpg);
27892828

27902829
return sprintf(page, "%u\n", sport->port_attrib.srp_max_rdma_size);
27912830
}
@@ -2794,7 +2833,7 @@ static ssize_t srpt_tpg_attrib_srp_max_rdma_size_store(struct config_item *item,
27942833
const char *page, size_t count)
27952834
{
27962835
struct se_portal_group *se_tpg = attrib_to_tpg(item);
2797-
struct srpt_port *sport = container_of(se_tpg, struct srpt_port, port_tpg_1);
2836+
struct srpt_port *sport = srpt_tpg_to_sport(se_tpg);
27982837
unsigned long val;
27992838
int ret;
28002839

@@ -2822,7 +2861,7 @@ static ssize_t srpt_tpg_attrib_srp_max_rsp_size_show(struct config_item *item,
28222861
char *page)
28232862
{
28242863
struct se_portal_group *se_tpg = attrib_to_tpg(item);
2825-
struct srpt_port *sport = container_of(se_tpg, struct srpt_port, port_tpg_1);
2864+
struct srpt_port *sport = srpt_tpg_to_sport(se_tpg);
28262865

28272866
return sprintf(page, "%u\n", sport->port_attrib.srp_max_rsp_size);
28282867
}
@@ -2831,7 +2870,7 @@ static ssize_t srpt_tpg_attrib_srp_max_rsp_size_store(struct config_item *item,
28312870
const char *page, size_t count)
28322871
{
28332872
struct se_portal_group *se_tpg = attrib_to_tpg(item);
2834-
struct srpt_port *sport = container_of(se_tpg, struct srpt_port, port_tpg_1);
2873+
struct srpt_port *sport = srpt_tpg_to_sport(se_tpg);
28352874
unsigned long val;
28362875
int ret;
28372876

@@ -2859,7 +2898,7 @@ static ssize_t srpt_tpg_attrib_srp_sq_size_show(struct config_item *item,
28592898
char *page)
28602899
{
28612900
struct se_portal_group *se_tpg = attrib_to_tpg(item);
2862-
struct srpt_port *sport = container_of(se_tpg, struct srpt_port, port_tpg_1);
2901+
struct srpt_port *sport = srpt_tpg_to_sport(se_tpg);
28632902

28642903
return sprintf(page, "%u\n", sport->port_attrib.srp_sq_size);
28652904
}
@@ -2868,7 +2907,7 @@ static ssize_t srpt_tpg_attrib_srp_sq_size_store(struct config_item *item,
28682907
const char *page, size_t count)
28692908
{
28702909
struct se_portal_group *se_tpg = attrib_to_tpg(item);
2871-
struct srpt_port *sport = container_of(se_tpg, struct srpt_port, port_tpg_1);
2910+
struct srpt_port *sport = srpt_tpg_to_sport(se_tpg);
28722911
unsigned long val;
28732912
int ret;
28742913

@@ -2906,7 +2945,7 @@ static struct configfs_attribute *srpt_tpg_attrib_attrs[] = {
29062945
static ssize_t srpt_tpg_enable_show(struct config_item *item, char *page)
29072946
{
29082947
struct se_portal_group *se_tpg = to_tpg(item);
2909-
struct srpt_port *sport = container_of(se_tpg, struct srpt_port, port_tpg_1);
2948+
struct srpt_port *sport = srpt_tpg_to_sport(se_tpg);
29102949

29112950
return snprintf(page, PAGE_SIZE, "%d\n", (sport->enabled) ? 1: 0);
29122951
}
@@ -2915,7 +2954,7 @@ static ssize_t srpt_tpg_enable_store(struct config_item *item,
29152954
const char *page, size_t count)
29162955
{
29172956
struct se_portal_group *se_tpg = to_tpg(item);
2918-
struct srpt_port *sport = container_of(se_tpg, struct srpt_port, port_tpg_1);
2957+
struct srpt_port *sport = srpt_tpg_to_sport(se_tpg);
29192958
struct srpt_device *sdev = sport->sdev;
29202959
struct srpt_rdma_ch *ch;
29212960
unsigned long tmp;
@@ -2967,15 +3006,19 @@ static struct se_portal_group *srpt_make_tpg(struct se_wwn *wwn,
29673006
struct config_group *group,
29683007
const char *name)
29693008
{
2970-
struct srpt_port *sport = container_of(wwn, struct srpt_port, port_wwn);
3009+
struct srpt_port *sport = wwn->priv;
3010+
static struct se_portal_group *tpg;
29713011
int res;
29723012

2973-
/* Initialize sport->port_wwn and sport->port_tpg_1 */
2974-
res = core_tpg_register(&sport->port_wwn, &sport->port_tpg_1, SCSI_PROTOCOL_SRP);
3013+
WARN_ON_ONCE(wwn != &sport->port_guid_wwn &&
3014+
wwn != &sport->port_gid_wwn);
3015+
tpg = wwn == &sport->port_guid_wwn ? &sport->port_guid_tpg :
3016+
&sport->port_gid_tpg;
3017+
res = core_tpg_register(wwn, tpg, SCSI_PROTOCOL_SRP);
29753018
if (res)
29763019
return ERR_PTR(res);
29773020

2978-
return &sport->port_tpg_1;
3021+
return tpg;
29793022
}
29803023

29813024
/**
@@ -2984,11 +3027,10 @@ static struct se_portal_group *srpt_make_tpg(struct se_wwn *wwn,
29843027
*/
29853028
static void srpt_drop_tpg(struct se_portal_group *tpg)
29863029
{
2987-
struct srpt_port *sport = container_of(tpg,
2988-
struct srpt_port, port_tpg_1);
3030+
struct srpt_port *sport = srpt_tpg_to_sport(tpg);
29893031

29903032
sport->enabled = false;
2991-
core_tpg_deregister(&sport->port_tpg_1);
3033+
core_tpg_deregister(tpg);
29923034
}
29933035

29943036
/**
@@ -2999,19 +3041,7 @@ static struct se_wwn *srpt_make_tport(struct target_fabric_configfs *tf,
29993041
struct config_group *group,
30003042
const char *name)
30013043
{
3002-
struct srpt_port *sport;
3003-
int ret;
3004-
3005-
sport = srpt_lookup_port(name);
3006-
pr_debug("make_tport(%s)\n", name);
3007-
ret = -EINVAL;
3008-
if (!sport)
3009-
goto err;
3010-
3011-
return &sport->port_wwn;
3012-
3013-
err:
3014-
return ERR_PTR(ret);
3044+
return srpt_lookup_wwn(name) ? : ERR_PTR(-EINVAL);
30153045
}
30163046

30173047
/**
@@ -3020,9 +3050,6 @@ static struct se_wwn *srpt_make_tport(struct target_fabric_configfs *tf,
30203050
*/
30213051
static void srpt_drop_tport(struct se_wwn *wwn)
30223052
{
3023-
struct srpt_port *sport = container_of(wwn, struct srpt_port, port_wwn);
3024-
3025-
pr_debug("drop_tport(%s\n", config_item_name(&sport->port_wwn.wwn_group.cg_item));
30263053
}
30273054

30283055
static ssize_t srpt_wwn_version_show(struct config_item *item, char *buf)

drivers/infiniband/ulp/srpt/ib_srpt.h

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -258,6 +258,7 @@ enum rdma_ch_state {
258258
* against concurrent modification by the cm_id spinlock.
259259
* @sess: Session information associated with this SRP channel.
260260
* @sess_name: Session name.
261+
* @ini_guid: Initiator port GUID.
261262
* @release_work: Allows scheduling of srpt_release_channel().
262263
* @release_done: Enables waiting for srpt_release_channel() completion.
263264
*/
@@ -284,6 +285,7 @@ struct srpt_rdma_ch {
284285
struct list_head cmd_wait_list;
285286
struct se_session *sess;
286287
u8 sess_name[36];
288+
u8 ini_guid[24];
287289
struct work_struct release_work;
288290
struct completion *release_done;
289291
};
@@ -306,28 +308,34 @@ struct srpt_port_attrib {
306308
* @mad_agent: per-port management datagram processing information.
307309
* @enabled: Whether or not this target port is enabled.
308310
* @port_guid: ASCII representation of Port GUID
311+
* @port_gid: ASCII representation of Port GID
309312
* @port: one-based port number.
310313
* @sm_lid: cached value of the port's sm_lid.
311314
* @lid: cached value of the port's lid.
312315
* @gid: cached value of the port's gid.
313316
* @port_acl_lock spinlock for port_acl_list:
314317
* @work: work structure for refreshing the aforementioned cached values.
315-
* @port_tpg_1 Target portal group = 1 data.
316-
* @port_wwn: Target core WWN data.
318+
* @port_guid_tpg: TPG associated with target port GUID.
319+
* @port_guid_wwn: WWN associated with target port GUID.
320+
* @port_gid_tpg: TPG associated with target port GID.
321+
* @port_gid_wwn: WWN associated with target port GID.
317322
* @port_acl_list: Head of the list with all node ACLs for this port.
318323
*/
319324
struct srpt_port {
320325
struct srpt_device *sdev;
321326
struct ib_mad_agent *mad_agent;
322327
bool enabled;
323-
u8 port_guid[64];
328+
u8 port_guid[24];
329+
u8 port_gid[64];
324330
u8 port;
325331
u16 sm_lid;
326332
u16 lid;
327333
union ib_gid gid;
328334
struct work_struct work;
329-
struct se_portal_group port_tpg_1;
330-
struct se_wwn port_wwn;
335+
struct se_portal_group port_guid_tpg;
336+
struct se_wwn port_guid_wwn;
337+
struct se_portal_group port_gid_tpg;
338+
struct se_wwn port_gid_wwn;
331339
struct srpt_port_attrib port_attrib;
332340
};
333341

drivers/target/target_core_tpg.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -448,6 +448,7 @@ static void core_tpg_lun_ref_release(struct percpu_ref *ref)
448448
complete(&lun->lun_ref_comp);
449449
}
450450

451+
/* Does not change se_wwn->priv. */
451452
int core_tpg_register(
452453
struct se_wwn *se_wwn,
453454
struct se_portal_group *se_tpg,

include/target/target_core_base.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -909,6 +909,7 @@ static inline struct se_portal_group *param_to_tpg(struct config_item *item)
909909

910910
struct se_wwn {
911911
struct target_fabric_configfs *wwn_tf;
912+
void *priv;
912913
struct config_group wwn_group;
913914
struct config_group fabric_stat_group;
914915
};

0 commit comments

Comments
 (0)