@@ -64,38 +64,50 @@ struct afs_addr_list *afs_alloc_addrlist(unsigned int nr,
6464/*
6565 * Parse a text string consisting of delimited addresses.
6666 */
67- struct afs_addr_list * afs_parse_text_addrs (const char * text , size_t len ,
68- char delim ,
69- unsigned short service ,
70- unsigned short port )
67+ struct afs_vlserver_list * afs_parse_text_addrs (struct afs_net * net ,
68+ const char * text , size_t len ,
69+ char delim ,
70+ unsigned short service ,
71+ unsigned short port )
7172{
73+ struct afs_vlserver_list * vllist ;
7274 struct afs_addr_list * alist ;
7375 const char * p , * end = text + len ;
76+ const char * problem ;
7477 unsigned int nr = 0 ;
78+ int ret = - ENOMEM ;
7579
7680 _enter ("%*.*s,%c" , (int )len , (int )len , text , delim );
7781
78- if (!len )
82+ if (!len ) {
83+ _leave (" = -EDESTADDRREQ [empty]" );
7984 return ERR_PTR (- EDESTADDRREQ );
85+ }
8086
8187 if (delim == ':' && (memchr (text , ',' , len ) || !memchr (text , '.' , len )))
8288 delim = ',' ;
8389
8490 /* Count the addresses */
8591 p = text ;
8692 do {
87- if (!* p )
88- return ERR_PTR (- EINVAL );
93+ if (!* p ) {
94+ problem = "nul" ;
95+ goto inval ;
96+ }
8997 if (* p == delim )
9098 continue ;
9199 nr ++ ;
92100 if (* p == '[' ) {
93101 p ++ ;
94- if (p == end )
95- return ERR_PTR (- EINVAL );
102+ if (p == end ) {
103+ problem = "brace1" ;
104+ goto inval ;
105+ }
96106 p = memchr (p , ']' , end - p );
97- if (!p )
98- return ERR_PTR (- EINVAL );
107+ if (!p ) {
108+ problem = "brace2" ;
109+ goto inval ;
110+ }
99111 p ++ ;
100112 if (p >= end )
101113 break ;
@@ -109,10 +121,19 @@ struct afs_addr_list *afs_parse_text_addrs(const char *text, size_t len,
109121
110122 _debug ("%u/%u addresses" , nr , AFS_MAX_ADDRESSES );
111123
112- alist = afs_alloc_addrlist ( nr , service , port );
113- if (!alist )
124+ vllist = afs_alloc_vlserver_list ( 1 );
125+ if (!vllist )
114126 return ERR_PTR (- ENOMEM );
115127
128+ vllist -> nr_servers = 1 ;
129+ vllist -> servers [0 ].server = afs_alloc_vlserver ("<dummy>" , 7 , AFS_VL_PORT );
130+ if (!vllist -> servers [0 ].server )
131+ goto error_vl ;
132+
133+ alist = afs_alloc_addrlist (nr , service , AFS_VL_PORT );
134+ if (!alist )
135+ goto error ;
136+
116137 /* Extract the addresses */
117138 p = text ;
118139 do {
@@ -135,17 +156,21 @@ struct afs_addr_list *afs_parse_text_addrs(const char *text, size_t len,
135156 break ;
136157 }
137158
138- if (in4_pton (p , q - p , (u8 * )& x [0 ], -1 , & stop ))
159+ if (in4_pton (p , q - p , (u8 * )& x [0 ], -1 , & stop )) {
139160 family = AF_INET ;
140- else if (in6_pton (p , q - p , (u8 * )x , -1 , & stop ))
161+ } else if (in6_pton (p , q - p , (u8 * )x , -1 , & stop )) {
141162 family = AF_INET6 ;
142- else
163+ } else {
164+ problem = "family" ;
143165 goto bad_address ;
166+ }
144167
145- if (stop != q )
168+ p = q ;
169+ if (stop != p ) {
170+ problem = "nostop" ;
146171 goto bad_address ;
172+ }
147173
148- p = q ;
149174 if (q < end && * q == ']' )
150175 p ++ ;
151176
@@ -154,18 +179,23 @@ struct afs_addr_list *afs_parse_text_addrs(const char *text, size_t len,
154179 /* Port number specification "+1234" */
155180 xport = 0 ;
156181 p ++ ;
157- if (p >= end || !isdigit (* p ))
182+ if (p >= end || !isdigit (* p )) {
183+ problem = "port" ;
158184 goto bad_address ;
185+ }
159186 do {
160187 xport *= 10 ;
161188 xport += * p - '0' ;
162- if (xport > 65535 )
189+ if (xport > 65535 ) {
190+ problem = "pval" ;
163191 goto bad_address ;
192+ }
164193 p ++ ;
165194 } while (p < end && isdigit (* p ));
166195 } else if (* p == delim ) {
167196 p ++ ;
168197 } else {
198+ problem = "weird" ;
169199 goto bad_address ;
170200 }
171201 }
@@ -177,12 +207,23 @@ struct afs_addr_list *afs_parse_text_addrs(const char *text, size_t len,
177207
178208 } while (p < end );
179209
210+ rcu_assign_pointer (vllist -> servers [0 ].server -> addresses , alist );
180211 _leave (" = [nr %u]" , alist -> nr_addrs );
181- return alist ;
212+ return vllist ;
182213
183- bad_address :
184- kfree (alist );
214+ inval :
215+ _leave (" = -EINVAL [%s %zu %*.*s]" ,
216+ problem , p - text , (int )len , (int )len , text );
185217 return ERR_PTR (- EINVAL );
218+ bad_address :
219+ _leave (" = -EINVAL [%s %zu %*.*s]" ,
220+ problem , p - text , (int )len , (int )len , text );
221+ ret = - EINVAL ;
222+ error :
223+ afs_put_addrlist (alist );
224+ error_vl :
225+ afs_put_vlserverlist (net , vllist );
226+ return ERR_PTR (ret );
186227}
187228
188229/*
@@ -201,30 +242,34 @@ static int afs_cmp_addr_list(const struct afs_addr_list *a1,
201242/*
202243 * Perform a DNS query for VL servers and build a up an address list.
203244 */
204- struct afs_addr_list * afs_dns_query (struct afs_cell * cell , time64_t * _expiry )
245+ struct afs_vlserver_list * afs_dns_query (struct afs_cell * cell , time64_t * _expiry )
205246{
206- struct afs_addr_list * alist ;
207- char * vllist = NULL ;
247+ struct afs_vlserver_list * vllist ;
248+ char * result = NULL ;
208249 int ret ;
209250
210251 _enter ("%s" , cell -> name );
211252
212- ret = dns_query ("afsdb" , cell -> name , cell -> name_len ,
213- "" , & vllist , _expiry );
214- if (ret < 0 )
253+ ret = dns_query ("afsdb" , cell -> name , cell -> name_len , "srv=1" ,
254+ & result , _expiry );
255+ if (ret < 0 ) {
256+ _leave (" = %d [dns]" , ret );
215257 return ERR_PTR (ret );
216-
217- alist = afs_parse_text_addrs (vllist , strlen (vllist ), ',' ,
218- VL_SERVICE , AFS_VL_PORT );
219- if (IS_ERR (alist )) {
220- kfree (vllist );
221- if (alist != ERR_PTR (- ENOMEM ))
222- pr_err ("Failed to parse DNS data\n" );
223- return alist ;
224258 }
225259
226- kfree (vllist );
227- return alist ;
260+ if (* _expiry == 0 )
261+ * _expiry = ktime_get_real_seconds () + 60 ;
262+
263+ if (ret > 1 && result [0 ] == 0 )
264+ vllist = afs_extract_vlserver_list (cell , result , ret );
265+ else
266+ vllist = afs_parse_text_addrs (cell -> net , result , ret , ',' ,
267+ VL_SERVICE , AFS_VL_PORT );
268+ kfree (result );
269+ if (IS_ERR (vllist ) && vllist != ERR_PTR (- ENOMEM ))
270+ pr_err ("Failed to parse DNS data %ld\n" , PTR_ERR (vllist ));
271+
272+ return vllist ;
228273}
229274
230275/*
@@ -347,43 +392,3 @@ int afs_end_cursor(struct afs_addr_cursor *ac)
347392 ac -> begun = false;
348393 return ac -> error ;
349394}
350-
351- /*
352- * Set the address cursor for iterating over VL servers.
353- */
354- int afs_set_vl_cursor (struct afs_addr_cursor * ac , struct afs_cell * cell )
355- {
356- struct afs_addr_list * alist ;
357- int ret ;
358-
359- if (!rcu_access_pointer (cell -> vl_addrs )) {
360- ret = wait_on_bit (& cell -> flags , AFS_CELL_FL_NO_LOOKUP_YET ,
361- TASK_INTERRUPTIBLE );
362- if (ret < 0 )
363- return ret ;
364-
365- if (!rcu_access_pointer (cell -> vl_addrs ) &&
366- ktime_get_real_seconds () < cell -> dns_expiry )
367- return cell -> error ;
368- }
369-
370- read_lock (& cell -> vl_addrs_lock );
371- alist = rcu_dereference_protected (cell -> vl_addrs ,
372- lockdep_is_held (& cell -> vl_addrs_lock ));
373- if (alist -> nr_addrs > 0 )
374- afs_get_addrlist (alist );
375- else
376- alist = NULL ;
377- read_unlock (& cell -> vl_addrs_lock );
378-
379- if (!alist )
380- return - EDESTADDRREQ ;
381-
382- ac -> alist = alist ;
383- ac -> addr = NULL ;
384- ac -> start = READ_ONCE (alist -> index );
385- ac -> index = ac -> start ;
386- ac -> error = 0 ;
387- ac -> begun = false;
388- return 0 ;
389- }
0 commit comments