@@ -565,18 +565,12 @@ static int srpt_refresh_port(struct srpt_port *sport)
565
565
if (ret )
566
566
return ret ;
567
567
568
- sport -> port_guid_id .wwn .priv = sport ;
569
568
srpt_format_guid (sport -> guid_name , ARRAY_SIZE (sport -> guid_name ),
570
569
& sport -> gid .global .interface_id );
571
- memcpy (sport -> port_guid_id .name , sport -> guid_name ,
572
- ARRAY_SIZE (sport -> guid_name ));
573
- sport -> port_gid_id .wwn .priv = sport ;
574
570
snprintf (sport -> gid_name , ARRAY_SIZE (sport -> gid_name ),
575
571
"0x%016llx%016llx" ,
576
572
be64_to_cpu (sport -> gid .global .subnet_prefix ),
577
573
be64_to_cpu (sport -> gid .global .interface_id ));
578
- memcpy (sport -> port_gid_id .name , sport -> gid_name ,
579
- ARRAY_SIZE (sport -> gid_name ));
580
574
581
575
if (rdma_protocol_iwarp (sport -> sdev -> device , sport -> port ))
582
576
return 0 ;
@@ -2317,31 +2311,35 @@ static int srpt_cm_req_recv(struct srpt_device *const sdev,
2317
2311
tag_num = ch -> rq_size ;
2318
2312
tag_size = 1 ; /* ib_srpt does not use se_sess->sess_cmd_map */
2319
2313
2320
- mutex_lock (& sport -> port_guid_id .mutex );
2321
- list_for_each_entry (stpg , & sport -> port_guid_id .tpg_list , entry ) {
2322
- if (!IS_ERR_OR_NULL (ch -> sess ))
2323
- break ;
2324
- ch -> sess = target_setup_session (& stpg -> tpg , tag_num ,
2314
+ if (sport -> guid_id ) {
2315
+ mutex_lock (& sport -> guid_id -> mutex );
2316
+ list_for_each_entry (stpg , & sport -> guid_id -> tpg_list , entry ) {
2317
+ if (!IS_ERR_OR_NULL (ch -> sess ))
2318
+ break ;
2319
+ ch -> sess = target_setup_session (& stpg -> tpg , tag_num ,
2325
2320
tag_size , TARGET_PROT_NORMAL ,
2326
2321
ch -> sess_name , ch , NULL );
2322
+ }
2323
+ mutex_unlock (& sport -> guid_id -> mutex );
2327
2324
}
2328
- mutex_unlock (& sport -> port_guid_id .mutex );
2329
2325
2330
- mutex_lock (& sport -> port_gid_id .mutex );
2331
- list_for_each_entry (stpg , & sport -> port_gid_id .tpg_list , entry ) {
2332
- if (!IS_ERR_OR_NULL (ch -> sess ))
2333
- break ;
2334
- ch -> sess = target_setup_session (& stpg -> tpg , tag_num ,
2326
+ if (sport -> gid_id ) {
2327
+ mutex_lock (& sport -> gid_id -> mutex );
2328
+ list_for_each_entry (stpg , & sport -> gid_id -> tpg_list , entry ) {
2329
+ if (!IS_ERR_OR_NULL (ch -> sess ))
2330
+ break ;
2331
+ ch -> sess = target_setup_session (& stpg -> tpg , tag_num ,
2335
2332
tag_size , TARGET_PROT_NORMAL , i_port_id ,
2336
2333
ch , NULL );
2337
- if (!IS_ERR_OR_NULL (ch -> sess ))
2338
- break ;
2339
- /* Retry without leading "0x" */
2340
- ch -> sess = target_setup_session (& stpg -> tpg , tag_num ,
2334
+ if (!IS_ERR_OR_NULL (ch -> sess ))
2335
+ break ;
2336
+ /* Retry without leading "0x" */
2337
+ ch -> sess = target_setup_session (& stpg -> tpg , tag_num ,
2341
2338
tag_size , TARGET_PROT_NORMAL ,
2342
2339
i_port_id + 2 , ch , NULL );
2340
+ }
2341
+ mutex_unlock (& sport -> gid_id -> mutex );
2343
2342
}
2344
- mutex_unlock (& sport -> port_gid_id .mutex );
2345
2343
2346
2344
if (IS_ERR_OR_NULL (ch -> sess )) {
2347
2345
WARN_ON_ONCE (ch -> sess == NULL );
@@ -2986,7 +2984,12 @@ static int srpt_release_sport(struct srpt_port *sport)
2986
2984
return 0 ;
2987
2985
}
2988
2986
2989
- static struct se_wwn * __srpt_lookup_wwn (const char * name )
2987
+ struct port_and_port_id {
2988
+ struct srpt_port * sport ;
2989
+ struct srpt_port_id * * port_id ;
2990
+ };
2991
+
2992
+ static struct port_and_port_id __srpt_lookup_port (const char * name )
2990
2993
{
2991
2994
struct ib_device * dev ;
2992
2995
struct srpt_device * sdev ;
@@ -3001,25 +3004,38 @@ static struct se_wwn *__srpt_lookup_wwn(const char *name)
3001
3004
for (i = 0 ; i < dev -> phys_port_cnt ; i ++ ) {
3002
3005
sport = & sdev -> port [i ];
3003
3006
3004
- if (strcmp (sport -> port_guid_id .name , name ) == 0 )
3005
- return & sport -> port_guid_id .wwn ;
3006
- if (strcmp (sport -> port_gid_id .name , name ) == 0 )
3007
- return & sport -> port_gid_id .wwn ;
3007
+ if (strcmp (sport -> guid_name , name ) == 0 ) {
3008
+ kref_get (& sdev -> refcnt );
3009
+ return (struct port_and_port_id ){
3010
+ sport , & sport -> guid_id };
3011
+ }
3012
+ if (strcmp (sport -> gid_name , name ) == 0 ) {
3013
+ kref_get (& sdev -> refcnt );
3014
+ return (struct port_and_port_id ){
3015
+ sport , & sport -> gid_id };
3016
+ }
3008
3017
}
3009
3018
}
3010
3019
3011
- return NULL ;
3020
+ return ( struct port_and_port_id ){} ;
3012
3021
}
3013
3022
3014
- static struct se_wwn * srpt_lookup_wwn (const char * name )
3023
+ /**
3024
+ * srpt_lookup_port() - Look up an RDMA port by name
3025
+ * @name: ASCII port name
3026
+ *
3027
+ * Increments the RDMA port reference count if an RDMA port pointer is returned.
3028
+ * The caller must drop that reference count by calling srpt_port_put_ref().
3029
+ */
3030
+ static struct port_and_port_id srpt_lookup_port (const char * name )
3015
3031
{
3016
- struct se_wwn * wwn ;
3032
+ struct port_and_port_id papi ;
3017
3033
3018
3034
spin_lock (& srpt_dev_lock );
3019
- wwn = __srpt_lookup_wwn (name );
3035
+ papi = __srpt_lookup_port (name );
3020
3036
spin_unlock (& srpt_dev_lock );
3021
3037
3022
- return wwn ;
3038
+ return papi ;
3023
3039
}
3024
3040
3025
3041
static void srpt_free_srq (struct srpt_device * sdev )
@@ -3198,10 +3214,6 @@ static int srpt_add_one(struct ib_device *device)
3198
3214
sport -> port_attrib .srp_sq_size = DEF_SRPT_SQ_SIZE ;
3199
3215
sport -> port_attrib .use_srq = false;
3200
3216
INIT_WORK (& sport -> work , srpt_refresh_port_work );
3201
- mutex_init (& sport -> port_guid_id .mutex );
3202
- INIT_LIST_HEAD (& sport -> port_guid_id .tpg_list );
3203
- mutex_init (& sport -> port_gid_id .mutex );
3204
- INIT_LIST_HEAD (& sport -> port_gid_id .tpg_list );
3205
3217
3206
3218
ret = srpt_refresh_port (sport );
3207
3219
if (ret ) {
@@ -3302,10 +3314,10 @@ static struct srpt_port_id *srpt_wwn_to_sport_id(struct se_wwn *wwn)
3302
3314
{
3303
3315
struct srpt_port * sport = wwn -> priv ;
3304
3316
3305
- if (wwn == & sport -> port_guid_id . wwn )
3306
- return & sport -> port_guid_id ;
3307
- if (wwn == & sport -> port_gid_id . wwn )
3308
- return & sport -> port_gid_id ;
3317
+ if (sport -> guid_id && & sport -> guid_id -> wwn == wwn )
3318
+ return sport -> guid_id ;
3319
+ if (sport -> gid_id && & sport -> gid_id -> wwn == wwn )
3320
+ return sport -> gid_id ;
3309
3321
WARN_ON_ONCE (true);
3310
3322
return NULL ;
3311
3323
}
@@ -3790,7 +3802,31 @@ static struct se_wwn *srpt_make_tport(struct target_fabric_configfs *tf,
3790
3802
struct config_group * group ,
3791
3803
const char * name )
3792
3804
{
3793
- return srpt_lookup_wwn (name ) ? : ERR_PTR (- EINVAL );
3805
+ struct port_and_port_id papi = srpt_lookup_port (name );
3806
+ struct srpt_port * sport = papi .sport ;
3807
+ struct srpt_port_id * port_id ;
3808
+
3809
+ if (!papi .port_id )
3810
+ return ERR_PTR (- EINVAL );
3811
+ if (* papi .port_id ) {
3812
+ /* Attempt to create a directory that already exists. */
3813
+ WARN_ON_ONCE (true);
3814
+ return & (* papi .port_id )-> wwn ;
3815
+ }
3816
+ port_id = kzalloc (sizeof (* port_id ), GFP_KERNEL );
3817
+ if (!port_id ) {
3818
+ srpt_sdev_put (sport -> sdev );
3819
+ return ERR_PTR (- ENOMEM );
3820
+ }
3821
+ mutex_init (& port_id -> mutex );
3822
+ INIT_LIST_HEAD (& port_id -> tpg_list );
3823
+ port_id -> wwn .priv = sport ;
3824
+ memcpy (port_id -> name , port_id == sport -> guid_id ? sport -> guid_name :
3825
+ sport -> gid_name , ARRAY_SIZE (port_id -> name ));
3826
+
3827
+ * papi .port_id = port_id ;
3828
+
3829
+ return & port_id -> wwn ;
3794
3830
}
3795
3831
3796
3832
/**
@@ -3799,6 +3835,18 @@ static struct se_wwn *srpt_make_tport(struct target_fabric_configfs *tf,
3799
3835
*/
3800
3836
static void srpt_drop_tport (struct se_wwn * wwn )
3801
3837
{
3838
+ struct srpt_port_id * port_id = container_of (wwn , typeof (* port_id ), wwn );
3839
+ struct srpt_port * sport = wwn -> priv ;
3840
+
3841
+ if (sport -> guid_id == port_id )
3842
+ sport -> guid_id = NULL ;
3843
+ else if (sport -> gid_id == port_id )
3844
+ sport -> gid_id = NULL ;
3845
+ else
3846
+ WARN_ON_ONCE (true);
3847
+
3848
+ srpt_sdev_put (sport -> sdev );
3849
+ kfree (port_id );
3802
3850
}
3803
3851
3804
3852
static ssize_t srpt_wwn_version_show (struct config_item * item , char * buf )
0 commit comments