1 /* AFS Cache Manager Service 2 * 3 * Copyright (C) 2002 Red Hat, Inc. All Rights Reserved. 4 * 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. 10 */ 11 12 #include <linux/module.h> 13 #include <linux/init.h> 14 #include <linux/slab.h> 15 #include <linux/sched.h> 16 #include <linux/ip.h> 17 #include "internal.h" 18 #include "afs_cm.h" 19 20 static int afs_deliver_cb_init_call_back_state(struct afs_call *); 21 static int afs_deliver_cb_init_call_back_state3(struct afs_call *); 22 static int afs_deliver_cb_probe(struct afs_call *); 23 static int afs_deliver_cb_callback(struct afs_call *); 24 static int afs_deliver_cb_probe_uuid(struct afs_call *); 25 static int afs_deliver_cb_tell_me_about_yourself(struct afs_call *); 26 static void afs_cm_destructor(struct afs_call *); 27 28 /* 29 * CB.CallBack operation type 30 */ 31 static const struct afs_call_type afs_SRXCBCallBack = { 32 .name = "CB.CallBack", 33 .deliver = afs_deliver_cb_callback, 34 .abort_to_error = afs_abort_to_error, 35 .destructor = afs_cm_destructor, 36 }; 37 38 /* 39 * CB.InitCallBackState operation type 40 */ 41 static const struct afs_call_type afs_SRXCBInitCallBackState = { 42 .name = "CB.InitCallBackState", 43 .deliver = afs_deliver_cb_init_call_back_state, 44 .abort_to_error = afs_abort_to_error, 45 .destructor = afs_cm_destructor, 46 }; 47 48 /* 49 * CB.InitCallBackState3 operation type 50 */ 51 static const struct afs_call_type afs_SRXCBInitCallBackState3 = { 52 .name = "CB.InitCallBackState3", 53 .deliver = afs_deliver_cb_init_call_back_state3, 54 .abort_to_error = afs_abort_to_error, 55 .destructor = afs_cm_destructor, 56 }; 57 58 /* 59 * CB.Probe operation type 60 */ 61 static const struct afs_call_type afs_SRXCBProbe = { 62 .name = "CB.Probe", 63 .deliver = afs_deliver_cb_probe, 64 .abort_to_error = afs_abort_to_error, 65 .destructor = afs_cm_destructor, 66 }; 67 68 /* 69 * CB.ProbeUuid operation type 70 */ 71 static const struct afs_call_type afs_SRXCBProbeUuid = { 72 .name = "CB.ProbeUuid", 73 .deliver = afs_deliver_cb_probe_uuid, 74 .abort_to_error = afs_abort_to_error, 75 .destructor = afs_cm_destructor, 76 }; 77 78 /* 79 * CB.TellMeAboutYourself operation type 80 */ 81 static const struct afs_call_type afs_SRXCBTellMeAboutYourself = { 82 .name = "CB.TellMeAboutYourself", 83 .deliver = afs_deliver_cb_tell_me_about_yourself, 84 .abort_to_error = afs_abort_to_error, 85 .destructor = afs_cm_destructor, 86 }; 87 88 /* 89 * route an incoming cache manager call 90 * - return T if supported, F if not 91 */ 92 bool afs_cm_incoming_call(struct afs_call *call) 93 { 94 _enter("{CB.OP %u}", call->operation_ID); 95 96 switch (call->operation_ID) { 97 case CBCallBack: 98 call->type = &afs_SRXCBCallBack; 99 return true; 100 case CBInitCallBackState: 101 call->type = &afs_SRXCBInitCallBackState; 102 return true; 103 case CBInitCallBackState3: 104 call->type = &afs_SRXCBInitCallBackState3; 105 return true; 106 case CBProbe: 107 call->type = &afs_SRXCBProbe; 108 return true; 109 case CBTellMeAboutYourself: 110 call->type = &afs_SRXCBTellMeAboutYourself; 111 return true; 112 default: 113 return false; 114 } 115 } 116 117 /* 118 * clean up a cache manager call 119 */ 120 static void afs_cm_destructor(struct afs_call *call) 121 { 122 _enter(""); 123 124 /* Break the callbacks here so that we do it after the final ACK is 125 * received. The step number here must match the final number in 126 * afs_deliver_cb_callback(). 127 */ 128 if (call->unmarshall == 5) { 129 ASSERT(call->server && call->count && call->request); 130 afs_break_callbacks(call->server, call->count, call->request); 131 } 132 133 afs_put_server(call->server); 134 call->server = NULL; 135 kfree(call->buffer); 136 call->buffer = NULL; 137 } 138 139 /* 140 * allow the fileserver to see if the cache manager is still alive 141 */ 142 static void SRXAFSCB_CallBack(struct work_struct *work) 143 { 144 struct afs_call *call = container_of(work, struct afs_call, work); 145 146 _enter(""); 147 148 /* be sure to send the reply *before* attempting to spam the AFS server 149 * with FSFetchStatus requests on the vnodes with broken callbacks lest 150 * the AFS server get into a vicious cycle of trying to break further 151 * callbacks because it hadn't received completion of the CBCallBack op 152 * yet */ 153 afs_send_empty_reply(call); 154 155 afs_break_callbacks(call->server, call->count, call->request); 156 _leave(""); 157 } 158 159 /* 160 * deliver request data to a CB.CallBack call 161 */ 162 static int afs_deliver_cb_callback(struct afs_call *call) 163 { 164 struct sockaddr_rxrpc srx; 165 struct afs_callback *cb; 166 struct afs_server *server; 167 __be32 *bp; 168 u32 tmp; 169 int ret, loop; 170 171 _enter("{%u}", call->unmarshall); 172 173 switch (call->unmarshall) { 174 case 0: 175 rxrpc_kernel_get_peer(afs_socket, call->rxcall, &srx); 176 call->offset = 0; 177 call->unmarshall++; 178 179 /* extract the FID array and its count in two steps */ 180 case 1: 181 _debug("extract FID count"); 182 ret = afs_extract_data(call, &call->tmp, 4, true); 183 if (ret < 0) 184 return ret; 185 186 call->count = ntohl(call->tmp); 187 _debug("FID count: %u", call->count); 188 if (call->count > AFSCBMAX) 189 return -EBADMSG; 190 191 call->buffer = kmalloc(call->count * 3 * 4, GFP_KERNEL); 192 if (!call->buffer) 193 return -ENOMEM; 194 call->offset = 0; 195 call->unmarshall++; 196 197 case 2: 198 _debug("extract FID array"); 199 ret = afs_extract_data(call, call->buffer, 200 call->count * 3 * 4, true); 201 if (ret < 0) 202 return ret; 203 204 _debug("unmarshall FID array"); 205 call->request = kcalloc(call->count, 206 sizeof(struct afs_callback), 207 GFP_KERNEL); 208 if (!call->request) 209 return -ENOMEM; 210 211 cb = call->request; 212 bp = call->buffer; 213 for (loop = call->count; loop > 0; loop--, cb++) { 214 cb->fid.vid = ntohl(*bp++); 215 cb->fid.vnode = ntohl(*bp++); 216 cb->fid.unique = ntohl(*bp++); 217 cb->type = AFSCM_CB_UNTYPED; 218 } 219 220 call->offset = 0; 221 call->unmarshall++; 222 223 /* extract the callback array and its count in two steps */ 224 case 3: 225 _debug("extract CB count"); 226 ret = afs_extract_data(call, &call->tmp, 4, true); 227 if (ret < 0) 228 return ret; 229 230 tmp = ntohl(call->tmp); 231 _debug("CB count: %u", tmp); 232 if (tmp != call->count && tmp != 0) 233 return -EBADMSG; 234 call->offset = 0; 235 call->unmarshall++; 236 237 case 4: 238 _debug("extract CB array"); 239 ret = afs_extract_data(call, call->buffer, 240 call->count * 3 * 4, false); 241 if (ret < 0) 242 return ret; 243 244 _debug("unmarshall CB array"); 245 cb = call->request; 246 bp = call->buffer; 247 for (loop = call->count; loop > 0; loop--, cb++) { 248 cb->version = ntohl(*bp++); 249 cb->expiry = ntohl(*bp++); 250 cb->type = ntohl(*bp++); 251 } 252 253 call->offset = 0; 254 call->unmarshall++; 255 256 /* Record that the message was unmarshalled successfully so 257 * that the call destructor can know do the callback breaking 258 * work, even if the final ACK isn't received. 259 * 260 * If the step number changes, then afs_cm_destructor() must be 261 * updated also. 262 */ 263 call->unmarshall++; 264 case 5: 265 break; 266 } 267 268 call->state = AFS_CALL_REPLYING; 269 270 /* we'll need the file server record as that tells us which set of 271 * vnodes to operate upon */ 272 server = afs_find_server(&srx); 273 if (!server) 274 return -ENOTCONN; 275 call->server = server; 276 277 INIT_WORK(&call->work, SRXAFSCB_CallBack); 278 queue_work(afs_wq, &call->work); 279 return 0; 280 } 281 282 /* 283 * allow the fileserver to request callback state (re-)initialisation 284 */ 285 static void SRXAFSCB_InitCallBackState(struct work_struct *work) 286 { 287 struct afs_call *call = container_of(work, struct afs_call, work); 288 289 _enter("{%p}", call->server); 290 291 afs_init_callback_state(call->server); 292 afs_send_empty_reply(call); 293 _leave(""); 294 } 295 296 /* 297 * deliver request data to a CB.InitCallBackState call 298 */ 299 static int afs_deliver_cb_init_call_back_state(struct afs_call *call) 300 { 301 struct sockaddr_rxrpc srx; 302 struct afs_server *server; 303 int ret; 304 305 _enter(""); 306 307 rxrpc_kernel_get_peer(afs_socket, call->rxcall, &srx); 308 309 ret = afs_extract_data(call, NULL, 0, false); 310 if (ret < 0) 311 return ret; 312 313 /* no unmarshalling required */ 314 call->state = AFS_CALL_REPLYING; 315 316 /* we'll need the file server record as that tells us which set of 317 * vnodes to operate upon */ 318 server = afs_find_server(&srx); 319 if (!server) 320 return -ENOTCONN; 321 call->server = server; 322 323 INIT_WORK(&call->work, SRXAFSCB_InitCallBackState); 324 queue_work(afs_wq, &call->work); 325 return 0; 326 } 327 328 /* 329 * deliver request data to a CB.InitCallBackState3 call 330 */ 331 static int afs_deliver_cb_init_call_back_state3(struct afs_call *call) 332 { 333 struct sockaddr_rxrpc srx; 334 struct afs_server *server; 335 struct afs_uuid *r; 336 unsigned loop; 337 __be32 *b; 338 int ret; 339 340 _enter(""); 341 342 rxrpc_kernel_get_peer(afs_socket, call->rxcall, &srx); 343 344 _enter("{%u}", call->unmarshall); 345 346 switch (call->unmarshall) { 347 case 0: 348 call->offset = 0; 349 call->buffer = kmalloc(11 * sizeof(__be32), GFP_KERNEL); 350 if (!call->buffer) 351 return -ENOMEM; 352 call->unmarshall++; 353 354 case 1: 355 _debug("extract UUID"); 356 ret = afs_extract_data(call, call->buffer, 357 11 * sizeof(__be32), false); 358 switch (ret) { 359 case 0: break; 360 case -EAGAIN: return 0; 361 default: return ret; 362 } 363 364 _debug("unmarshall UUID"); 365 call->request = kmalloc(sizeof(struct afs_uuid), GFP_KERNEL); 366 if (!call->request) 367 return -ENOMEM; 368 369 b = call->buffer; 370 r = call->request; 371 r->time_low = ntohl(b[0]); 372 r->time_mid = ntohl(b[1]); 373 r->time_hi_and_version = ntohl(b[2]); 374 r->clock_seq_hi_and_reserved = ntohl(b[3]); 375 r->clock_seq_low = ntohl(b[4]); 376 377 for (loop = 0; loop < 6; loop++) 378 r->node[loop] = ntohl(b[loop + 5]); 379 380 call->offset = 0; 381 call->unmarshall++; 382 383 case 2: 384 break; 385 } 386 387 /* no unmarshalling required */ 388 call->state = AFS_CALL_REPLYING; 389 390 /* we'll need the file server record as that tells us which set of 391 * vnodes to operate upon */ 392 server = afs_find_server(&srx); 393 if (!server) 394 return -ENOTCONN; 395 call->server = server; 396 397 INIT_WORK(&call->work, SRXAFSCB_InitCallBackState); 398 queue_work(afs_wq, &call->work); 399 return 0; 400 } 401 402 /* 403 * allow the fileserver to see if the cache manager is still alive 404 */ 405 static void SRXAFSCB_Probe(struct work_struct *work) 406 { 407 struct afs_call *call = container_of(work, struct afs_call, work); 408 409 _enter(""); 410 afs_send_empty_reply(call); 411 _leave(""); 412 } 413 414 /* 415 * deliver request data to a CB.Probe call 416 */ 417 static int afs_deliver_cb_probe(struct afs_call *call) 418 { 419 int ret; 420 421 _enter(""); 422 423 ret = afs_extract_data(call, NULL, 0, false); 424 if (ret < 0) 425 return ret; 426 427 /* no unmarshalling required */ 428 call->state = AFS_CALL_REPLYING; 429 430 INIT_WORK(&call->work, SRXAFSCB_Probe); 431 queue_work(afs_wq, &call->work); 432 return 0; 433 } 434 435 /* 436 * allow the fileserver to quickly find out if the fileserver has been rebooted 437 */ 438 static void SRXAFSCB_ProbeUuid(struct work_struct *work) 439 { 440 struct afs_call *call = container_of(work, struct afs_call, work); 441 struct afs_uuid *r = call->request; 442 443 struct { 444 __be32 match; 445 } reply; 446 447 _enter(""); 448 449 if (memcmp(r, &afs_uuid, sizeof(afs_uuid)) == 0) 450 reply.match = htonl(0); 451 else 452 reply.match = htonl(1); 453 454 afs_send_simple_reply(call, &reply, sizeof(reply)); 455 _leave(""); 456 } 457 458 /* 459 * deliver request data to a CB.ProbeUuid call 460 */ 461 static int afs_deliver_cb_probe_uuid(struct afs_call *call) 462 { 463 struct afs_uuid *r; 464 unsigned loop; 465 __be32 *b; 466 int ret; 467 468 _enter("{%u}", call->unmarshall); 469 470 switch (call->unmarshall) { 471 case 0: 472 call->offset = 0; 473 call->buffer = kmalloc(11 * sizeof(__be32), GFP_KERNEL); 474 if (!call->buffer) 475 return -ENOMEM; 476 call->unmarshall++; 477 478 case 1: 479 _debug("extract UUID"); 480 ret = afs_extract_data(call, call->buffer, 481 11 * sizeof(__be32), false); 482 switch (ret) { 483 case 0: break; 484 case -EAGAIN: return 0; 485 default: return ret; 486 } 487 488 _debug("unmarshall UUID"); 489 call->request = kmalloc(sizeof(struct afs_uuid), GFP_KERNEL); 490 if (!call->request) 491 return -ENOMEM; 492 493 b = call->buffer; 494 r = call->request; 495 r->time_low = ntohl(b[0]); 496 r->time_mid = ntohl(b[1]); 497 r->time_hi_and_version = ntohl(b[2]); 498 r->clock_seq_hi_and_reserved = ntohl(b[3]); 499 r->clock_seq_low = ntohl(b[4]); 500 501 for (loop = 0; loop < 6; loop++) 502 r->node[loop] = ntohl(b[loop + 5]); 503 504 call->offset = 0; 505 call->unmarshall++; 506 507 case 2: 508 break; 509 } 510 511 call->state = AFS_CALL_REPLYING; 512 513 INIT_WORK(&call->work, SRXAFSCB_ProbeUuid); 514 queue_work(afs_wq, &call->work); 515 return 0; 516 } 517 518 /* 519 * allow the fileserver to ask about the cache manager's capabilities 520 */ 521 static void SRXAFSCB_TellMeAboutYourself(struct work_struct *work) 522 { 523 struct afs_interface *ifs; 524 struct afs_call *call = container_of(work, struct afs_call, work); 525 int loop, nifs; 526 527 struct { 528 struct /* InterfaceAddr */ { 529 __be32 nifs; 530 __be32 uuid[11]; 531 __be32 ifaddr[32]; 532 __be32 netmask[32]; 533 __be32 mtu[32]; 534 } ia; 535 struct /* Capabilities */ { 536 __be32 capcount; 537 __be32 caps[1]; 538 } cap; 539 } reply; 540 541 _enter(""); 542 543 nifs = 0; 544 ifs = kcalloc(32, sizeof(*ifs), GFP_KERNEL); 545 if (ifs) { 546 nifs = afs_get_ipv4_interfaces(ifs, 32, false); 547 if (nifs < 0) { 548 kfree(ifs); 549 ifs = NULL; 550 nifs = 0; 551 } 552 } 553 554 memset(&reply, 0, sizeof(reply)); 555 reply.ia.nifs = htonl(nifs); 556 557 reply.ia.uuid[0] = htonl(afs_uuid.time_low); 558 reply.ia.uuid[1] = htonl(afs_uuid.time_mid); 559 reply.ia.uuid[2] = htonl(afs_uuid.time_hi_and_version); 560 reply.ia.uuid[3] = htonl((s8) afs_uuid.clock_seq_hi_and_reserved); 561 reply.ia.uuid[4] = htonl((s8) afs_uuid.clock_seq_low); 562 for (loop = 0; loop < 6; loop++) 563 reply.ia.uuid[loop + 5] = htonl((s8) afs_uuid.node[loop]); 564 565 if (ifs) { 566 for (loop = 0; loop < nifs; loop++) { 567 reply.ia.ifaddr[loop] = ifs[loop].address.s_addr; 568 reply.ia.netmask[loop] = ifs[loop].netmask.s_addr; 569 reply.ia.mtu[loop] = htonl(ifs[loop].mtu); 570 } 571 kfree(ifs); 572 } 573 574 reply.cap.capcount = htonl(1); 575 reply.cap.caps[0] = htonl(AFS_CAP_ERROR_TRANSLATION); 576 afs_send_simple_reply(call, &reply, sizeof(reply)); 577 578 _leave(""); 579 } 580 581 /* 582 * deliver request data to a CB.TellMeAboutYourself call 583 */ 584 static int afs_deliver_cb_tell_me_about_yourself(struct afs_call *call) 585 { 586 int ret; 587 588 _enter(""); 589 590 ret = afs_extract_data(call, NULL, 0, false); 591 if (ret < 0) 592 return ret; 593 594 /* no unmarshalling required */ 595 call->state = AFS_CALL_REPLYING; 596 597 INIT_WORK(&call->work, SRXAFSCB_TellMeAboutYourself); 598 queue_work(afs_wq, &call->work); 599 return 0; 600 } 601