@@ -565,18 +565,12 @@ static int srpt_refresh_port(struct srpt_port *sport)
565565 if (ret )
566566 return ret ;
567567
568- sport -> port_guid_id .wwn .priv = sport ;
569568 srpt_format_guid (sport -> guid_name , ARRAY_SIZE (sport -> guid_name ),
570569 & 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 ;
574570 snprintf (sport -> gid_name , ARRAY_SIZE (sport -> gid_name ),
575571 "0x%016llx%016llx" ,
576572 be64_to_cpu (sport -> gid .global .subnet_prefix ),
577573 be64_to_cpu (sport -> gid .global .interface_id ));
578- memcpy (sport -> port_gid_id .name , sport -> gid_name ,
579- ARRAY_SIZE (sport -> gid_name ));
580574
581575 if (rdma_protocol_iwarp (sport -> sdev -> device , sport -> port ))
582576 return 0 ;
@@ -2317,31 +2311,35 @@ static int srpt_cm_req_recv(struct srpt_device *const sdev,
23172311 tag_num = ch -> rq_size ;
23182312 tag_size = 1 ; /* ib_srpt does not use se_sess->sess_cmd_map */
23192313
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 ,
23252320 tag_size , TARGET_PROT_NORMAL ,
23262321 ch -> sess_name , ch , NULL );
2322+ }
2323+ mutex_unlock (& sport -> guid_id -> mutex );
23272324 }
2328- mutex_unlock (& sport -> port_guid_id .mutex );
23292325
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 ,
23352332 tag_size , TARGET_PROT_NORMAL , i_port_id ,
23362333 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 ,
23412338 tag_size , TARGET_PROT_NORMAL ,
23422339 i_port_id + 2 , ch , NULL );
2340+ }
2341+ mutex_unlock (& sport -> gid_id -> mutex );
23432342 }
2344- mutex_unlock (& sport -> port_gid_id .mutex );
23452343
23462344 if (IS_ERR_OR_NULL (ch -> sess )) {
23472345 WARN_ON_ONCE (ch -> sess == NULL );
@@ -2986,7 +2984,12 @@ static int srpt_release_sport(struct srpt_port *sport)
29862984 return 0 ;
29872985}
29882986
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 )
29902993{
29912994 struct ib_device * dev ;
29922995 struct srpt_device * sdev ;
@@ -3001,25 +3004,38 @@ static struct se_wwn *__srpt_lookup_wwn(const char *name)
30013004 for (i = 0 ; i < dev -> phys_port_cnt ; i ++ ) {
30023005 sport = & sdev -> port [i ];
30033006
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+ }
30083017 }
30093018 }
30103019
3011- return NULL ;
3020+ return ( struct port_and_port_id ){} ;
30123021}
30133022
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 )
30153031{
3016- struct se_wwn * wwn ;
3032+ struct port_and_port_id papi ;
30173033
30183034 spin_lock (& srpt_dev_lock );
3019- wwn = __srpt_lookup_wwn (name );
3035+ papi = __srpt_lookup_port (name );
30203036 spin_unlock (& srpt_dev_lock );
30213037
3022- return wwn ;
3038+ return papi ;
30233039}
30243040
30253041static void srpt_free_srq (struct srpt_device * sdev )
@@ -3198,10 +3214,6 @@ static int srpt_add_one(struct ib_device *device)
31983214 sport -> port_attrib .srp_sq_size = DEF_SRPT_SQ_SIZE ;
31993215 sport -> port_attrib .use_srq = false;
32003216 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 );
32053217
32063218 ret = srpt_refresh_port (sport );
32073219 if (ret ) {
@@ -3302,10 +3314,10 @@ static struct srpt_port_id *srpt_wwn_to_sport_id(struct se_wwn *wwn)
33023314{
33033315 struct srpt_port * sport = wwn -> priv ;
33043316
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 ;
33093321 WARN_ON_ONCE (true);
33103322 return NULL ;
33113323}
@@ -3790,7 +3802,31 @@ static struct se_wwn *srpt_make_tport(struct target_fabric_configfs *tf,
37903802 struct config_group * group ,
37913803 const char * name )
37923804{
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 ;
37943830}
37953831
37963832/**
@@ -3799,6 +3835,18 @@ static struct se_wwn *srpt_make_tport(struct target_fabric_configfs *tf,
37993835 */
38003836static void srpt_drop_tport (struct se_wwn * wwn )
38013837{
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 );
38023850}
38033851
38043852static ssize_t srpt_wwn_version_show (struct config_item * item , char * buf )
0 commit comments