hc
2024-05-10 9999e48639b3cecb08ffb37358bcba3b48161b29
kernel/fs/afs/vlclient.c
....@@ -1,12 +1,8 @@
1
+// SPDX-License-Identifier: GPL-2.0-or-later
12 /* AFS Volume Location Service client
23 *
34 * Copyright (C) 2002 Red Hat, Inc. All Rights Reserved.
45 * Written by David Howells (dhowells@redhat.com)
5
- *
6
- * This program is free software; you can redistribute it and/or
7
- * modify it under the terms of the GNU General Public License
8
- * as published by the Free Software Foundation; either version
9
- * 2 of the License, or (at your option) any later version.
106 */
117
128 #include <linux/gfp.h>
....@@ -34,7 +30,7 @@
3430
3531 /* unmarshall the reply once we've received all of it */
3632 uvldb = call->buffer;
37
- entry = call->reply[0];
33
+ entry = call->ret_vldb;
3834
3935 nr_servers = ntohl(uvldb->nServers);
4036 if (nr_servers > AFS_NMAXNSERVERS)
....@@ -86,6 +82,7 @@
8682 for (j = 0; j < 6; j++)
8783 uuid->node[j] = (u8)ntohl(xdr->node[j]);
8884
85
+ entry->addr_version[n] = ntohl(uvldb->serverUnique[i]);
8986 entry->nr_servers++;
9087 }
9188
....@@ -111,7 +108,7 @@
111108
112109 static void afs_destroy_vl_get_entry_by_name_u(struct afs_call *call)
113110 {
114
- kfree(call->reply[0]);
111
+ kfree(call->ret_vldb);
115112 afs_flat_call_destructor(call);
116113 }
117114
....@@ -129,14 +126,13 @@
129126 * Dispatch a get volume entry by name or ID operation (uuid variant). If the
130127 * volname is a decimal number then it's a volume ID not a volume name.
131128 */
132
-struct afs_vldb_entry *afs_vl_get_entry_by_name_u(struct afs_net *net,
133
- struct afs_addr_cursor *ac,
134
- struct key *key,
129
+struct afs_vldb_entry *afs_vl_get_entry_by_name_u(struct afs_vl_cursor *vc,
135130 const char *volname,
136131 int volnamesz)
137132 {
138133 struct afs_vldb_entry *entry;
139134 struct afs_call *call;
135
+ struct afs_net *net = vc->cell->net;
140136 size_t reqsz, padsz;
141137 __be32 *bp;
142138
....@@ -156,9 +152,9 @@
156152 return ERR_PTR(-ENOMEM);
157153 }
158154
159
- call->key = key;
160
- call->reply[0] = entry;
161
- call->ret_reply0 = true;
155
+ call->key = vc->key;
156
+ call->ret_vldb = entry;
157
+ call->max_lifespan = AFS_VL_MAX_LIFESPAN;
162158
163159 /* Marshall the parameters */
164160 bp = call->request;
....@@ -169,7 +165,8 @@
169165 memset((void *)bp + volnamesz, 0, padsz);
170166
171167 trace_afs_make_vl_call(call);
172
- return (struct afs_vldb_entry *)afs_make_call(ac, call, GFP_KERNEL, false);
168
+ afs_make_call(&vc->ac, call, GFP_KERNEL);
169
+ return (struct afs_vldb_entry *)afs_wait_for_call_to_complete(call, &vc->ac);
173170 }
174171
175172 /*
....@@ -188,19 +185,20 @@
188185 u32 uniquifier, nentries, count;
189186 int i, ret;
190187
191
- _enter("{%u,%zu/%u}", call->unmarshall, call->offset, call->count);
188
+ _enter("{%u,%zu/%u}",
189
+ call->unmarshall, iov_iter_count(call->iter), call->count);
192190
193
-again:
194191 switch (call->unmarshall) {
195192 case 0:
196
- call->offset = 0;
193
+ afs_extract_to_buf(call,
194
+ sizeof(struct afs_uuid__xdr) + 3 * sizeof(__be32));
197195 call->unmarshall++;
198196
199
- /* Extract the returned uuid, uniquifier, nentries and blkaddrs size */
197
+ /* Extract the returned uuid, uniquifier, nentries and
198
+ * blkaddrs size */
199
+ fallthrough;
200200 case 1:
201
- ret = afs_extract_data(call, call->buffer,
202
- sizeof(struct afs_uuid__xdr) + 3 * sizeof(__be32),
203
- true);
201
+ ret = afs_extract_data(call, true);
204202 if (ret < 0)
205203 return ret;
206204
....@@ -214,31 +212,31 @@
214212 if (!alist)
215213 return -ENOMEM;
216214 alist->version = uniquifier;
217
- call->reply[0] = alist;
215
+ call->ret_alist = alist;
218216 call->count = count;
219217 call->count2 = nentries;
220
- call->offset = 0;
221218 call->unmarshall++;
222219
223
- /* Extract entries */
224
- case 2:
220
+ more_entries:
225221 count = min(call->count, 4U);
226
- ret = afs_extract_data(call, call->buffer,
227
- count * sizeof(__be32),
228
- call->count > 4);
222
+ afs_extract_to_buf(call, count * sizeof(__be32));
223
+
224
+ fallthrough; /* and extract entries */
225
+ case 2:
226
+ ret = afs_extract_data(call, call->count > 4);
229227 if (ret < 0)
230228 return ret;
231229
232
- alist = call->reply[0];
230
+ alist = call->ret_alist;
233231 bp = call->buffer;
232
+ count = min(call->count, 4U);
234233 for (i = 0; i < count; i++)
235234 if (alist->nr_addrs < call->count2)
236235 afs_merge_fs_addr4(alist, *bp++, AFS_FS_PORT);
237236
238237 call->count -= count;
239238 if (call->count > 0)
240
- goto again;
241
- call->offset = 0;
239
+ goto more_entries;
242240 call->unmarshall++;
243241 break;
244242 }
....@@ -249,8 +247,7 @@
249247
250248 static void afs_vl_get_addrs_u_destructor(struct afs_call *call)
251249 {
252
- afs_put_server(call->net, (struct afs_server *)call->reply[0]);
253
- kfree(call->reply[1]);
250
+ afs_put_addrlist(call->ret_alist);
254251 return afs_flat_call_destructor(call);
255252 }
256253
....@@ -268,14 +265,13 @@
268265 * Dispatch an operation to get the addresses for a server, where the server is
269266 * nominated by UUID.
270267 */
271
-struct afs_addr_list *afs_vl_get_addrs_u(struct afs_net *net,
272
- struct afs_addr_cursor *ac,
273
- struct key *key,
268
+struct afs_addr_list *afs_vl_get_addrs_u(struct afs_vl_cursor *vc,
274269 const uuid_t *uuid)
275270 {
276271 struct afs_ListAddrByAttributes__xdr *r;
277272 const struct afs_uuid *u = (const struct afs_uuid *)uuid;
278273 struct afs_call *call;
274
+ struct afs_net *net = vc->cell->net;
279275 __be32 *bp;
280276 int i;
281277
....@@ -287,9 +283,9 @@
287283 if (!call)
288284 return ERR_PTR(-ENOMEM);
289285
290
- call->key = key;
291
- call->reply[0] = NULL;
292
- call->ret_reply0 = true;
286
+ call->key = vc->key;
287
+ call->ret_alist = NULL;
288
+ call->max_lifespan = AFS_VL_MAX_LIFESPAN;
293289
294290 /* Marshall the parameters */
295291 bp = call->request;
....@@ -308,7 +304,8 @@
308304 r->uuid.node[i] = htonl(u->node[i]);
309305
310306 trace_afs_make_vl_call(call);
311
- return (struct afs_addr_list *)afs_make_call(ac, call, GFP_KERNEL, false);
307
+ afs_make_call(&vc->ac, call, GFP_KERNEL);
308
+ return (struct afs_addr_list *)afs_wait_for_call_to_complete(call, &vc->ac);
312309 }
313310
314311 /*
....@@ -319,52 +316,47 @@
319316 u32 count;
320317 int ret;
321318
322
- _enter("{%u,%zu/%u}", call->unmarshall, call->offset, call->count);
319
+ _enter("{%u,%zu/%u}",
320
+ call->unmarshall, iov_iter_count(call->iter), call->count);
323321
324
-again:
325322 switch (call->unmarshall) {
326323 case 0:
327
- call->offset = 0;
324
+ afs_extract_to_tmp(call);
328325 call->unmarshall++;
329326
330
- /* Extract the capabilities word count */
327
+ fallthrough; /* and extract the capabilities word count */
331328 case 1:
332
- ret = afs_extract_data(call, &call->tmp,
333
- 1 * sizeof(__be32),
334
- true);
329
+ ret = afs_extract_data(call, true);
335330 if (ret < 0)
336331 return ret;
337332
338333 count = ntohl(call->tmp);
339
-
340334 call->count = count;
341335 call->count2 = count;
342
- call->offset = 0;
343
- call->unmarshall++;
344336
345
- /* Extract capabilities words */
337
+ call->unmarshall++;
338
+ afs_extract_discard(call, count * sizeof(__be32));
339
+
340
+ fallthrough; /* and extract capabilities words */
346341 case 2:
347
- count = min(call->count, 16U);
348
- ret = afs_extract_data(call, call->buffer,
349
- count * sizeof(__be32),
350
- call->count > 16);
342
+ ret = afs_extract_data(call, false);
351343 if (ret < 0)
352344 return ret;
353345
354346 /* TODO: Examine capabilities */
355347
356
- call->count -= count;
357
- if (call->count > 0)
358
- goto again;
359
- call->offset = 0;
360348 call->unmarshall++;
361349 break;
362350 }
363351
364
- call->reply[0] = (void *)(unsigned long)call->service_id;
365
-
366352 _leave(" = 0 [done]");
367353 return 0;
354
+}
355
+
356
+static void afs_destroy_vl_get_capabilities(struct afs_call *call)
357
+{
358
+ afs_put_vlserver(call->net, call->vlserver);
359
+ afs_flat_call_destructor(call);
368360 }
369361
370362 /*
....@@ -374,19 +366,22 @@
374366 .name = "VL.GetCapabilities",
375367 .op = afs_VL_GetCapabilities,
376368 .deliver = afs_deliver_vl_get_capabilities,
377
- .destructor = afs_flat_call_destructor,
369
+ .done = afs_vlserver_probe_result,
370
+ .destructor = afs_destroy_vl_get_capabilities,
378371 };
379372
380373 /*
381
- * Probe a fileserver for the capabilities that it supports. This can
374
+ * Probe a volume server for the capabilities that it supports. This can
382375 * return up to 196 words.
383376 *
384377 * We use this to probe for service upgrade to determine what the server at the
385378 * other end supports.
386379 */
387
-int afs_vl_get_capabilities(struct afs_net *net,
388
- struct afs_addr_cursor *ac,
389
- struct key *key)
380
+struct afs_call *afs_vl_get_capabilities(struct afs_net *net,
381
+ struct afs_addr_cursor *ac,
382
+ struct key *key,
383
+ struct afs_vlserver *server,
384
+ unsigned int server_index)
390385 {
391386 struct afs_call *call;
392387 __be32 *bp;
....@@ -395,12 +390,14 @@
395390
396391 call = afs_alloc_flat_call(net, &afs_RXVLGetCapabilities, 1 * 4, 16 * 4);
397392 if (!call)
398
- return -ENOMEM;
393
+ return ERR_PTR(-ENOMEM);
399394
400395 call->key = key;
401
- call->upgrade = true; /* Let's see if this is a YFS server */
402
- call->reply[0] = (void *)VLGETCAPABILITIES;
403
- call->ret_reply0 = true;
396
+ call->vlserver = afs_get_vlserver(server);
397
+ call->server_index = server_index;
398
+ call->upgrade = true;
399
+ call->async = true;
400
+ call->max_lifespan = AFS_PROBE_MAX_LIFESPAN;
404401
405402 /* marshall the parameters */
406403 bp = call->request;
....@@ -408,7 +405,8 @@
408405
409406 /* Can't take a ref on server */
410407 trace_afs_make_vl_call(call);
411
- return afs_make_call(ac, call, GFP_KERNEL, false);
408
+ afs_make_call(ac, call, GFP_KERNEL);
409
+ return call;
412410 }
413411
414412 /*
....@@ -427,22 +425,20 @@
427425 u32 uniquifier, size;
428426 int ret;
429427
430
- _enter("{%u,%zu/%u,%u}", call->unmarshall, call->offset, call->count, call->count2);
428
+ _enter("{%u,%zu,%u}",
429
+ call->unmarshall, iov_iter_count(call->iter), call->count2);
431430
432
-again:
433431 switch (call->unmarshall) {
434432 case 0:
435
- call->offset = 0;
433
+ afs_extract_to_buf(call, sizeof(uuid_t) + 3 * sizeof(__be32));
436434 call->unmarshall = 1;
437435
438436 /* Extract the returned uuid, uniquifier, fsEndpoints count and
439437 * either the first fsEndpoint type or the volEndpoints
440438 * count if there are no fsEndpoints. */
439
+ fallthrough;
441440 case 1:
442
- ret = afs_extract_data(call, call->buffer,
443
- sizeof(uuid_t) +
444
- 3 * sizeof(__be32),
445
- true);
441
+ ret = afs_extract_data(call, true);
446442 if (ret < 0)
447443 return ret;
448444
....@@ -452,22 +448,18 @@
452448 call->count2 = ntohl(*bp); /* Type or next count */
453449
454450 if (call->count > YFS_MAXENDPOINTS)
455
- return afs_protocol_error(call, -EBADMSG);
451
+ return afs_protocol_error(call, afs_eproto_yvl_fsendpt_num);
456452
457453 alist = afs_alloc_addrlist(call->count, FS_SERVICE, AFS_FS_PORT);
458454 if (!alist)
459455 return -ENOMEM;
460456 alist->version = uniquifier;
461
- call->reply[0] = alist;
462
- call->offset = 0;
457
+ call->ret_alist = alist;
463458
464459 if (call->count == 0)
465460 goto extract_volendpoints;
466461
467
- call->unmarshall = 2;
468
-
469
- /* Extract fsEndpoints[] entries */
470
- case 2:
462
+ next_fsendpoint:
471463 switch (call->count2) {
472464 case YFS_ENDPOINT_IPV4:
473465 size = sizeof(__be32) * (1 + 1 + 1);
....@@ -476,31 +468,38 @@
476468 size = sizeof(__be32) * (1 + 4 + 1);
477469 break;
478470 default:
479
- return afs_protocol_error(call, -EBADMSG);
471
+ return afs_protocol_error(call, afs_eproto_yvl_fsendpt_type);
480472 }
481473
482474 size += sizeof(__be32);
483
- ret = afs_extract_data(call, call->buffer, size, true);
475
+ afs_extract_to_buf(call, size);
476
+ call->unmarshall = 2;
477
+
478
+ fallthrough; /* and extract fsEndpoints[] entries */
479
+ case 2:
480
+ ret = afs_extract_data(call, true);
484481 if (ret < 0)
485482 return ret;
486483
487
- alist = call->reply[0];
484
+ alist = call->ret_alist;
488485 bp = call->buffer;
489486 switch (call->count2) {
490487 case YFS_ENDPOINT_IPV4:
491488 if (ntohl(bp[0]) != sizeof(__be32) * 2)
492
- return afs_protocol_error(call, -EBADMSG);
489
+ return afs_protocol_error(
490
+ call, afs_eproto_yvl_fsendpt4_len);
493491 afs_merge_fs_addr4(alist, bp[1], ntohl(bp[2]));
494492 bp += 3;
495493 break;
496494 case YFS_ENDPOINT_IPV6:
497495 if (ntohl(bp[0]) != sizeof(__be32) * 5)
498
- return afs_protocol_error(call, -EBADMSG);
496
+ return afs_protocol_error(
497
+ call, afs_eproto_yvl_fsendpt6_len);
499498 afs_merge_fs_addr6(alist, bp + 1, ntohl(bp[5]));
500499 bp += 6;
501500 break;
502501 default:
503
- return afs_protocol_error(call, -EBADMSG);
502
+ return afs_protocol_error(call, afs_eproto_yvl_fsendpt_type);
504503 }
505504
506505 /* Got either the type of the next entry or the count of
....@@ -508,10 +507,9 @@
508507 */
509508 call->count2 = ntohl(*bp++);
510509
511
- call->offset = 0;
512510 call->count--;
513511 if (call->count > 0)
514
- goto again;
512
+ goto next_fsendpoint;
515513
516514 extract_volendpoints:
517515 /* Extract the list of volEndpoints. */
....@@ -519,26 +517,25 @@
519517 if (!call->count)
520518 goto end;
521519 if (call->count > YFS_MAXENDPOINTS)
522
- return afs_protocol_error(call, -EBADMSG);
520
+ return afs_protocol_error(call, afs_eproto_yvl_vlendpt_type);
523521
522
+ afs_extract_to_buf(call, 1 * sizeof(__be32));
524523 call->unmarshall = 3;
525524
526525 /* Extract the type of volEndpoints[0]. Normally we would
527526 * extract the type of the next endpoint when we extract the
528527 * data of the current one, but this is the first...
529528 */
529
+ fallthrough;
530530 case 3:
531
- ret = afs_extract_data(call, call->buffer, sizeof(__be32), true);
531
+ ret = afs_extract_data(call, true);
532532 if (ret < 0)
533533 return ret;
534534
535535 bp = call->buffer;
536
- call->count2 = ntohl(*bp++);
537
- call->offset = 0;
538
- call->unmarshall = 4;
539536
540
- /* Extract volEndpoints[] entries */
541
- case 4:
537
+ next_volendpoint:
538
+ call->count2 = ntohl(*bp++);
542539 switch (call->count2) {
543540 case YFS_ENDPOINT_IPV4:
544541 size = sizeof(__be32) * (1 + 1 + 1);
....@@ -547,12 +544,17 @@
547544 size = sizeof(__be32) * (1 + 4 + 1);
548545 break;
549546 default:
550
- return afs_protocol_error(call, -EBADMSG);
547
+ return afs_protocol_error(call, afs_eproto_yvl_vlendpt_type);
551548 }
552549
553550 if (call->count > 1)
554
- size += sizeof(__be32);
555
- ret = afs_extract_data(call, call->buffer, size, true);
551
+ size += sizeof(__be32); /* Get next type too */
552
+ afs_extract_to_buf(call, size);
553
+ call->unmarshall = 4;
554
+
555
+ fallthrough; /* and extract volEndpoints[] entries */
556
+ case 4:
557
+ ret = afs_extract_data(call, true);
556558 if (ret < 0)
557559 return ret;
558560
....@@ -560,34 +562,34 @@
560562 switch (call->count2) {
561563 case YFS_ENDPOINT_IPV4:
562564 if (ntohl(bp[0]) != sizeof(__be32) * 2)
563
- return afs_protocol_error(call, -EBADMSG);
565
+ return afs_protocol_error(
566
+ call, afs_eproto_yvl_vlendpt4_len);
564567 bp += 3;
565568 break;
566569 case YFS_ENDPOINT_IPV6:
567570 if (ntohl(bp[0]) != sizeof(__be32) * 5)
568
- return afs_protocol_error(call, -EBADMSG);
571
+ return afs_protocol_error(
572
+ call, afs_eproto_yvl_vlendpt6_len);
569573 bp += 6;
570574 break;
571575 default:
572
- return afs_protocol_error(call, -EBADMSG);
576
+ return afs_protocol_error(call, afs_eproto_yvl_vlendpt_type);
573577 }
574578
575579 /* Got either the type of the next entry or the count of
576580 * volEndpoints if no more fsEndpoints.
577581 */
578
- call->offset = 0;
579582 call->count--;
580
- if (call->count > 0) {
581
- call->count2 = ntohl(*bp++);
582
- goto again;
583
- }
583
+ if (call->count > 0)
584
+ goto next_volendpoint;
584585
585586 end:
587
+ afs_extract_discard(call, 0);
586588 call->unmarshall = 5;
587589
588
- /* Done */
590
+ fallthrough; /* Done */
589591 case 5:
590
- ret = afs_extract_data(call, call->buffer, 0, false);
592
+ ret = afs_extract_data(call, false);
591593 if (ret < 0)
592594 return ret;
593595 call->unmarshall = 6;
....@@ -595,12 +597,6 @@
595597 case 6:
596598 break;
597599 }
598
-
599
- alist = call->reply[0];
600
-
601
- /* Start with IPv6 if available. */
602
- if (alist->nr_ipv4 < alist->nr_addrs)
603
- alist->index = alist->nr_ipv4;
604600
605601 _leave(" = 0 [done]");
606602 return 0;
....@@ -620,12 +616,11 @@
620616 * Dispatch an operation to get the addresses for a server, where the server is
621617 * nominated by UUID.
622618 */
623
-struct afs_addr_list *afs_yfsvl_get_endpoints(struct afs_net *net,
624
- struct afs_addr_cursor *ac,
625
- struct key *key,
619
+struct afs_addr_list *afs_yfsvl_get_endpoints(struct afs_vl_cursor *vc,
626620 const uuid_t *uuid)
627621 {
628622 struct afs_call *call;
623
+ struct afs_net *net = vc->cell->net;
629624 __be32 *bp;
630625
631626 _enter("");
....@@ -636,9 +631,9 @@
636631 if (!call)
637632 return ERR_PTR(-ENOMEM);
638633
639
- call->key = key;
640
- call->reply[0] = NULL;
641
- call->ret_reply0 = true;
634
+ call->key = vc->key;
635
+ call->ret_alist = NULL;
636
+ call->max_lifespan = AFS_VL_MAX_LIFESPAN;
642637
643638 /* Marshall the parameters */
644639 bp = call->request;
....@@ -647,5 +642,117 @@
647642 memcpy(bp, uuid, sizeof(*uuid)); /* Type opr_uuid */
648643
649644 trace_afs_make_vl_call(call);
650
- return (struct afs_addr_list *)afs_make_call(ac, call, GFP_KERNEL, false);
645
+ afs_make_call(&vc->ac, call, GFP_KERNEL);
646
+ return (struct afs_addr_list *)afs_wait_for_call_to_complete(call, &vc->ac);
647
+}
648
+
649
+/*
650
+ * Deliver reply data to a YFSVL.GetCellName operation.
651
+ */
652
+static int afs_deliver_yfsvl_get_cell_name(struct afs_call *call)
653
+{
654
+ char *cell_name;
655
+ u32 namesz, paddedsz;
656
+ int ret;
657
+
658
+ _enter("{%u,%zu/%u}",
659
+ call->unmarshall, iov_iter_count(call->iter), call->count);
660
+
661
+ switch (call->unmarshall) {
662
+ case 0:
663
+ afs_extract_to_tmp(call);
664
+ call->unmarshall++;
665
+
666
+ fallthrough; /* and extract the cell name length */
667
+ case 1:
668
+ ret = afs_extract_data(call, true);
669
+ if (ret < 0)
670
+ return ret;
671
+
672
+ namesz = ntohl(call->tmp);
673
+ if (namesz > AFS_MAXCELLNAME)
674
+ return afs_protocol_error(call, afs_eproto_cellname_len);
675
+ paddedsz = (namesz + 3) & ~3;
676
+ call->count = namesz;
677
+ call->count2 = paddedsz - namesz;
678
+
679
+ cell_name = kmalloc(namesz + 1, GFP_KERNEL);
680
+ if (!cell_name)
681
+ return -ENOMEM;
682
+ cell_name[namesz] = 0;
683
+ call->ret_str = cell_name;
684
+
685
+ afs_extract_begin(call, cell_name, namesz);
686
+ call->unmarshall++;
687
+
688
+ fallthrough; /* and extract cell name */
689
+ case 2:
690
+ ret = afs_extract_data(call, true);
691
+ if (ret < 0)
692
+ return ret;
693
+
694
+ afs_extract_discard(call, call->count2);
695
+ call->unmarshall++;
696
+
697
+ fallthrough; /* and extract padding */
698
+ case 3:
699
+ ret = afs_extract_data(call, false);
700
+ if (ret < 0)
701
+ return ret;
702
+
703
+ call->unmarshall++;
704
+ break;
705
+ }
706
+
707
+ _leave(" = 0 [done]");
708
+ return 0;
709
+}
710
+
711
+static void afs_destroy_yfsvl_get_cell_name(struct afs_call *call)
712
+{
713
+ kfree(call->ret_str);
714
+ afs_flat_call_destructor(call);
715
+}
716
+
717
+/*
718
+ * VL.GetCapabilities operation type
719
+ */
720
+static const struct afs_call_type afs_YFSVLGetCellName = {
721
+ .name = "YFSVL.GetCellName",
722
+ .op = afs_YFSVL_GetCellName,
723
+ .deliver = afs_deliver_yfsvl_get_cell_name,
724
+ .destructor = afs_destroy_yfsvl_get_cell_name,
725
+};
726
+
727
+/*
728
+ * Probe a volume server for the capabilities that it supports. This can
729
+ * return up to 196 words.
730
+ *
731
+ * We use this to probe for service upgrade to determine what the server at the
732
+ * other end supports.
733
+ */
734
+char *afs_yfsvl_get_cell_name(struct afs_vl_cursor *vc)
735
+{
736
+ struct afs_call *call;
737
+ struct afs_net *net = vc->cell->net;
738
+ __be32 *bp;
739
+
740
+ _enter("");
741
+
742
+ call = afs_alloc_flat_call(net, &afs_YFSVLGetCellName, 1 * 4, 0);
743
+ if (!call)
744
+ return ERR_PTR(-ENOMEM);
745
+
746
+ call->key = vc->key;
747
+ call->ret_str = NULL;
748
+ call->max_lifespan = AFS_VL_MAX_LIFESPAN;
749
+
750
+ /* marshall the parameters */
751
+ bp = call->request;
752
+ *bp++ = htonl(YVLGETCELLNAME);
753
+
754
+ /* Can't take a ref on server */
755
+ trace_afs_make_vl_call(call);
756
+ afs_make_call(&vc->ac, call, GFP_KERNEL);
757
+ return (char *)afs_wait_for_call_to_complete(call, &vc->ac);
651758 }