1 // SPDX-License-Identifier: GPL-2.0-or-later 2 /* AFS Volume Location Service client 3 * 4 * Copyright (C) 2002 Red Hat, Inc. All Rights Reserved. 5 * Written by David Howells (dhowells@redhat.com) 6 */ 7 8 #include <linux/gfp.h> 9 #include <linux/init.h> 10 #include <linux/sched.h> 11 #include "afs_fs.h" 12 #include "internal.h" 13 14 /* 15 * Deliver reply data to a VL.GetEntryByNameU call. 16 */ 17 static int afs_deliver_vl_get_entry_by_name_u(struct afs_call *call) 18 { 19 struct afs_uvldbentry__xdr *uvldb; 20 struct afs_vldb_entry *entry; 21 bool new_only = false; 22 u32 tmp, nr_servers, vlflags; 23 int i, ret; 24 25 _enter(""); 26 27 ret = afs_transfer_reply(call); 28 if (ret < 0) 29 return ret; 30 31 /* unmarshall the reply once we've received all of it */ 32 uvldb = call->buffer; 33 entry = call->ret_vldb; 34 35 nr_servers = ntohl(uvldb->nServers); 36 if (nr_servers > AFS_NMAXNSERVERS) 37 nr_servers = AFS_NMAXNSERVERS; 38 39 for (i = 0; i < ARRAY_SIZE(uvldb->name) - 1; i++) 40 entry->name[i] = (u8)ntohl(uvldb->name[i]); 41 entry->name[i] = 0; 42 entry->name_len = strlen(entry->name); 43 44 /* If there is a new replication site that we can use, ignore all the 45 * sites that aren't marked as new. 46 */ 47 for (i = 0; i < nr_servers; i++) { 48 tmp = ntohl(uvldb->serverFlags[i]); 49 if (!(tmp & AFS_VLSF_DONTUSE) && 50 (tmp & AFS_VLSF_NEWREPSITE)) 51 new_only = true; 52 } 53 54 vlflags = ntohl(uvldb->flags); 55 for (i = 0; i < nr_servers; i++) { 56 struct afs_uuid__xdr *xdr; 57 struct afs_uuid *uuid; 58 int j; 59 int n = entry->nr_servers; 60 61 tmp = ntohl(uvldb->serverFlags[i]); 62 if (tmp & AFS_VLSF_DONTUSE || 63 (new_only && !(tmp & AFS_VLSF_NEWREPSITE))) 64 continue; 65 if (tmp & AFS_VLSF_RWVOL) { 66 entry->fs_mask[n] |= AFS_VOL_VTM_RW; 67 if (vlflags & AFS_VLF_BACKEXISTS) 68 entry->fs_mask[n] |= AFS_VOL_VTM_BAK; 69 } 70 if (tmp & AFS_VLSF_ROVOL) 71 entry->fs_mask[n] |= AFS_VOL_VTM_RO; 72 if (!entry->fs_mask[n]) 73 continue; 74 75 xdr = &uvldb->serverNumber[i]; 76 uuid = (struct afs_uuid *)&entry->fs_server[n]; 77 uuid->time_low = xdr->time_low; 78 uuid->time_mid = htons(ntohl(xdr->time_mid)); 79 uuid->time_hi_and_version = htons(ntohl(xdr->time_hi_and_version)); 80 uuid->clock_seq_hi_and_reserved = (u8)ntohl(xdr->clock_seq_hi_and_reserved); 81 uuid->clock_seq_low = (u8)ntohl(xdr->clock_seq_low); 82 for (j = 0; j < 6; j++) 83 uuid->node[j] = (u8)ntohl(xdr->node[j]); 84 85 entry->addr_version[n] = ntohl(uvldb->serverUnique[i]); 86 entry->nr_servers++; 87 } 88 89 for (i = 0; i < AFS_MAXTYPES; i++) 90 entry->vid[i] = ntohl(uvldb->volumeId[i]); 91 92 if (vlflags & AFS_VLF_RWEXISTS) 93 __set_bit(AFS_VLDB_HAS_RW, &entry->flags); 94 if (vlflags & AFS_VLF_ROEXISTS) 95 __set_bit(AFS_VLDB_HAS_RO, &entry->flags); 96 if (vlflags & AFS_VLF_BACKEXISTS) 97 __set_bit(AFS_VLDB_HAS_BAK, &entry->flags); 98 99 if (!(vlflags & (AFS_VLF_RWEXISTS | AFS_VLF_ROEXISTS | AFS_VLF_BACKEXISTS))) { 100 entry->error = -ENOMEDIUM; 101 __set_bit(AFS_VLDB_QUERY_ERROR, &entry->flags); 102 } 103 104 __set_bit(AFS_VLDB_QUERY_VALID, &entry->flags); 105 _leave(" = 0 [done]"); 106 return 0; 107 } 108 109 static void afs_destroy_vl_get_entry_by_name_u(struct afs_call *call) 110 { 111 kfree(call->ret_vldb); 112 afs_flat_call_destructor(call); 113 } 114 115 /* 116 * VL.GetEntryByNameU operation type. 117 */ 118 static const struct afs_call_type afs_RXVLGetEntryByNameU = { 119 .name = "VL.GetEntryByNameU", 120 .op = afs_VL_GetEntryByNameU, 121 .deliver = afs_deliver_vl_get_entry_by_name_u, 122 .destructor = afs_destroy_vl_get_entry_by_name_u, 123 }; 124 125 /* 126 * Dispatch a get volume entry by name or ID operation (uuid variant). If the 127 * volname is a decimal number then it's a volume ID not a volume name. 128 */ 129 struct afs_vldb_entry *afs_vl_get_entry_by_name_u(struct afs_vl_cursor *vc, 130 const char *volname, 131 int volnamesz) 132 { 133 struct afs_vldb_entry *entry; 134 struct afs_call *call; 135 struct afs_net *net = vc->cell->net; 136 size_t reqsz, padsz; 137 __be32 *bp; 138 139 _enter(""); 140 141 padsz = (4 - (volnamesz & 3)) & 3; 142 reqsz = 8 + volnamesz + padsz; 143 144 entry = kzalloc(sizeof(struct afs_vldb_entry), GFP_KERNEL); 145 if (!entry) 146 return ERR_PTR(-ENOMEM); 147 148 call = afs_alloc_flat_call(net, &afs_RXVLGetEntryByNameU, reqsz, 149 sizeof(struct afs_uvldbentry__xdr)); 150 if (!call) { 151 kfree(entry); 152 return ERR_PTR(-ENOMEM); 153 } 154 155 call->key = vc->key; 156 call->ret_vldb = entry; 157 call->max_lifespan = AFS_VL_MAX_LIFESPAN; 158 159 /* Marshall the parameters */ 160 bp = call->request; 161 *bp++ = htonl(VLGETENTRYBYNAMEU); 162 *bp++ = htonl(volnamesz); 163 memcpy(bp, volname, volnamesz); 164 if (padsz > 0) 165 memset((void *)bp + volnamesz, 0, padsz); 166 167 trace_afs_make_vl_call(call); 168 afs_make_call(&vc->ac, call, GFP_KERNEL); 169 return (struct afs_vldb_entry *)afs_wait_for_call_to_complete(call, &vc->ac); 170 } 171 172 /* 173 * Deliver reply data to a VL.GetAddrsU call. 174 * 175 * GetAddrsU(IN ListAddrByAttributes *inaddr, 176 * OUT afsUUID *uuidp1, 177 * OUT uint32_t *uniquifier, 178 * OUT uint32_t *nentries, 179 * OUT bulkaddrs *blkaddrs); 180 */ 181 static int afs_deliver_vl_get_addrs_u(struct afs_call *call) 182 { 183 struct afs_addr_list *alist; 184 __be32 *bp; 185 u32 uniquifier, nentries, count; 186 int i, ret; 187 188 _enter("{%u,%zu/%u}", 189 call->unmarshall, iov_iter_count(call->iter), call->count); 190 191 switch (call->unmarshall) { 192 case 0: 193 afs_extract_to_buf(call, 194 sizeof(struct afs_uuid__xdr) + 3 * sizeof(__be32)); 195 call->unmarshall++; 196 197 /* Extract the returned uuid, uniquifier, nentries and 198 * blkaddrs size */ 199 /* Fall through */ 200 case 1: 201 ret = afs_extract_data(call, true); 202 if (ret < 0) 203 return ret; 204 205 bp = call->buffer + sizeof(struct afs_uuid__xdr); 206 uniquifier = ntohl(*bp++); 207 nentries = ntohl(*bp++); 208 count = ntohl(*bp); 209 210 nentries = min(nentries, count); 211 alist = afs_alloc_addrlist(nentries, FS_SERVICE, AFS_FS_PORT); 212 if (!alist) 213 return -ENOMEM; 214 alist->version = uniquifier; 215 call->ret_alist = alist; 216 call->count = count; 217 call->count2 = nentries; 218 call->unmarshall++; 219 220 more_entries: 221 count = min(call->count, 4U); 222 afs_extract_to_buf(call, count * sizeof(__be32)); 223 224 /* Fall through - and extract entries */ 225 case 2: 226 ret = afs_extract_data(call, call->count > 4); 227 if (ret < 0) 228 return ret; 229 230 alist = call->ret_alist; 231 bp = call->buffer; 232 count = min(call->count, 4U); 233 for (i = 0; i < count; i++) 234 if (alist->nr_addrs < call->count2) 235 afs_merge_fs_addr4(alist, *bp++, AFS_FS_PORT); 236 237 call->count -= count; 238 if (call->count > 0) 239 goto more_entries; 240 call->unmarshall++; 241 break; 242 } 243 244 _leave(" = 0 [done]"); 245 return 0; 246 } 247 248 static void afs_vl_get_addrs_u_destructor(struct afs_call *call) 249 { 250 afs_put_addrlist(call->ret_alist); 251 return afs_flat_call_destructor(call); 252 } 253 254 /* 255 * VL.GetAddrsU operation type. 256 */ 257 static const struct afs_call_type afs_RXVLGetAddrsU = { 258 .name = "VL.GetAddrsU", 259 .op = afs_VL_GetAddrsU, 260 .deliver = afs_deliver_vl_get_addrs_u, 261 .destructor = afs_vl_get_addrs_u_destructor, 262 }; 263 264 /* 265 * Dispatch an operation to get the addresses for a server, where the server is 266 * nominated by UUID. 267 */ 268 struct afs_addr_list *afs_vl_get_addrs_u(struct afs_vl_cursor *vc, 269 const uuid_t *uuid) 270 { 271 struct afs_ListAddrByAttributes__xdr *r; 272 const struct afs_uuid *u = (const struct afs_uuid *)uuid; 273 struct afs_call *call; 274 struct afs_net *net = vc->cell->net; 275 __be32 *bp; 276 int i; 277 278 _enter(""); 279 280 call = afs_alloc_flat_call(net, &afs_RXVLGetAddrsU, 281 sizeof(__be32) + sizeof(struct afs_ListAddrByAttributes__xdr), 282 sizeof(struct afs_uuid__xdr) + 3 * sizeof(__be32)); 283 if (!call) 284 return ERR_PTR(-ENOMEM); 285 286 call->key = vc->key; 287 call->ret_alist = NULL; 288 call->max_lifespan = AFS_VL_MAX_LIFESPAN; 289 290 /* Marshall the parameters */ 291 bp = call->request; 292 *bp++ = htonl(VLGETADDRSU); 293 r = (struct afs_ListAddrByAttributes__xdr *)bp; 294 r->Mask = htonl(AFS_VLADDR_UUID); 295 r->ipaddr = 0; 296 r->index = 0; 297 r->spare = 0; 298 r->uuid.time_low = u->time_low; 299 r->uuid.time_mid = htonl(ntohs(u->time_mid)); 300 r->uuid.time_hi_and_version = htonl(ntohs(u->time_hi_and_version)); 301 r->uuid.clock_seq_hi_and_reserved = htonl(u->clock_seq_hi_and_reserved); 302 r->uuid.clock_seq_low = htonl(u->clock_seq_low); 303 for (i = 0; i < 6; i++) 304 r->uuid.node[i] = htonl(u->node[i]); 305 306 trace_afs_make_vl_call(call); 307 afs_make_call(&vc->ac, call, GFP_KERNEL); 308 return (struct afs_addr_list *)afs_wait_for_call_to_complete(call, &vc->ac); 309 } 310 311 /* 312 * Deliver reply data to an VL.GetCapabilities operation. 313 */ 314 static int afs_deliver_vl_get_capabilities(struct afs_call *call) 315 { 316 u32 count; 317 int ret; 318 319 _enter("{%u,%zu/%u}", 320 call->unmarshall, iov_iter_count(call->iter), call->count); 321 322 switch (call->unmarshall) { 323 case 0: 324 afs_extract_to_tmp(call); 325 call->unmarshall++; 326 327 /* Fall through - and extract the capabilities word count */ 328 case 1: 329 ret = afs_extract_data(call, true); 330 if (ret < 0) 331 return ret; 332 333 count = ntohl(call->tmp); 334 call->count = count; 335 call->count2 = count; 336 337 call->unmarshall++; 338 afs_extract_discard(call, count * sizeof(__be32)); 339 340 /* Fall through - and extract capabilities words */ 341 case 2: 342 ret = afs_extract_data(call, false); 343 if (ret < 0) 344 return ret; 345 346 /* TODO: Examine capabilities */ 347 348 call->unmarshall++; 349 break; 350 } 351 352 _leave(" = 0 [done]"); 353 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); 360 } 361 362 /* 363 * VL.GetCapabilities operation type 364 */ 365 static const struct afs_call_type afs_RXVLGetCapabilities = { 366 .name = "VL.GetCapabilities", 367 .op = afs_VL_GetCapabilities, 368 .deliver = afs_deliver_vl_get_capabilities, 369 .done = afs_vlserver_probe_result, 370 .destructor = afs_destroy_vl_get_capabilities, 371 }; 372 373 /* 374 * Probe a volume server for the capabilities that it supports. This can 375 * return up to 196 words. 376 * 377 * We use this to probe for service upgrade to determine what the server at the 378 * other end supports. 379 */ 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) 385 { 386 struct afs_call *call; 387 __be32 *bp; 388 389 _enter(""); 390 391 call = afs_alloc_flat_call(net, &afs_RXVLGetCapabilities, 1 * 4, 16 * 4); 392 if (!call) 393 return ERR_PTR(-ENOMEM); 394 395 call->key = key; 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; 401 402 /* marshall the parameters */ 403 bp = call->request; 404 *bp++ = htonl(VLGETCAPABILITIES); 405 406 /* Can't take a ref on server */ 407 trace_afs_make_vl_call(call); 408 afs_make_call(ac, call, GFP_KERNEL); 409 return call; 410 } 411 412 /* 413 * Deliver reply data to a YFSVL.GetEndpoints call. 414 * 415 * GetEndpoints(IN yfsServerAttributes *attr, 416 * OUT opr_uuid *uuid, 417 * OUT afs_int32 *uniquifier, 418 * OUT endpoints *fsEndpoints, 419 * OUT endpoints *volEndpoints) 420 */ 421 static int afs_deliver_yfsvl_get_endpoints(struct afs_call *call) 422 { 423 struct afs_addr_list *alist; 424 __be32 *bp; 425 u32 uniquifier, size; 426 int ret; 427 428 _enter("{%u,%zu,%u}", 429 call->unmarshall, iov_iter_count(call->iter), call->count2); 430 431 switch (call->unmarshall) { 432 case 0: 433 afs_extract_to_buf(call, sizeof(uuid_t) + 3 * sizeof(__be32)); 434 call->unmarshall = 1; 435 436 /* Extract the returned uuid, uniquifier, fsEndpoints count and 437 * either the first fsEndpoint type or the volEndpoints 438 * count if there are no fsEndpoints. */ 439 /* Fall through */ 440 case 1: 441 ret = afs_extract_data(call, true); 442 if (ret < 0) 443 return ret; 444 445 bp = call->buffer + sizeof(uuid_t); 446 uniquifier = ntohl(*bp++); 447 call->count = ntohl(*bp++); 448 call->count2 = ntohl(*bp); /* Type or next count */ 449 450 if (call->count > YFS_MAXENDPOINTS) 451 return afs_protocol_error(call, afs_eproto_yvl_fsendpt_num); 452 453 alist = afs_alloc_addrlist(call->count, FS_SERVICE, AFS_FS_PORT); 454 if (!alist) 455 return -ENOMEM; 456 alist->version = uniquifier; 457 call->ret_alist = alist; 458 459 if (call->count == 0) 460 goto extract_volendpoints; 461 462 next_fsendpoint: 463 switch (call->count2) { 464 case YFS_ENDPOINT_IPV4: 465 size = sizeof(__be32) * (1 + 1 + 1); 466 break; 467 case YFS_ENDPOINT_IPV6: 468 size = sizeof(__be32) * (1 + 4 + 1); 469 break; 470 default: 471 return afs_protocol_error(call, afs_eproto_yvl_fsendpt_type); 472 } 473 474 size += sizeof(__be32); 475 afs_extract_to_buf(call, size); 476 call->unmarshall = 2; 477 478 /* Fall through - and extract fsEndpoints[] entries */ 479 case 2: 480 ret = afs_extract_data(call, true); 481 if (ret < 0) 482 return ret; 483 484 alist = call->ret_alist; 485 bp = call->buffer; 486 switch (call->count2) { 487 case YFS_ENDPOINT_IPV4: 488 if (ntohl(bp[0]) != sizeof(__be32) * 2) 489 return afs_protocol_error( 490 call, afs_eproto_yvl_fsendpt4_len); 491 afs_merge_fs_addr4(alist, bp[1], ntohl(bp[2])); 492 bp += 3; 493 break; 494 case YFS_ENDPOINT_IPV6: 495 if (ntohl(bp[0]) != sizeof(__be32) * 5) 496 return afs_protocol_error( 497 call, afs_eproto_yvl_fsendpt6_len); 498 afs_merge_fs_addr6(alist, bp + 1, ntohl(bp[5])); 499 bp += 6; 500 break; 501 default: 502 return afs_protocol_error(call, afs_eproto_yvl_fsendpt_type); 503 } 504 505 /* Got either the type of the next entry or the count of 506 * volEndpoints if no more fsEndpoints. 507 */ 508 call->count2 = ntohl(*bp++); 509 510 call->count--; 511 if (call->count > 0) 512 goto next_fsendpoint; 513 514 extract_volendpoints: 515 /* Extract the list of volEndpoints. */ 516 call->count = call->count2; 517 if (!call->count) 518 goto end; 519 if (call->count > YFS_MAXENDPOINTS) 520 return afs_protocol_error(call, afs_eproto_yvl_vlendpt_type); 521 522 afs_extract_to_buf(call, 1 * sizeof(__be32)); 523 call->unmarshall = 3; 524 525 /* Extract the type of volEndpoints[0]. Normally we would 526 * extract the type of the next endpoint when we extract the 527 * data of the current one, but this is the first... 528 */ 529 /* Fall through */ 530 case 3: 531 ret = afs_extract_data(call, true); 532 if (ret < 0) 533 return ret; 534 535 bp = call->buffer; 536 537 next_volendpoint: 538 call->count2 = ntohl(*bp++); 539 switch (call->count2) { 540 case YFS_ENDPOINT_IPV4: 541 size = sizeof(__be32) * (1 + 1 + 1); 542 break; 543 case YFS_ENDPOINT_IPV6: 544 size = sizeof(__be32) * (1 + 4 + 1); 545 break; 546 default: 547 return afs_protocol_error(call, afs_eproto_yvl_vlendpt_type); 548 } 549 550 if (call->count > 1) 551 size += sizeof(__be32); /* Get next type too */ 552 afs_extract_to_buf(call, size); 553 call->unmarshall = 4; 554 555 /* Fall through - and extract volEndpoints[] entries */ 556 case 4: 557 ret = afs_extract_data(call, true); 558 if (ret < 0) 559 return ret; 560 561 bp = call->buffer; 562 switch (call->count2) { 563 case YFS_ENDPOINT_IPV4: 564 if (ntohl(bp[0]) != sizeof(__be32) * 2) 565 return afs_protocol_error( 566 call, afs_eproto_yvl_vlendpt4_len); 567 bp += 3; 568 break; 569 case YFS_ENDPOINT_IPV6: 570 if (ntohl(bp[0]) != sizeof(__be32) * 5) 571 return afs_protocol_error( 572 call, afs_eproto_yvl_vlendpt6_len); 573 bp += 6; 574 break; 575 default: 576 return afs_protocol_error(call, afs_eproto_yvl_vlendpt_type); 577 } 578 579 /* Got either the type of the next entry or the count of 580 * volEndpoints if no more fsEndpoints. 581 */ 582 call->count--; 583 if (call->count > 0) 584 goto next_volendpoint; 585 586 end: 587 afs_extract_discard(call, 0); 588 call->unmarshall = 5; 589 590 /* Fall through - Done */ 591 case 5: 592 ret = afs_extract_data(call, false); 593 if (ret < 0) 594 return ret; 595 call->unmarshall = 6; 596 597 case 6: 598 break; 599 } 600 601 _leave(" = 0 [done]"); 602 return 0; 603 } 604 605 /* 606 * YFSVL.GetEndpoints operation type. 607 */ 608 static const struct afs_call_type afs_YFSVLGetEndpoints = { 609 .name = "YFSVL.GetEndpoints", 610 .op = afs_YFSVL_GetEndpoints, 611 .deliver = afs_deliver_yfsvl_get_endpoints, 612 .destructor = afs_vl_get_addrs_u_destructor, 613 }; 614 615 /* 616 * Dispatch an operation to get the addresses for a server, where the server is 617 * nominated by UUID. 618 */ 619 struct afs_addr_list *afs_yfsvl_get_endpoints(struct afs_vl_cursor *vc, 620 const uuid_t *uuid) 621 { 622 struct afs_call *call; 623 struct afs_net *net = vc->cell->net; 624 __be32 *bp; 625 626 _enter(""); 627 628 call = afs_alloc_flat_call(net, &afs_YFSVLGetEndpoints, 629 sizeof(__be32) * 2 + sizeof(*uuid), 630 sizeof(struct in6_addr) + sizeof(__be32) * 3); 631 if (!call) 632 return ERR_PTR(-ENOMEM); 633 634 call->key = vc->key; 635 call->ret_alist = NULL; 636 call->max_lifespan = AFS_VL_MAX_LIFESPAN; 637 638 /* Marshall the parameters */ 639 bp = call->request; 640 *bp++ = htonl(YVLGETENDPOINTS); 641 *bp++ = htonl(YFS_SERVER_UUID); 642 memcpy(bp, uuid, sizeof(*uuid)); /* Type opr_uuid */ 643 644 trace_afs_make_vl_call(call); 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 /* Fall through - 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 /* Fall through - 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 /* Fall through - 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); 758 } 759