@@ -21,35 +21,79 @@ static DEFINE_MUTEX(nvmf_hosts_mutex);
21
21
22
22
static struct nvmf_host * nvmf_default_host ;
23
23
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 )
25
38
{
26
39
struct nvmf_host * host ;
27
40
41
+ lockdep_assert_held (& nvmf_hosts_mutex );
42
+
28
43
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 )
30
48
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
+ }
31
61
}
32
62
33
63
return NULL ;
34
64
}
35
65
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 )
37
82
{
38
83
struct nvmf_host * host ;
39
84
40
85
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 ) {
43
90
kref_get (& host -> ref );
44
91
goto out_unlock ;
45
92
}
46
93
47
- host = kmalloc ( sizeof ( * host ), GFP_KERNEL );
94
+ host = nvmf_host_alloc ( hostnqn , id );
48
95
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 );
53
97
54
98
list_add_tail (& host -> list , & nvmf_hosts );
55
99
out_unlock :
@@ -60,16 +104,17 @@ static struct nvmf_host *nvmf_host_add(const char *hostnqn)
60
104
static struct nvmf_host * nvmf_host_default (void )
61
105
{
62
106
struct nvmf_host * host ;
107
+ char nqn [NVMF_NQN_SIZE ];
108
+ uuid_t id ;
63
109
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 );
65
115
if (!host )
66
116
return NULL ;
67
117
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
-
73
118
mutex_lock (& nvmf_hosts_mutex );
74
119
list_add_tail (& host -> list , & nvmf_hosts );
75
120
mutex_unlock (& nvmf_hosts_mutex );
@@ -633,6 +678,7 @@ static int nvmf_parse_options(struct nvmf_ctrl_options *opts,
633
678
size_t nqnlen = 0 ;
634
679
int ctrl_loss_tmo = NVMF_DEF_CTRL_LOSS_TMO ;
635
680
uuid_t hostid ;
681
+ char hostnqn [NVMF_NQN_SIZE ];
636
682
637
683
/* Set defaults */
638
684
opts -> queue_size = NVMF_DEF_QUEUE_SIZE ;
@@ -649,7 +695,9 @@ static int nvmf_parse_options(struct nvmf_ctrl_options *opts,
649
695
if (!options )
650
696
return - ENOMEM ;
651
697
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 );
653
701
654
702
while ((p = strsep (& o , ",\n" )) != NULL ) {
655
703
if (!* p )
@@ -795,12 +843,8 @@ static int nvmf_parse_options(struct nvmf_ctrl_options *opts,
795
843
ret = - EINVAL ;
796
844
goto out ;
797
845
}
798
- opts -> host = nvmf_host_add ( p );
846
+ strscpy ( hostnqn , p , NVMF_NQN_SIZE );
799
847
kfree (p );
800
- if (!opts -> host ) {
801
- ret = - ENOMEM ;
802
- goto out ;
803
- }
804
848
break ;
805
849
case NVMF_OPT_RECONNECT_DELAY :
806
850
if (match_int (args , & token )) {
@@ -957,13 +1001,13 @@ static int nvmf_parse_options(struct nvmf_ctrl_options *opts,
957
1001
opts -> fast_io_fail_tmo , ctrl_loss_tmo );
958
1002
}
959
1003
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 ;
963
1009
}
964
1010
965
- uuid_copy (& opts -> host -> id , & hostid );
966
-
967
1011
out :
968
1012
kfree (options );
969
1013
return ret ;
0 commit comments