@@ -21,35 +21,79 @@ static DEFINE_MUTEX(nvmf_hosts_mutex);
2121
2222static struct nvmf_host * nvmf_default_host ;
2323
24- static struct nvmf_host * __nvmf_host_find (const char * hostnqn )
24+ /**
25+ * __nvmf_host_find() - Find a matching to a previously created host
26+ * @hostnqn: Host NQN to match
27+ * @id: Host ID to match
28+ *
29+ * We have defined a host as how it is perceived by the target.
30+ * Therefore, we don't allow different Host NQNs with the same Host ID.
31+ * Similarly, we do not allow the usage of the same Host NQN with different
32+ * Host IDs. This will maintain unambiguous host identification.
33+ *
34+ * Return: Returns host pointer on success, NULL in case of no match or
35+ * ERR_PTR(-EINVAL) in case of error match.
36+ */
37+ static struct nvmf_host * __nvmf_host_find (const char * hostnqn , uuid_t * id )
2538{
2639 struct nvmf_host * host ;
2740
41+ lockdep_assert_held (& nvmf_hosts_mutex );
42+
2843 list_for_each_entry (host , & nvmf_hosts , list ) {
29- if (!strcmp (host -> nqn , hostnqn ))
44+ bool same_hostnqn = !strcmp (host -> nqn , hostnqn );
45+ bool same_hostid = uuid_equal (& host -> id , id );
46+
47+ if (same_hostnqn && same_hostid )
3048 return host ;
49+
50+ if (same_hostnqn ) {
51+ pr_err ("found same hostnqn %s but different hostid %pUb\n" ,
52+ hostnqn , id );
53+ return ERR_PTR (- EINVAL );
54+ }
55+ if (same_hostid ) {
56+ pr_err ("found same hostid %pUb but different hostnqn %s\n" ,
57+ id , hostnqn );
58+ return ERR_PTR (- EINVAL );
59+
60+ }
3161 }
3262
3363 return NULL ;
3464}
3565
36- static struct nvmf_host * nvmf_host_add (const char * hostnqn )
66+ static struct nvmf_host * nvmf_host_alloc (const char * hostnqn , uuid_t * id )
67+ {
68+ struct nvmf_host * host ;
69+
70+ host = kmalloc (sizeof (* host ), GFP_KERNEL );
71+ if (!host )
72+ return NULL ;
73+
74+ kref_init (& host -> ref );
75+ uuid_copy (& host -> id , id );
76+ strscpy (host -> nqn , hostnqn , NVMF_NQN_SIZE );
77+
78+ return host ;
79+ }
80+
81+ static struct nvmf_host * nvmf_host_add (const char * hostnqn , uuid_t * id )
3782{
3883 struct nvmf_host * host ;
3984
4085 mutex_lock (& nvmf_hosts_mutex );
41- host = __nvmf_host_find (hostnqn );
42- if (host ) {
86+ host = __nvmf_host_find (hostnqn , id );
87+ if (IS_ERR (host )) {
88+ goto out_unlock ;
89+ } else if (host ) {
4390 kref_get (& host -> ref );
4491 goto out_unlock ;
4592 }
4693
47- host = kmalloc ( sizeof ( * host ), GFP_KERNEL );
94+ host = nvmf_host_alloc ( hostnqn , id );
4895 if (!host )
49- goto out_unlock ;
50-
51- kref_init (& host -> ref );
52- strscpy (host -> nqn , hostnqn , NVMF_NQN_SIZE );
96+ return ERR_PTR (- ENOMEM );
5397
5498 list_add_tail (& host -> list , & nvmf_hosts );
5599out_unlock :
@@ -60,16 +104,17 @@ static struct nvmf_host *nvmf_host_add(const char *hostnqn)
60104static struct nvmf_host * nvmf_host_default (void )
61105{
62106 struct nvmf_host * host ;
107+ char nqn [NVMF_NQN_SIZE ];
108+ uuid_t id ;
63109
64- host = kmalloc (sizeof (* host ), GFP_KERNEL );
110+ uuid_gen (& id );
111+ snprintf (nqn , NVMF_NQN_SIZE ,
112+ "nqn.2014-08.org.nvmexpress:uuid:%pUb" , & id );
113+
114+ host = nvmf_host_alloc (nqn , & id );
65115 if (!host )
66116 return NULL ;
67117
68- kref_init (& host -> ref );
69- uuid_gen (& host -> id );
70- snprintf (host -> nqn , NVMF_NQN_SIZE ,
71- "nqn.2014-08.org.nvmexpress:uuid:%pUb" , & host -> id );
72-
73118 mutex_lock (& nvmf_hosts_mutex );
74119 list_add_tail (& host -> list , & nvmf_hosts );
75120 mutex_unlock (& nvmf_hosts_mutex );
@@ -633,6 +678,7 @@ static int nvmf_parse_options(struct nvmf_ctrl_options *opts,
633678 size_t nqnlen = 0 ;
634679 int ctrl_loss_tmo = NVMF_DEF_CTRL_LOSS_TMO ;
635680 uuid_t hostid ;
681+ char hostnqn [NVMF_NQN_SIZE ];
636682
637683 /* Set defaults */
638684 opts -> queue_size = NVMF_DEF_QUEUE_SIZE ;
@@ -649,7 +695,9 @@ static int nvmf_parse_options(struct nvmf_ctrl_options *opts,
649695 if (!options )
650696 return - ENOMEM ;
651697
652- uuid_gen (& hostid );
698+ /* use default host if not given by user space */
699+ uuid_copy (& hostid , & nvmf_default_host -> id );
700+ strscpy (hostnqn , nvmf_default_host -> nqn , NVMF_NQN_SIZE );
653701
654702 while ((p = strsep (& o , ",\n" )) != NULL ) {
655703 if (!* p )
@@ -795,12 +843,8 @@ static int nvmf_parse_options(struct nvmf_ctrl_options *opts,
795843 ret = - EINVAL ;
796844 goto out ;
797845 }
798- opts -> host = nvmf_host_add ( p );
846+ strscpy ( hostnqn , p , NVMF_NQN_SIZE );
799847 kfree (p );
800- if (!opts -> host ) {
801- ret = - ENOMEM ;
802- goto out ;
803- }
804848 break ;
805849 case NVMF_OPT_RECONNECT_DELAY :
806850 if (match_int (args , & token )) {
@@ -957,13 +1001,13 @@ static int nvmf_parse_options(struct nvmf_ctrl_options *opts,
9571001 opts -> fast_io_fail_tmo , ctrl_loss_tmo );
9581002 }
9591003
960- if (!opts -> host ) {
961- kref_get (& nvmf_default_host -> ref );
962- opts -> host = nvmf_default_host ;
1004+ opts -> host = nvmf_host_add (hostnqn , & hostid );
1005+ if (IS_ERR (opts -> host )) {
1006+ ret = PTR_ERR (opts -> host );
1007+ opts -> host = NULL ;
1008+ goto out ;
9631009 }
9641010
965- uuid_copy (& opts -> host -> id , & hostid );
966-
9671011out :
9681012 kfree (options );
9691013 return ret ;
0 commit comments