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 u32 nr_servers, vlflags; 22 int i, ret; 23 24 _enter(""); 25 26 ret = afs_transfer_reply(call); 27 if (ret < 0) 28 return ret; 29 30 /* unmarshall the reply once we've received all of it */ 31 uvldb = call->buffer; 32 entry = call->ret_vldb; 33 34 nr_servers = ntohl(uvldb->nServers); 35 if (nr_servers > AFS_NMAXNSERVERS) 36 nr_servers = AFS_NMAXNSERVERS; 37 38 for (i = 0; i < ARRAY_SIZE(uvldb->name) - 1; i++) 39 entry->name[i] = (u8)ntohl(uvldb->name[i]); 40 entry->name[i] = 0; 41 entry->name_len = strlen(entry->name); 42 43 vlflags = ntohl(uvldb->flags); 44 for (i = 0; i < nr_servers; i++) { 45 struct afs_uuid__xdr *xdr; 46 struct afs_uuid *uuid; 47 u32 tmp = ntohl(uvldb->serverFlags[i]); 48 int j; 49 int n = entry->nr_servers; 50 51 if (tmp & AFS_VLSF_RWVOL) { 52 entry->fs_mask[n] |= AFS_VOL_VTM_RW; 53 if (vlflags & AFS_VLF_BACKEXISTS) 54 entry->fs_mask[n] |= AFS_VOL_VTM_BAK; 55 } 56 if (tmp & AFS_VLSF_ROVOL) 57 entry->fs_mask[n] |= AFS_VOL_VTM_RO; 58 if (!entry->fs_mask[n]) 59 continue; 60 61 xdr = &uvldb->serverNumber[i]; 62 uuid = (struct afs_uuid *)&entry->fs_server[n]; 63 uuid->time_low = xdr->time_low; 64 uuid->time_mid = htons(ntohl(xdr->time_mid)); 65 uuid->time_hi_and_version = htons(ntohl(xdr->time_hi_and_version)); 66 uuid->clock_seq_hi_and_reserved = (u8)ntohl(xdr->clock_seq_hi_and_reserved); 67 uuid->clock_seq_low = (u8)ntohl(xdr->clock_seq_low); 68 for (j = 0; j < 6; j++) 69 uuid->node[j] = (u8)ntohl(xdr->node[j]); 70 71 entry->vlsf_flags[n] = tmp; 72 entry->addr_version[n] = ntohl(uvldb->serverUnique[i]); 73 entry->nr_servers++; 74 } 75 76 for (i = 0; i < AFS_MAXTYPES; i++) 77 entry->vid[i] = ntohl(uvldb->volumeId[i]); 78 79 if (vlflags & AFS_VLF_RWEXISTS) 80 __set_bit(AFS_VLDB_HAS_RW, &entry->flags); 81 if (vlflags & AFS_VLF_ROEXISTS) 82 __set_bit(AFS_VLDB_HAS_RO, &entry->flags); 83 if (vlflags & AFS_VLF_BACKEXISTS) 84 __set_bit(AFS_VLDB_HAS_BAK, &entry->flags); 85 86 if (!(vlflags & (AFS_VLF_RWEXISTS | AFS_VLF_ROEXISTS | AFS_VLF_BACKEXISTS))) { 87 entry->error = -ENOMEDIUM; 88 __set_bit(AFS_VLDB_QUERY_ERROR, &entry->flags); 89 } 90 91 __set_bit(AFS_VLDB_QUERY_VALID, &entry->flags); 92 _leave(" = 0 [done]"); 93 return 0; 94 } 95 96 /* 97 * VL.GetEntryByNameU operation type. 98 */ 99 static const struct afs_call_type afs_RXVLGetEntryByNameU = { 100 .name = "VL.GetEntryByNameU", 101 .op = afs_VL_GetEntryByNameU, 102 .deliver = afs_deliver_vl_get_entry_by_name_u, 103 .destructor = afs_flat_call_destructor, 104 }; 105 106 /* 107 * Dispatch a get volume entry by name or ID operation (uuid variant). If the 108 * volname is a decimal number then it's a volume ID not a volume name. 109 */ 110 struct afs_vldb_entry *afs_vl_get_entry_by_name_u(struct afs_vl_cursor *vc, 111 const char *volname, 112 int volnamesz) 113 { 114 struct afs_vldb_entry *entry; 115 struct afs_call *call; 116 struct afs_net *net = vc->cell->net; 117 size_t reqsz, padsz; 118 __be32 *bp; 119 120 _enter(""); 121 122 padsz = (4 - (volnamesz & 3)) & 3; 123 reqsz = 8 + volnamesz + padsz; 124 125 entry = kzalloc(sizeof(struct afs_vldb_entry), GFP_KERNEL); 126 if (!entry) 127 return ERR_PTR(-ENOMEM); 128 129 call = afs_alloc_flat_call(net, &afs_RXVLGetEntryByNameU, reqsz, 130 sizeof(struct afs_uvldbentry__xdr)); 131 if (!call) { 132 kfree(entry); 133 return ERR_PTR(-ENOMEM); 134 } 135 136 call->key = vc->key; 137 call->ret_vldb = entry; 138 call->max_lifespan = AFS_VL_MAX_LIFESPAN; 139 call->peer = rxrpc_kernel_get_peer(vc->alist->addrs[vc->addr_index].peer); 140 call->service_id = vc->server->service_id; 141 142 /* Marshall the parameters */ 143 bp = call->request; 144 *bp++ = htonl(VLGETENTRYBYNAMEU); 145 *bp++ = htonl(volnamesz); 146 memcpy(bp, volname, volnamesz); 147 if (padsz > 0) 148 memset((void *)bp + volnamesz, 0, padsz); 149 150 trace_afs_make_vl_call(call); 151 afs_make_call(call, GFP_KERNEL); 152 afs_wait_for_call_to_complete(call); 153 vc->call_abort_code = call->abort_code; 154 vc->call_error = call->error; 155 vc->call_responded = call->responded; 156 afs_put_call(call); 157 if (vc->call_error) { 158 kfree(entry); 159 return ERR_PTR(vc->call_error); 160 } 161 return entry; 162 } 163 164 /* 165 * Deliver reply data to a VL.GetAddrsU call. 166 * 167 * GetAddrsU(IN ListAddrByAttributes *inaddr, 168 * OUT afsUUID *uuidp1, 169 * OUT uint32_t *uniquifier, 170 * OUT uint32_t *nentries, 171 * OUT bulkaddrs *blkaddrs); 172 */ 173 static int afs_deliver_vl_get_addrs_u(struct afs_call *call) 174 { 175 struct afs_addr_list *alist; 176 __be32 *bp; 177 u32 uniquifier, nentries, count; 178 int i, ret; 179 180 _enter("{%u,%zu/%u}", 181 call->unmarshall, iov_iter_count(call->iter), call->count); 182 183 switch (call->unmarshall) { 184 case 0: 185 afs_extract_to_buf(call, 186 sizeof(struct afs_uuid__xdr) + 3 * sizeof(__be32)); 187 call->unmarshall++; 188 189 /* Extract the returned uuid, uniquifier, nentries and 190 * blkaddrs size */ 191 fallthrough; 192 case 1: 193 ret = afs_extract_data(call, true); 194 if (ret < 0) 195 return ret; 196 197 bp = call->buffer + sizeof(struct afs_uuid__xdr); 198 uniquifier = ntohl(*bp++); 199 nentries = ntohl(*bp++); 200 count = ntohl(*bp); 201 202 nentries = min(nentries, count); 203 alist = afs_alloc_addrlist(nentries); 204 if (!alist) 205 return -ENOMEM; 206 alist->version = uniquifier; 207 call->ret_alist = alist; 208 call->count = count; 209 call->count2 = nentries; 210 call->unmarshall++; 211 212 more_entries: 213 count = min(call->count, 4U); 214 afs_extract_to_buf(call, count * sizeof(__be32)); 215 216 fallthrough; /* and extract entries */ 217 case 2: 218 ret = afs_extract_data(call, call->count > 4); 219 if (ret < 0) 220 return ret; 221 222 alist = call->ret_alist; 223 bp = call->buffer; 224 count = min(call->count, 4U); 225 for (i = 0; i < count; i++) { 226 if (alist->nr_addrs < call->count2) { 227 ret = afs_merge_fs_addr4(call->net, alist, *bp++, AFS_FS_PORT); 228 if (ret < 0) 229 return ret; 230 } 231 } 232 233 call->count -= count; 234 if (call->count > 0) 235 goto more_entries; 236 call->unmarshall++; 237 break; 238 } 239 240 _leave(" = 0 [done]"); 241 return 0; 242 } 243 244 /* 245 * VL.GetAddrsU operation type. 246 */ 247 static const struct afs_call_type afs_RXVLGetAddrsU = { 248 .name = "VL.GetAddrsU", 249 .op = afs_VL_GetAddrsU, 250 .deliver = afs_deliver_vl_get_addrs_u, 251 .destructor = afs_flat_call_destructor, 252 }; 253 254 /* 255 * Dispatch an operation to get the addresses for a server, where the server is 256 * nominated by UUID. 257 */ 258 struct afs_addr_list *afs_vl_get_addrs_u(struct afs_vl_cursor *vc, 259 const uuid_t *uuid) 260 { 261 struct afs_ListAddrByAttributes__xdr *r; 262 struct afs_addr_list *alist; 263 const struct afs_uuid *u = (const struct afs_uuid *)uuid; 264 struct afs_call *call; 265 struct afs_net *net = vc->cell->net; 266 __be32 *bp; 267 int i; 268 269 _enter(""); 270 271 call = afs_alloc_flat_call(net, &afs_RXVLGetAddrsU, 272 sizeof(__be32) + sizeof(struct afs_ListAddrByAttributes__xdr), 273 sizeof(struct afs_uuid__xdr) + 3 * sizeof(__be32)); 274 if (!call) 275 return ERR_PTR(-ENOMEM); 276 277 call->key = vc->key; 278 call->ret_alist = NULL; 279 call->max_lifespan = AFS_VL_MAX_LIFESPAN; 280 call->peer = rxrpc_kernel_get_peer(vc->alist->addrs[vc->addr_index].peer); 281 call->service_id = vc->server->service_id; 282 283 /* Marshall the parameters */ 284 bp = call->request; 285 *bp++ = htonl(VLGETADDRSU); 286 r = (struct afs_ListAddrByAttributes__xdr *)bp; 287 r->Mask = htonl(AFS_VLADDR_UUID); 288 r->ipaddr = 0; 289 r->index = 0; 290 r->spare = 0; 291 r->uuid.time_low = u->time_low; 292 r->uuid.time_mid = htonl(ntohs(u->time_mid)); 293 r->uuid.time_hi_and_version = htonl(ntohs(u->time_hi_and_version)); 294 r->uuid.clock_seq_hi_and_reserved = htonl(u->clock_seq_hi_and_reserved); 295 r->uuid.clock_seq_low = htonl(u->clock_seq_low); 296 for (i = 0; i < 6; i++) 297 r->uuid.node[i] = htonl(u->node[i]); 298 299 trace_afs_make_vl_call(call); 300 afs_make_call(call, GFP_KERNEL); 301 afs_wait_for_call_to_complete(call); 302 vc->call_abort_code = call->abort_code; 303 vc->call_error = call->error; 304 vc->call_responded = call->responded; 305 alist = call->ret_alist; 306 afs_put_call(call); 307 if (vc->call_error) { 308 afs_put_addrlist(alist, afs_alist_trace_put_getaddru); 309 return ERR_PTR(vc->call_error); 310 } 311 return alist; 312 } 313 314 /* 315 * Deliver reply data to an VL.GetCapabilities operation. 316 */ 317 static int afs_deliver_vl_get_capabilities(struct afs_call *call) 318 { 319 u32 count; 320 int ret; 321 322 _enter("{%u,%zu/%u}", 323 call->unmarshall, iov_iter_count(call->iter), call->count); 324 325 switch (call->unmarshall) { 326 case 0: 327 afs_extract_to_tmp(call); 328 call->unmarshall++; 329 330 fallthrough; /* and extract the capabilities word count */ 331 case 1: 332 ret = afs_extract_data(call, true); 333 if (ret < 0) 334 return ret; 335 336 count = ntohl(call->tmp); 337 call->count = count; 338 call->count2 = count; 339 340 call->unmarshall++; 341 afs_extract_discard(call, count * sizeof(__be32)); 342 343 fallthrough; /* and extract capabilities words */ 344 case 2: 345 ret = afs_extract_data(call, false); 346 if (ret < 0) 347 return ret; 348 349 /* TODO: Examine capabilities */ 350 351 call->unmarshall++; 352 break; 353 } 354 355 _leave(" = 0 [done]"); 356 return 0; 357 } 358 359 static void afs_destroy_vl_get_capabilities(struct afs_call *call) 360 { 361 afs_put_addrlist(call->vl_probe, afs_alist_trace_put_vlgetcaps); 362 afs_put_vlserver(call->net, call->vlserver); 363 afs_flat_call_destructor(call); 364 } 365 366 /* 367 * VL.GetCapabilities operation type 368 */ 369 static const struct afs_call_type afs_RXVLGetCapabilities = { 370 .name = "VL.GetCapabilities", 371 .op = afs_VL_GetCapabilities, 372 .deliver = afs_deliver_vl_get_capabilities, 373 .immediate_cancel = afs_vlserver_probe_result, 374 .done = afs_vlserver_probe_result, 375 .destructor = afs_destroy_vl_get_capabilities, 376 }; 377 378 /* 379 * Probe a volume server for the capabilities that it supports. This can 380 * return up to 196 words. 381 * 382 * We use this to probe for service upgrade to determine what the server at the 383 * other end supports. 384 */ 385 struct afs_call *afs_vl_get_capabilities(struct afs_net *net, 386 struct afs_addr_list *alist, 387 unsigned int addr_index, 388 struct key *key, 389 struct afs_vlserver *server, 390 unsigned int server_index) 391 { 392 struct afs_call *call; 393 __be32 *bp; 394 395 _enter(""); 396 397 call = afs_alloc_flat_call(net, &afs_RXVLGetCapabilities, 1 * 4, 16 * 4); 398 if (!call) 399 return ERR_PTR(-ENOMEM); 400 401 call->key = key; 402 call->vlserver = afs_get_vlserver(server); 403 call->server_index = server_index; 404 call->peer = rxrpc_kernel_get_peer(alist->addrs[addr_index].peer); 405 call->vl_probe = afs_get_addrlist(alist, afs_alist_trace_get_vlgetcaps); 406 call->probe_index = addr_index; 407 call->service_id = server->service_id; 408 call->upgrade = true; 409 call->async = true; 410 call->max_lifespan = AFS_PROBE_MAX_LIFESPAN; 411 412 /* marshall the parameters */ 413 bp = call->request; 414 *bp++ = htonl(VLGETCAPABILITIES); 415 416 /* Can't take a ref on server */ 417 trace_afs_make_vl_call(call); 418 afs_make_call(call, GFP_KERNEL); 419 return call; 420 } 421 422 /* 423 * Deliver reply data to a YFSVL.GetEndpoints call. 424 * 425 * GetEndpoints(IN yfsServerAttributes *attr, 426 * OUT opr_uuid *uuid, 427 * OUT afs_int32 *uniquifier, 428 * OUT endpoints *fsEndpoints, 429 * OUT endpoints *volEndpoints) 430 */ 431 static int afs_deliver_yfsvl_get_endpoints(struct afs_call *call) 432 { 433 struct afs_addr_list *alist; 434 __be32 *bp; 435 u32 uniquifier, size; 436 int ret; 437 438 _enter("{%u,%zu,%u}", 439 call->unmarshall, iov_iter_count(call->iter), call->count2); 440 441 switch (call->unmarshall) { 442 case 0: 443 afs_extract_to_buf(call, sizeof(uuid_t) + 3 * sizeof(__be32)); 444 call->unmarshall = 1; 445 446 /* Extract the returned uuid, uniquifier, fsEndpoints count and 447 * either the first fsEndpoint type or the volEndpoints 448 * count if there are no fsEndpoints. */ 449 fallthrough; 450 case 1: 451 ret = afs_extract_data(call, true); 452 if (ret < 0) 453 return ret; 454 455 bp = call->buffer + sizeof(uuid_t); 456 uniquifier = ntohl(*bp++); 457 call->count = ntohl(*bp++); 458 call->count2 = ntohl(*bp); /* Type or next count */ 459 460 if (call->count > YFS_MAXENDPOINTS) 461 return afs_protocol_error(call, afs_eproto_yvl_fsendpt_num); 462 463 alist = afs_alloc_addrlist(call->count); 464 if (!alist) 465 return -ENOMEM; 466 alist->version = uniquifier; 467 call->ret_alist = alist; 468 469 if (call->count == 0) 470 goto extract_volendpoints; 471 472 next_fsendpoint: 473 switch (call->count2) { 474 case YFS_ENDPOINT_IPV4: 475 size = sizeof(__be32) * (1 + 1 + 1); 476 break; 477 case YFS_ENDPOINT_IPV6: 478 size = sizeof(__be32) * (1 + 4 + 1); 479 break; 480 default: 481 return afs_protocol_error(call, afs_eproto_yvl_fsendpt_type); 482 } 483 484 size += sizeof(__be32); 485 afs_extract_to_buf(call, size); 486 call->unmarshall = 2; 487 488 fallthrough; /* and extract fsEndpoints[] entries */ 489 case 2: 490 ret = afs_extract_data(call, true); 491 if (ret < 0) 492 return ret; 493 494 alist = call->ret_alist; 495 bp = call->buffer; 496 switch (call->count2) { 497 case YFS_ENDPOINT_IPV4: 498 if (ntohl(bp[0]) != sizeof(__be32) * 2) 499 return afs_protocol_error( 500 call, afs_eproto_yvl_fsendpt4_len); 501 ret = afs_merge_fs_addr4(call->net, alist, bp[1], ntohl(bp[2])); 502 if (ret < 0) 503 return ret; 504 bp += 3; 505 break; 506 case YFS_ENDPOINT_IPV6: 507 if (ntohl(bp[0]) != sizeof(__be32) * 5) 508 return afs_protocol_error( 509 call, afs_eproto_yvl_fsendpt6_len); 510 ret = afs_merge_fs_addr6(call->net, alist, bp + 1, ntohl(bp[5])); 511 if (ret < 0) 512 return ret; 513 bp += 6; 514 break; 515 default: 516 return afs_protocol_error(call, afs_eproto_yvl_fsendpt_type); 517 } 518 519 /* Got either the type of the next entry or the count of 520 * volEndpoints if no more fsEndpoints. 521 */ 522 call->count2 = ntohl(*bp++); 523 524 call->count--; 525 if (call->count > 0) 526 goto next_fsendpoint; 527 528 extract_volendpoints: 529 /* Extract the list of volEndpoints. */ 530 call->count = call->count2; 531 if (!call->count) 532 goto end; 533 if (call->count > YFS_MAXENDPOINTS) 534 return afs_protocol_error(call, afs_eproto_yvl_vlendpt_type); 535 536 afs_extract_to_buf(call, 1 * sizeof(__be32)); 537 call->unmarshall = 3; 538 539 /* Extract the type of volEndpoints[0]. Normally we would 540 * extract the type of the next endpoint when we extract the 541 * data of the current one, but this is the first... 542 */ 543 fallthrough; 544 case 3: 545 ret = afs_extract_data(call, true); 546 if (ret < 0) 547 return ret; 548 549 bp = call->buffer; 550 551 next_volendpoint: 552 call->count2 = ntohl(*bp++); 553 switch (call->count2) { 554 case YFS_ENDPOINT_IPV4: 555 size = sizeof(__be32) * (1 + 1 + 1); 556 break; 557 case YFS_ENDPOINT_IPV6: 558 size = sizeof(__be32) * (1 + 4 + 1); 559 break; 560 default: 561 return afs_protocol_error(call, afs_eproto_yvl_vlendpt_type); 562 } 563 564 if (call->count > 1) 565 size += sizeof(__be32); /* Get next type too */ 566 afs_extract_to_buf(call, size); 567 call->unmarshall = 4; 568 569 fallthrough; /* and extract volEndpoints[] entries */ 570 case 4: 571 ret = afs_extract_data(call, true); 572 if (ret < 0) 573 return ret; 574 575 bp = call->buffer; 576 switch (call->count2) { 577 case YFS_ENDPOINT_IPV4: 578 if (ntohl(bp[0]) != sizeof(__be32) * 2) 579 return afs_protocol_error( 580 call, afs_eproto_yvl_vlendpt4_len); 581 bp += 3; 582 break; 583 case YFS_ENDPOINT_IPV6: 584 if (ntohl(bp[0]) != sizeof(__be32) * 5) 585 return afs_protocol_error( 586 call, afs_eproto_yvl_vlendpt6_len); 587 bp += 6; 588 break; 589 default: 590 return afs_protocol_error(call, afs_eproto_yvl_vlendpt_type); 591 } 592 593 /* Got either the type of the next entry or the count of 594 * volEndpoints if no more fsEndpoints. 595 */ 596 call->count--; 597 if (call->count > 0) 598 goto next_volendpoint; 599 600 end: 601 afs_extract_discard(call, 0); 602 call->unmarshall = 5; 603 604 fallthrough; /* Done */ 605 case 5: 606 ret = afs_extract_data(call, false); 607 if (ret < 0) 608 return ret; 609 call->unmarshall = 6; 610 fallthrough; 611 612 case 6: 613 break; 614 } 615 616 _leave(" = 0 [done]"); 617 return 0; 618 } 619 620 /* 621 * YFSVL.GetEndpoints operation type. 622 */ 623 static const struct afs_call_type afs_YFSVLGetEndpoints = { 624 .name = "YFSVL.GetEndpoints", 625 .op = afs_YFSVL_GetEndpoints, 626 .deliver = afs_deliver_yfsvl_get_endpoints, 627 .destructor = afs_flat_call_destructor, 628 }; 629 630 /* 631 * Dispatch an operation to get the addresses for a server, where the server is 632 * nominated by UUID. 633 */ 634 struct afs_addr_list *afs_yfsvl_get_endpoints(struct afs_vl_cursor *vc, 635 const uuid_t *uuid) 636 { 637 struct afs_addr_list *alist; 638 struct afs_call *call; 639 struct afs_net *net = vc->cell->net; 640 __be32 *bp; 641 642 _enter(""); 643 644 call = afs_alloc_flat_call(net, &afs_YFSVLGetEndpoints, 645 sizeof(__be32) * 2 + sizeof(*uuid), 646 sizeof(struct in6_addr) + sizeof(__be32) * 3); 647 if (!call) 648 return ERR_PTR(-ENOMEM); 649 650 call->key = vc->key; 651 call->ret_alist = NULL; 652 call->max_lifespan = AFS_VL_MAX_LIFESPAN; 653 call->peer = rxrpc_kernel_get_peer(vc->alist->addrs[vc->addr_index].peer); 654 call->service_id = vc->server->service_id; 655 656 /* Marshall the parameters */ 657 bp = call->request; 658 *bp++ = htonl(YVLGETENDPOINTS); 659 *bp++ = htonl(YFS_SERVER_UUID); 660 memcpy(bp, uuid, sizeof(*uuid)); /* Type opr_uuid */ 661 662 trace_afs_make_vl_call(call); 663 afs_make_call(call, GFP_KERNEL); 664 afs_wait_for_call_to_complete(call); 665 vc->call_abort_code = call->abort_code; 666 vc->call_error = call->error; 667 vc->call_responded = call->responded; 668 alist = call->ret_alist; 669 afs_put_call(call); 670 if (vc->call_error) { 671 afs_put_addrlist(alist, afs_alist_trace_put_getaddru); 672 return ERR_PTR(vc->call_error); 673 } 674 return alist; 675 } 676 677 /* 678 * Deliver reply data to a YFSVL.GetCellName operation. 679 */ 680 static int afs_deliver_yfsvl_get_cell_name(struct afs_call *call) 681 { 682 char *cell_name; 683 u32 namesz, paddedsz; 684 int ret; 685 686 _enter("{%u,%zu/%u}", 687 call->unmarshall, iov_iter_count(call->iter), call->count); 688 689 switch (call->unmarshall) { 690 case 0: 691 afs_extract_to_tmp(call); 692 call->unmarshall++; 693 694 fallthrough; /* and extract the cell name length */ 695 case 1: 696 ret = afs_extract_data(call, true); 697 if (ret < 0) 698 return ret; 699 700 namesz = ntohl(call->tmp); 701 if (namesz > YFS_VL_MAXCELLNAME) 702 return afs_protocol_error(call, afs_eproto_cellname_len); 703 paddedsz = (namesz + 3) & ~3; 704 call->count = namesz; 705 call->count2 = paddedsz - namesz; 706 707 cell_name = kmalloc(namesz + 1, GFP_KERNEL); 708 if (!cell_name) 709 return -ENOMEM; 710 cell_name[namesz] = 0; 711 call->ret_str = cell_name; 712 713 afs_extract_begin(call, cell_name, namesz); 714 call->unmarshall++; 715 716 fallthrough; /* and extract cell name */ 717 case 2: 718 ret = afs_extract_data(call, true); 719 if (ret < 0) 720 return ret; 721 722 afs_extract_discard(call, call->count2); 723 call->unmarshall++; 724 725 fallthrough; /* and extract padding */ 726 case 3: 727 ret = afs_extract_data(call, false); 728 if (ret < 0) 729 return ret; 730 731 call->unmarshall++; 732 break; 733 } 734 735 _leave(" = 0 [done]"); 736 return 0; 737 } 738 739 /* 740 * VL.GetCapabilities operation type 741 */ 742 static const struct afs_call_type afs_YFSVLGetCellName = { 743 .name = "YFSVL.GetCellName", 744 .op = afs_YFSVL_GetCellName, 745 .deliver = afs_deliver_yfsvl_get_cell_name, 746 .destructor = afs_flat_call_destructor, 747 }; 748 749 /* 750 * Probe a volume server for the capabilities that it supports. This can 751 * return up to 196 words. 752 * 753 * We use this to probe for service upgrade to determine what the server at the 754 * other end supports. 755 */ 756 char *afs_yfsvl_get_cell_name(struct afs_vl_cursor *vc) 757 { 758 struct afs_call *call; 759 struct afs_net *net = vc->cell->net; 760 __be32 *bp; 761 char *cellname; 762 763 _enter(""); 764 765 call = afs_alloc_flat_call(net, &afs_YFSVLGetCellName, 1 * 4, 0); 766 if (!call) 767 return ERR_PTR(-ENOMEM); 768 769 call->key = vc->key; 770 call->ret_str = NULL; 771 call->max_lifespan = AFS_VL_MAX_LIFESPAN; 772 call->peer = rxrpc_kernel_get_peer(vc->alist->addrs[vc->addr_index].peer); 773 call->service_id = vc->server->service_id; 774 775 /* marshall the parameters */ 776 bp = call->request; 777 *bp++ = htonl(YVLGETCELLNAME); 778 779 /* Can't take a ref on server */ 780 trace_afs_make_vl_call(call); 781 afs_make_call(call, GFP_KERNEL); 782 afs_wait_for_call_to_complete(call); 783 vc->call_abort_code = call->abort_code; 784 vc->call_error = call->error; 785 vc->call_responded = call->responded; 786 cellname = call->ret_str; 787 afs_put_call(call); 788 if (vc->call_error) { 789 kfree(cellname); 790 return ERR_PTR(vc->call_error); 791 } 792 return cellname; 793 } 794