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/sched.h> 15 #include <linux/ip.h> 16 #include "internal.h" 17 #include "afs_cm.h" 18 19 struct workqueue_struct *afs_cm_workqueue; 20 21 static int afs_deliver_cb_init_call_back_state(struct afs_call *, 22 struct sk_buff *, bool); 23 static int afs_deliver_cb_init_call_back_state3(struct afs_call *, 24 struct sk_buff *, bool); 25 static int afs_deliver_cb_probe(struct afs_call *, struct sk_buff *, bool); 26 static int afs_deliver_cb_callback(struct afs_call *, struct sk_buff *, bool); 27 static int afs_deliver_cb_get_capabilities(struct afs_call *, struct sk_buff *, 28 bool); 29 static void afs_cm_destructor(struct afs_call *); 30 31 /* 32 * CB.CallBack operation type 33 */ 34 static const struct afs_call_type afs_SRXCBCallBack = { 35 .name = "CB.CallBack", 36 .deliver = afs_deliver_cb_callback, 37 .abort_to_error = afs_abort_to_error, 38 .destructor = afs_cm_destructor, 39 }; 40 41 /* 42 * CB.InitCallBackState operation type 43 */ 44 static const struct afs_call_type afs_SRXCBInitCallBackState = { 45 .name = "CB.InitCallBackState", 46 .deliver = afs_deliver_cb_init_call_back_state, 47 .abort_to_error = afs_abort_to_error, 48 .destructor = afs_cm_destructor, 49 }; 50 51 /* 52 * CB.InitCallBackState3 operation type 53 */ 54 static const struct afs_call_type afs_SRXCBInitCallBackState3 = { 55 .name = "CB.InitCallBackState3", 56 .deliver = afs_deliver_cb_init_call_back_state3, 57 .abort_to_error = afs_abort_to_error, 58 .destructor = afs_cm_destructor, 59 }; 60 61 /* 62 * CB.Probe operation type 63 */ 64 static const struct afs_call_type afs_SRXCBProbe = { 65 .name = "CB.Probe", 66 .deliver = afs_deliver_cb_probe, 67 .abort_to_error = afs_abort_to_error, 68 .destructor = afs_cm_destructor, 69 }; 70 71 /* 72 * CB.GetCapabilities operation type 73 */ 74 static const struct afs_call_type afs_SRXCBGetCapabilites = { 75 .name = "CB.GetCapabilities", 76 .deliver = afs_deliver_cb_get_capabilities, 77 .abort_to_error = afs_abort_to_error, 78 .destructor = afs_cm_destructor, 79 }; 80 81 /* 82 * route an incoming cache manager call 83 * - return T if supported, F if not 84 */ 85 bool afs_cm_incoming_call(struct afs_call *call) 86 { 87 u32 operation_id = ntohl(call->operation_ID); 88 89 _enter("{CB.OP %u}", operation_id); 90 91 switch (operation_id) { 92 case CBCallBack: 93 call->type = &afs_SRXCBCallBack; 94 return true; 95 case CBInitCallBackState: 96 call->type = &afs_SRXCBInitCallBackState; 97 return true; 98 case CBInitCallBackState3: 99 call->type = &afs_SRXCBInitCallBackState3; 100 return true; 101 case CBProbe: 102 call->type = &afs_SRXCBProbe; 103 return true; 104 case CBGetCapabilities: 105 call->type = &afs_SRXCBGetCapabilites; 106 return true; 107 default: 108 return false; 109 } 110 } 111 112 /* 113 * clean up a cache manager call 114 */ 115 static void afs_cm_destructor(struct afs_call *call) 116 { 117 _enter(""); 118 119 afs_put_server(call->server); 120 call->server = NULL; 121 kfree(call->buffer); 122 call->buffer = NULL; 123 } 124 125 /* 126 * allow the fileserver to see if the cache manager is still alive 127 */ 128 static void SRXAFSCB_CallBack(struct work_struct *work) 129 { 130 struct afs_call *call = container_of(work, struct afs_call, work); 131 132 _enter(""); 133 134 /* be sure to send the reply *before* attempting to spam the AFS server 135 * with FSFetchStatus requests on the vnodes with broken callbacks lest 136 * the AFS server get into a vicious cycle of trying to break further 137 * callbacks because it hadn't received completion of the CBCallBack op 138 * yet */ 139 afs_send_empty_reply(call); 140 141 afs_break_callbacks(call->server, call->count, call->request); 142 _leave(""); 143 } 144 145 /* 146 * deliver request data to a CB.CallBack call 147 */ 148 static int afs_deliver_cb_callback(struct afs_call *call, struct sk_buff *skb, 149 bool last) 150 { 151 struct afs_callback *cb; 152 struct afs_server *server; 153 struct in_addr addr; 154 __be32 *bp; 155 u32 tmp; 156 int ret, loop; 157 158 _enter("{%u},{%u},%d", call->unmarshall, skb->len, last); 159 160 switch (call->unmarshall) { 161 case 0: 162 call->offset = 0; 163 call->unmarshall++; 164 165 /* extract the FID array and its count in two steps */ 166 case 1: 167 _debug("extract FID count"); 168 ret = afs_extract_data(call, skb, last, &call->tmp, 4); 169 switch (ret) { 170 case 0: break; 171 case -EAGAIN: return 0; 172 default: return ret; 173 } 174 175 call->count = ntohl(call->tmp); 176 _debug("FID count: %u", call->count); 177 if (call->count > AFSCBMAX) 178 return -EBADMSG; 179 180 call->buffer = kmalloc(call->count * 3 * 4, GFP_KERNEL); 181 if (!call->buffer) 182 return -ENOMEM; 183 call->offset = 0; 184 call->unmarshall++; 185 186 case 2: 187 _debug("extract FID array"); 188 ret = afs_extract_data(call, skb, last, call->buffer, 189 call->count * 3 * 4); 190 switch (ret) { 191 case 0: break; 192 case -EAGAIN: return 0; 193 default: return ret; 194 } 195 196 _debug("unmarshall FID array"); 197 call->request = kcalloc(call->count, 198 sizeof(struct afs_callback), 199 GFP_KERNEL); 200 if (!call->request) 201 return -ENOMEM; 202 203 cb = call->request; 204 bp = call->buffer; 205 for (loop = call->count; loop > 0; loop--, cb++) { 206 cb->fid.vid = ntohl(*bp++); 207 cb->fid.vnode = ntohl(*bp++); 208 cb->fid.unique = ntohl(*bp++); 209 cb->type = AFSCM_CB_UNTYPED; 210 } 211 212 call->offset = 0; 213 call->unmarshall++; 214 215 /* extract the callback array and its count in two steps */ 216 case 3: 217 _debug("extract CB count"); 218 ret = afs_extract_data(call, skb, last, &call->tmp, 4); 219 switch (ret) { 220 case 0: break; 221 case -EAGAIN: return 0; 222 default: return ret; 223 } 224 225 tmp = ntohl(call->tmp); 226 _debug("CB count: %u", tmp); 227 if (tmp != call->count && tmp != 0) 228 return -EBADMSG; 229 call->offset = 0; 230 call->unmarshall++; 231 if (tmp == 0) 232 goto empty_cb_array; 233 234 case 4: 235 _debug("extract CB array"); 236 ret = afs_extract_data(call, skb, last, call->request, 237 call->count * 3 * 4); 238 switch (ret) { 239 case 0: break; 240 case -EAGAIN: return 0; 241 default: return ret; 242 } 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 empty_cb_array: 254 call->offset = 0; 255 call->unmarshall++; 256 257 case 5: 258 _debug("trailer"); 259 if (skb->len != 0) 260 return -EBADMSG; 261 break; 262 } 263 264 if (!last) 265 return 0; 266 267 call->state = AFS_CALL_REPLYING; 268 269 /* we'll need the file server record as that tells us which set of 270 * vnodes to operate upon */ 271 memcpy(&addr, &ip_hdr(skb)->saddr, 4); 272 server = afs_find_server(&addr); 273 if (!server) 274 return -ENOTCONN; 275 call->server = server; 276 277 INIT_WORK(&call->work, SRXAFSCB_CallBack); 278 schedule_work(&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 struct sk_buff *skb, 301 bool last) 302 { 303 struct afs_server *server; 304 struct in_addr addr; 305 306 _enter(",{%u},%d", skb->len, last); 307 308 if (skb->len > 0) 309 return -EBADMSG; 310 if (!last) 311 return 0; 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 memcpy(&addr, &ip_hdr(skb)->saddr, 4); 319 server = afs_find_server(&addr); 320 if (!server) 321 return -ENOTCONN; 322 call->server = server; 323 324 INIT_WORK(&call->work, SRXAFSCB_InitCallBackState); 325 schedule_work(&call->work); 326 return 0; 327 } 328 329 /* 330 * deliver request data to a CB.InitCallBackState3 call 331 */ 332 static int afs_deliver_cb_init_call_back_state3(struct afs_call *call, 333 struct sk_buff *skb, 334 bool last) 335 { 336 struct afs_server *server; 337 struct in_addr addr; 338 339 _enter(",{%u},%d", skb->len, last); 340 341 if (!last) 342 return 0; 343 344 /* no unmarshalling required */ 345 call->state = AFS_CALL_REPLYING; 346 347 /* we'll need the file server record as that tells us which set of 348 * vnodes to operate upon */ 349 memcpy(&addr, &ip_hdr(skb)->saddr, 4); 350 server = afs_find_server(&addr); 351 if (!server) 352 return -ENOTCONN; 353 call->server = server; 354 355 INIT_WORK(&call->work, SRXAFSCB_InitCallBackState); 356 schedule_work(&call->work); 357 return 0; 358 } 359 360 /* 361 * allow the fileserver to see if the cache manager is still alive 362 */ 363 static void SRXAFSCB_Probe(struct work_struct *work) 364 { 365 struct afs_call *call = container_of(work, struct afs_call, work); 366 367 _enter(""); 368 afs_send_empty_reply(call); 369 _leave(""); 370 } 371 372 /* 373 * deliver request data to a CB.Probe call 374 */ 375 static int afs_deliver_cb_probe(struct afs_call *call, struct sk_buff *skb, 376 bool last) 377 { 378 _enter(",{%u},%d", skb->len, last); 379 380 if (skb->len > 0) 381 return -EBADMSG; 382 if (!last) 383 return 0; 384 385 /* no unmarshalling required */ 386 call->state = AFS_CALL_REPLYING; 387 388 INIT_WORK(&call->work, SRXAFSCB_Probe); 389 schedule_work(&call->work); 390 return 0; 391 } 392 393 /* 394 * allow the fileserver to ask about the cache manager's capabilities 395 */ 396 static void SRXAFSCB_GetCapabilities(struct work_struct *work) 397 { 398 struct afs_interface *ifs; 399 struct afs_call *call = container_of(work, struct afs_call, work); 400 int loop, nifs; 401 402 struct { 403 struct /* InterfaceAddr */ { 404 __be32 nifs; 405 __be32 uuid[11]; 406 __be32 ifaddr[32]; 407 __be32 netmask[32]; 408 __be32 mtu[32]; 409 } ia; 410 struct /* Capabilities */ { 411 __be32 capcount; 412 __be32 caps[1]; 413 } cap; 414 } reply; 415 416 _enter(""); 417 418 nifs = 0; 419 ifs = kcalloc(32, sizeof(*ifs), GFP_KERNEL); 420 if (ifs) { 421 nifs = afs_get_ipv4_interfaces(ifs, 32, false); 422 if (nifs < 0) { 423 kfree(ifs); 424 ifs = NULL; 425 nifs = 0; 426 } 427 } 428 429 memset(&reply, 0, sizeof(reply)); 430 reply.ia.nifs = htonl(nifs); 431 432 reply.ia.uuid[0] = htonl(afs_uuid.time_low); 433 reply.ia.uuid[1] = htonl(afs_uuid.time_mid); 434 reply.ia.uuid[2] = htonl(afs_uuid.time_hi_and_version); 435 reply.ia.uuid[3] = htonl((s8) afs_uuid.clock_seq_hi_and_reserved); 436 reply.ia.uuid[4] = htonl((s8) afs_uuid.clock_seq_low); 437 for (loop = 0; loop < 6; loop++) 438 reply.ia.uuid[loop + 5] = htonl((s8) afs_uuid.node[loop]); 439 440 if (ifs) { 441 for (loop = 0; loop < nifs; loop++) { 442 reply.ia.ifaddr[loop] = ifs[loop].address.s_addr; 443 reply.ia.netmask[loop] = ifs[loop].netmask.s_addr; 444 reply.ia.mtu[loop] = htonl(ifs[loop].mtu); 445 } 446 } 447 448 reply.cap.capcount = htonl(1); 449 reply.cap.caps[0] = htonl(AFS_CAP_ERROR_TRANSLATION); 450 afs_send_simple_reply(call, &reply, sizeof(reply)); 451 452 _leave(""); 453 } 454 455 /* 456 * deliver request data to a CB.GetCapabilities call 457 */ 458 static int afs_deliver_cb_get_capabilities(struct afs_call *call, 459 struct sk_buff *skb, bool last) 460 { 461 _enter(",{%u},%d", skb->len, last); 462 463 if (skb->len > 0) 464 return -EBADMSG; 465 if (!last) 466 return 0; 467 468 /* no unmarshalling required */ 469 call->state = AFS_CALL_REPLYING; 470 471 INIT_WORK(&call->work, SRXAFSCB_GetCapabilities); 472 schedule_work(&call->work); 473 return 0; 474 } 475