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