1 // SPDX-License-Identifier: GPL-2.0-or-later 1 2 /* AFS Cache Manager Service 3 * 4 * Copyright (C) 2002 Red Hat, Inc. All Rights 5 * Written by David Howells (dhowells@redhat.c 6 */ 7 8 #include <linux/module.h> 9 #include <linux/init.h> 10 #include <linux/slab.h> 11 #include <linux/sched.h> 12 #include <linux/ip.h> 13 #include "internal.h" 14 #include "afs_cm.h" 15 #include "protocol_yfs.h" 16 #define RXRPC_TRACE_ONLY_DEFINE_ENUMS 17 #include <trace/events/rxrpc.h> 18 19 static int afs_deliver_cb_init_call_back_state 20 static int afs_deliver_cb_init_call_back_state 21 static int afs_deliver_cb_probe(struct afs_cal 22 static int afs_deliver_cb_callback(struct afs_ 23 static int afs_deliver_cb_probe_uuid(struct af 24 static int afs_deliver_cb_tell_me_about_yourse 25 static void afs_cm_destructor(struct afs_call 26 static void SRXAFSCB_CallBack(struct work_stru 27 static void SRXAFSCB_InitCallBackState(struct 28 static void SRXAFSCB_Probe(struct work_struct 29 static void SRXAFSCB_ProbeUuid(struct work_str 30 static void SRXAFSCB_TellMeAboutYourself(struc 31 32 static int afs_deliver_yfs_cb_callback(struct 33 34 /* 35 * CB.CallBack operation type 36 */ 37 static const struct afs_call_type afs_SRXCBCal 38 .name = "CB.CallBack", 39 .deliver = afs_deliver_cb_callb 40 .destructor = afs_cm_destructor, 41 .work = SRXAFSCB_CallBack, 42 }; 43 44 /* 45 * CB.InitCallBackState operation type 46 */ 47 static const struct afs_call_type afs_SRXCBIni 48 .name = "CB.InitCallBackStat 49 .deliver = afs_deliver_cb_init_ 50 .destructor = afs_cm_destructor, 51 .work = SRXAFSCB_InitCallBac 52 }; 53 54 /* 55 * CB.InitCallBackState3 operation type 56 */ 57 static const struct afs_call_type afs_SRXCBIni 58 .name = "CB.InitCallBackStat 59 .deliver = afs_deliver_cb_init_ 60 .destructor = afs_cm_destructor, 61 .work = SRXAFSCB_InitCallBac 62 }; 63 64 /* 65 * CB.Probe operation type 66 */ 67 static const struct afs_call_type afs_SRXCBPro 68 .name = "CB.Probe", 69 .deliver = afs_deliver_cb_probe 70 .destructor = afs_cm_destructor, 71 .work = SRXAFSCB_Probe, 72 }; 73 74 /* 75 * CB.ProbeUuid operation type 76 */ 77 static const struct afs_call_type afs_SRXCBPro 78 .name = "CB.ProbeUuid", 79 .deliver = afs_deliver_cb_probe 80 .destructor = afs_cm_destructor, 81 .work = SRXAFSCB_ProbeUuid, 82 }; 83 84 /* 85 * CB.TellMeAboutYourself operation type 86 */ 87 static const struct afs_call_type afs_SRXCBTel 88 .name = "CB.TellMeAboutYours 89 .deliver = afs_deliver_cb_tell_ 90 .destructor = afs_cm_destructor, 91 .work = SRXAFSCB_TellMeAbout 92 }; 93 94 /* 95 * YFS CB.CallBack operation type 96 */ 97 static const struct afs_call_type afs_SRXYFSCB 98 .name = "YFSCB.CallBack", 99 .deliver = afs_deliver_yfs_cb_c 100 .destructor = afs_cm_destructor, 101 .work = SRXAFSCB_CallBack, 102 }; 103 104 /* 105 * route an incoming cache manager call 106 * - return T if supported, F if not 107 */ 108 bool afs_cm_incoming_call(struct afs_call *cal 109 { 110 _enter("{%u, CB.OP %u}", call->service 111 112 switch (call->operation_ID) { 113 case CBCallBack: 114 call->type = &afs_SRXCBCallBac 115 return true; 116 case CBInitCallBackState: 117 call->type = &afs_SRXCBInitCal 118 return true; 119 case CBInitCallBackState3: 120 call->type = &afs_SRXCBInitCal 121 return true; 122 case CBProbe: 123 call->type = &afs_SRXCBProbe; 124 return true; 125 case CBProbeUuid: 126 call->type = &afs_SRXCBProbeUu 127 return true; 128 case CBTellMeAboutYourself: 129 call->type = &afs_SRXCBTellMeA 130 return true; 131 case YFSCBCallBack: 132 if (call->service_id != YFS_CM 133 return false; 134 call->type = &afs_SRXYFSCB_Cal 135 return true; 136 default: 137 return false; 138 } 139 } 140 141 /* 142 * Find the server record by peer address and 143 * manager from a server. 144 */ 145 static int afs_find_cm_server_by_peer(struct a 146 { 147 struct sockaddr_rxrpc srx; 148 struct afs_server *server; 149 struct rxrpc_peer *peer; 150 151 peer = rxrpc_kernel_get_call_peer(call 152 153 server = afs_find_server(call->net, pe 154 if (!server) { 155 trace_afs_cm_no_server(call, & 156 return 0; 157 } 158 159 call->server = server; 160 return 0; 161 } 162 163 /* 164 * Find the server record by server UUID and r 165 * manager from a server. 166 */ 167 static int afs_find_cm_server_by_uuid(struct a 168 struct a 169 { 170 struct afs_server *server; 171 172 rcu_read_lock(); 173 server = afs_find_server_by_uuid(call- 174 rcu_read_unlock(); 175 if (!server) { 176 trace_afs_cm_no_server_u(call, 177 return 0; 178 } 179 180 call->server = server; 181 return 0; 182 } 183 184 /* 185 * Clean up a cache manager call. 186 */ 187 static void afs_cm_destructor(struct afs_call 188 { 189 kfree(call->buffer); 190 call->buffer = NULL; 191 } 192 193 /* 194 * Abort a service call from within an action 195 */ 196 static void afs_abort_service_call(struct afs_ 197 enum rxrpc_ 198 { 199 rxrpc_kernel_abort_call(call->net->soc 200 abort_code, er 201 afs_set_call_complete(call, error, 0); 202 } 203 204 /* 205 * The server supplied a list of callbacks tha 206 */ 207 static void SRXAFSCB_CallBack(struct work_stru 208 { 209 struct afs_call *call = container_of(w 210 211 _enter(""); 212 213 /* We need to break the callbacks befo 214 * server holds up change visibility t 215 * to maintain cache coherency. 216 */ 217 if (call->server) { 218 trace_afs_server(call->server- 219 refcount_read 220 atomic_read(& 221 afs_server_tr 222 afs_break_callbacks(call->serv 223 } 224 225 afs_send_empty_reply(call); 226 afs_put_call(call); 227 _leave(""); 228 } 229 230 /* 231 * deliver request data to a CB.CallBack call 232 */ 233 static int afs_deliver_cb_callback(struct afs_ 234 { 235 struct afs_callback_break *cb; 236 __be32 *bp; 237 int ret, loop; 238 239 _enter("{%u}", call->unmarshall); 240 241 switch (call->unmarshall) { 242 case 0: 243 afs_extract_to_tmp(call); 244 call->unmarshall++; 245 246 /* extract the FID array and i 247 fallthrough; 248 case 1: 249 _debug("extract FID count"); 250 ret = afs_extract_data(call, t 251 if (ret < 0) 252 return ret; 253 254 call->count = ntohl(call->tmp) 255 _debug("FID count: %u", call-> 256 if (call->count > AFSCBMAX) 257 return afs_protocol_er 258 259 call->buffer = kmalloc(array3_ 260 GFP_KER 261 if (!call->buffer) 262 return -ENOMEM; 263 afs_extract_to_buf(call, call- 264 call->unmarshall++; 265 266 fallthrough; 267 case 2: 268 _debug("extract FID array"); 269 ret = afs_extract_data(call, t 270 if (ret < 0) 271 return ret; 272 273 _debug("unmarshall FID array") 274 call->request = kcalloc(call-> 275 sizeof 276 GFP_KE 277 if (!call->request) 278 return -ENOMEM; 279 280 cb = call->request; 281 bp = call->buffer; 282 for (loop = call->count; loop 283 cb->fid.vid = ntoh 284 cb->fid.vnode = ntoh 285 cb->fid.unique = ntoh 286 } 287 288 afs_extract_to_tmp(call); 289 call->unmarshall++; 290 291 /* extract the callback array 292 fallthrough; 293 case 3: 294 _debug("extract CB count"); 295 ret = afs_extract_data(call, t 296 if (ret < 0) 297 return ret; 298 299 call->count2 = ntohl(call->tmp 300 _debug("CB count: %u", call->c 301 if (call->count2 != call->coun 302 return afs_protocol_er 303 call->iter = &call->def_iter; 304 iov_iter_discard(&call->def_it 305 call->unmarshall++; 306 307 fallthrough; 308 case 4: 309 _debug("extract discard %zu/%u 310 iov_iter_count(call->it 311 312 ret = afs_extract_data(call, f 313 if (ret < 0) 314 return ret; 315 316 call->unmarshall++; 317 fallthrough; 318 319 case 5: 320 break; 321 } 322 323 if (!afs_check_call_state(call, AFS_CA 324 return afs_io_error(call, afs_ 325 326 /* we'll need the file server record a 327 * vnodes to operate upon */ 328 return afs_find_cm_server_by_peer(call 329 } 330 331 /* 332 * allow the fileserver to request callback st 333 */ 334 static void SRXAFSCB_InitCallBackState(struct 335 { 336 struct afs_call *call = container_of(w 337 338 _enter("{%p}", call->server); 339 340 if (call->server) 341 afs_init_callback_state(call-> 342 afs_send_empty_reply(call); 343 afs_put_call(call); 344 _leave(""); 345 } 346 347 /* 348 * deliver request data to a CB.InitCallBackSt 349 */ 350 static int afs_deliver_cb_init_call_back_state 351 { 352 int ret; 353 354 _enter(""); 355 356 afs_extract_discard(call, 0); 357 ret = afs_extract_data(call, false); 358 if (ret < 0) 359 return ret; 360 361 /* we'll need the file server record a 362 * vnodes to operate upon */ 363 return afs_find_cm_server_by_peer(call 364 } 365 366 /* 367 * deliver request data to a CB.InitCallBackSt 368 */ 369 static int afs_deliver_cb_init_call_back_state 370 { 371 struct afs_uuid *r; 372 unsigned loop; 373 __be32 *b; 374 int ret; 375 376 _enter(""); 377 378 _enter("{%u}", call->unmarshall); 379 380 switch (call->unmarshall) { 381 case 0: 382 call->buffer = kmalloc_array(1 383 if (!call->buffer) 384 return -ENOMEM; 385 afs_extract_to_buf(call, 11 * 386 call->unmarshall++; 387 388 fallthrough; 389 case 1: 390 _debug("extract UUID"); 391 ret = afs_extract_data(call, f 392 switch (ret) { 393 case 0: break; 394 case -EAGAIN: return 0; 395 default: return ret; 396 } 397 398 _debug("unmarshall UUID"); 399 call->request = kmalloc(sizeof 400 if (!call->request) 401 return -ENOMEM; 402 403 b = call->buffer; 404 r = call->request; 405 r->time_low 406 r->time_mid 407 r->time_hi_and_version 408 r->clock_seq_hi_and_reserved 409 r->clock_seq_low 410 411 for (loop = 0; loop < 6; loop+ 412 r->node[loop] = ntohl( 413 414 call->unmarshall++; 415 fallthrough; 416 417 case 2: 418 break; 419 } 420 421 if (!afs_check_call_state(call, AFS_CA 422 return afs_io_error(call, afs_ 423 424 /* we'll need the file server record a 425 * vnodes to operate upon */ 426 return afs_find_cm_server_by_uuid(call 427 } 428 429 /* 430 * allow the fileserver to see if the cache ma 431 */ 432 static void SRXAFSCB_Probe(struct work_struct 433 { 434 struct afs_call *call = container_of(w 435 436 _enter(""); 437 afs_send_empty_reply(call); 438 afs_put_call(call); 439 _leave(""); 440 } 441 442 /* 443 * deliver request data to a CB.Probe call 444 */ 445 static int afs_deliver_cb_probe(struct afs_cal 446 { 447 int ret; 448 449 _enter(""); 450 451 afs_extract_discard(call, 0); 452 ret = afs_extract_data(call, false); 453 if (ret < 0) 454 return ret; 455 456 if (!afs_check_call_state(call, AFS_CA 457 return afs_io_error(call, afs_ 458 return afs_find_cm_server_by_peer(call 459 } 460 461 /* 462 * Allow the fileserver to quickly find out if 463 * rebooted. 464 */ 465 static void SRXAFSCB_ProbeUuid(struct work_str 466 { 467 struct afs_call *call = container_of(w 468 struct afs_uuid *r = call->request; 469 470 _enter(""); 471 472 if (memcmp(r, &call->net->uuid, sizeof 473 afs_send_empty_reply(call); 474 else 475 afs_abort_service_call(call, 1 476 477 afs_put_call(call); 478 _leave(""); 479 } 480 481 /* 482 * deliver request data to a CB.ProbeUuid call 483 */ 484 static int afs_deliver_cb_probe_uuid(struct af 485 { 486 struct afs_uuid *r; 487 unsigned loop; 488 __be32 *b; 489 int ret; 490 491 _enter("{%u}", call->unmarshall); 492 493 switch (call->unmarshall) { 494 case 0: 495 call->buffer = kmalloc_array(1 496 if (!call->buffer) 497 return -ENOMEM; 498 afs_extract_to_buf(call, 11 * 499 call->unmarshall++; 500 501 fallthrough; 502 case 1: 503 _debug("extract UUID"); 504 ret = afs_extract_data(call, f 505 switch (ret) { 506 case 0: break; 507 case -EAGAIN: return 0; 508 default: return ret; 509 } 510 511 _debug("unmarshall UUID"); 512 call->request = kmalloc(sizeof 513 if (!call->request) 514 return -ENOMEM; 515 516 b = call->buffer; 517 r = call->request; 518 r->time_low 519 r->time_mid 520 r->time_hi_and_version 521 r->clock_seq_hi_and_reserved 522 r->clock_seq_low 523 524 for (loop = 0; loop < 6; loop+ 525 r->node[loop] = ntohl( 526 527 call->unmarshall++; 528 fallthrough; 529 530 case 2: 531 break; 532 } 533 534 if (!afs_check_call_state(call, AFS_CA 535 return afs_io_error(call, afs_ 536 return afs_find_cm_server_by_peer(call 537 } 538 539 /* 540 * allow the fileserver to ask about the cache 541 */ 542 static void SRXAFSCB_TellMeAboutYourself(struc 543 { 544 struct afs_call *call = container_of(w 545 int loop; 546 547 struct { 548 struct /* InterfaceAddr */ { 549 __be32 nifs; 550 __be32 uuid[11]; 551 __be32 ifaddr[32]; 552 __be32 netmask[32]; 553 __be32 mtu[32]; 554 } ia; 555 struct /* Capabilities */ { 556 __be32 capcount; 557 __be32 caps[1]; 558 } cap; 559 } reply; 560 561 _enter(""); 562 563 memset(&reply, 0, sizeof(reply)); 564 565 reply.ia.uuid[0] = call->net->uuid.tim 566 reply.ia.uuid[1] = htonl(ntohs(call->n 567 reply.ia.uuid[2] = htonl(ntohs(call->n 568 reply.ia.uuid[3] = htonl((s8) call->ne 569 reply.ia.uuid[4] = htonl((s8) call->ne 570 for (loop = 0; loop < 6; loop++) 571 reply.ia.uuid[loop + 5] = hton 572 573 reply.cap.capcount = htonl(1); 574 reply.cap.caps[0] = htonl(AFS_CAP_ERRO 575 afs_send_simple_reply(call, &reply, si 576 afs_put_call(call); 577 _leave(""); 578 } 579 580 /* 581 * deliver request data to a CB.TellMeAboutYou 582 */ 583 static int afs_deliver_cb_tell_me_about_yourse 584 { 585 int ret; 586 587 _enter(""); 588 589 afs_extract_discard(call, 0); 590 ret = afs_extract_data(call, false); 591 if (ret < 0) 592 return ret; 593 594 if (!afs_check_call_state(call, AFS_CA 595 return afs_io_error(call, afs_ 596 return afs_find_cm_server_by_peer(call 597 } 598 599 /* 600 * deliver request data to a YFS CB.CallBack c 601 */ 602 static int afs_deliver_yfs_cb_callback(struct 603 { 604 struct afs_callback_break *cb; 605 struct yfs_xdr_YFSFid *bp; 606 size_t size; 607 int ret, loop; 608 609 _enter("{%u}", call->unmarshall); 610 611 switch (call->unmarshall) { 612 case 0: 613 afs_extract_to_tmp(call); 614 call->unmarshall++; 615 616 /* extract the FID array and i 617 fallthrough; 618 case 1: 619 _debug("extract FID count"); 620 ret = afs_extract_data(call, t 621 if (ret < 0) 622 return ret; 623 624 call->count = ntohl(call->tmp) 625 _debug("FID count: %u", call-> 626 if (call->count > YFSCBMAX) 627 return afs_protocol_er 628 629 size = array_size(call->count, 630 call->buffer = kmalloc(size, G 631 if (!call->buffer) 632 return -ENOMEM; 633 afs_extract_to_buf(call, size) 634 call->unmarshall++; 635 636 fallthrough; 637 case 2: 638 _debug("extract FID array"); 639 ret = afs_extract_data(call, f 640 if (ret < 0) 641 return ret; 642 643 _debug("unmarshall FID array") 644 call->request = kcalloc(call-> 645 sizeof 646 GFP_KE 647 if (!call->request) 648 return -ENOMEM; 649 650 cb = call->request; 651 bp = call->buffer; 652 for (loop = call->count; loop 653 cb->fid.vid = xdr_ 654 cb->fid.vnode = xdr_ 655 cb->fid.vnode_hi = nto 656 cb->fid.unique = ntoh 657 bp++; 658 } 659 660 afs_extract_to_tmp(call); 661 call->unmarshall++; 662 fallthrough; 663 664 case 3: 665 break; 666 } 667 668 if (!afs_check_call_state(call, AFS_CA 669 return afs_io_error(call, afs_ 670 671 /* We'll need the file server record a 672 * vnodes to operate upon. 673 */ 674 return afs_find_cm_server_by_peer(call 675 } 676
Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.