ipc/shm: Fix shmat mmap nil-page protection
[cris-mirror.git] / fs / afs / cmservice.c
blob2edbdcbf6432add190464b5a5f414592953c944a
1 /* AFS Cache Manager Service
3 * Copyright (C) 2002 Red Hat, Inc. All Rights Reserved.
4 * Written by David Howells (dhowells@redhat.com)
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.
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"
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 static void SRXAFSCB_CallBack(struct work_struct *);
28 static void SRXAFSCB_InitCallBackState(struct work_struct *);
29 static void SRXAFSCB_Probe(struct work_struct *);
30 static void SRXAFSCB_ProbeUuid(struct work_struct *);
31 static void SRXAFSCB_TellMeAboutYourself(struct work_struct *);
33 #define CM_NAME(name) \
34 const char afs_SRXCB##name##_name[] __tracepoint_string = \
35 "CB." #name
38 * CB.CallBack operation type
40 static CM_NAME(CallBack);
41 static const struct afs_call_type afs_SRXCBCallBack = {
42 .name = afs_SRXCBCallBack_name,
43 .deliver = afs_deliver_cb_callback,
44 .abort_to_error = afs_abort_to_error,
45 .destructor = afs_cm_destructor,
46 .work = SRXAFSCB_CallBack,
50 * CB.InitCallBackState operation type
52 static CM_NAME(InitCallBackState);
53 static const struct afs_call_type afs_SRXCBInitCallBackState = {
54 .name = afs_SRXCBInitCallBackState_name,
55 .deliver = afs_deliver_cb_init_call_back_state,
56 .abort_to_error = afs_abort_to_error,
57 .destructor = afs_cm_destructor,
58 .work = SRXAFSCB_InitCallBackState,
62 * CB.InitCallBackState3 operation type
64 static CM_NAME(InitCallBackState3);
65 static const struct afs_call_type afs_SRXCBInitCallBackState3 = {
66 .name = afs_SRXCBInitCallBackState3_name,
67 .deliver = afs_deliver_cb_init_call_back_state3,
68 .abort_to_error = afs_abort_to_error,
69 .destructor = afs_cm_destructor,
70 .work = SRXAFSCB_InitCallBackState,
74 * CB.Probe operation type
76 static CM_NAME(Probe);
77 static const struct afs_call_type afs_SRXCBProbe = {
78 .name = afs_SRXCBProbe_name,
79 .deliver = afs_deliver_cb_probe,
80 .abort_to_error = afs_abort_to_error,
81 .destructor = afs_cm_destructor,
82 .work = SRXAFSCB_Probe,
86 * CB.ProbeUuid operation type
88 static CM_NAME(ProbeUuid);
89 static const struct afs_call_type afs_SRXCBProbeUuid = {
90 .name = afs_SRXCBProbeUuid_name,
91 .deliver = afs_deliver_cb_probe_uuid,
92 .abort_to_error = afs_abort_to_error,
93 .destructor = afs_cm_destructor,
94 .work = SRXAFSCB_ProbeUuid,
98 * CB.TellMeAboutYourself operation type
100 static CM_NAME(TellMeAboutYourself);
101 static const struct afs_call_type afs_SRXCBTellMeAboutYourself = {
102 .name = afs_SRXCBTellMeAboutYourself_name,
103 .deliver = afs_deliver_cb_tell_me_about_yourself,
104 .abort_to_error = afs_abort_to_error,
105 .destructor = afs_cm_destructor,
106 .work = SRXAFSCB_TellMeAboutYourself,
110 * route an incoming cache manager call
111 * - return T if supported, F if not
113 bool afs_cm_incoming_call(struct afs_call *call)
115 _enter("{CB.OP %u}", call->operation_ID);
117 switch (call->operation_ID) {
118 case CBCallBack:
119 call->type = &afs_SRXCBCallBack;
120 return true;
121 case CBInitCallBackState:
122 call->type = &afs_SRXCBInitCallBackState;
123 return true;
124 case CBInitCallBackState3:
125 call->type = &afs_SRXCBInitCallBackState3;
126 return true;
127 case CBProbe:
128 call->type = &afs_SRXCBProbe;
129 return true;
130 case CBTellMeAboutYourself:
131 call->type = &afs_SRXCBTellMeAboutYourself;
132 return true;
133 default:
134 return false;
139 * clean up a cache manager call
141 static void afs_cm_destructor(struct afs_call *call)
143 _enter("");
145 /* Break the callbacks here so that we do it after the final ACK is
146 * received. The step number here must match the final number in
147 * afs_deliver_cb_callback().
149 if (call->unmarshall == 5) {
150 ASSERT(call->server && call->count && call->request);
151 afs_break_callbacks(call->server, call->count, call->request);
154 afs_put_server(call->server);
155 call->server = NULL;
156 kfree(call->buffer);
157 call->buffer = NULL;
161 * allow the fileserver to see if the cache manager is still alive
163 static void SRXAFSCB_CallBack(struct work_struct *work)
165 struct afs_call *call = container_of(work, struct afs_call, work);
167 _enter("");
169 /* be sure to send the reply *before* attempting to spam the AFS server
170 * with FSFetchStatus requests on the vnodes with broken callbacks lest
171 * the AFS server get into a vicious cycle of trying to break further
172 * callbacks because it hadn't received completion of the CBCallBack op
173 * yet */
174 afs_send_empty_reply(call);
176 afs_break_callbacks(call->server, call->count, call->request);
177 afs_put_call(call);
178 _leave("");
182 * deliver request data to a CB.CallBack call
184 static int afs_deliver_cb_callback(struct afs_call *call)
186 struct sockaddr_rxrpc srx;
187 struct afs_callback *cb;
188 struct afs_server *server;
189 __be32 *bp;
190 u32 tmp;
191 int ret, loop;
193 _enter("{%u}", call->unmarshall);
195 switch (call->unmarshall) {
196 case 0:
197 rxrpc_kernel_get_peer(afs_socket, call->rxcall, &srx);
198 call->offset = 0;
199 call->unmarshall++;
201 /* extract the FID array and its count in two steps */
202 case 1:
203 _debug("extract FID count");
204 ret = afs_extract_data(call, &call->tmp, 4, true);
205 if (ret < 0)
206 return ret;
208 call->count = ntohl(call->tmp);
209 _debug("FID count: %u", call->count);
210 if (call->count > AFSCBMAX)
211 return -EBADMSG;
213 call->buffer = kmalloc(call->count * 3 * 4, GFP_KERNEL);
214 if (!call->buffer)
215 return -ENOMEM;
216 call->offset = 0;
217 call->unmarshall++;
219 case 2:
220 _debug("extract FID array");
221 ret = afs_extract_data(call, call->buffer,
222 call->count * 3 * 4, true);
223 if (ret < 0)
224 return ret;
226 _debug("unmarshall FID array");
227 call->request = kcalloc(call->count,
228 sizeof(struct afs_callback),
229 GFP_KERNEL);
230 if (!call->request)
231 return -ENOMEM;
233 cb = call->request;
234 bp = call->buffer;
235 for (loop = call->count; loop > 0; loop--, cb++) {
236 cb->fid.vid = ntohl(*bp++);
237 cb->fid.vnode = ntohl(*bp++);
238 cb->fid.unique = ntohl(*bp++);
239 cb->type = AFSCM_CB_UNTYPED;
242 call->offset = 0;
243 call->unmarshall++;
245 /* extract the callback array and its count in two steps */
246 case 3:
247 _debug("extract CB count");
248 ret = afs_extract_data(call, &call->tmp, 4, true);
249 if (ret < 0)
250 return ret;
252 tmp = ntohl(call->tmp);
253 _debug("CB count: %u", tmp);
254 if (tmp != call->count && tmp != 0)
255 return -EBADMSG;
256 call->offset = 0;
257 call->unmarshall++;
259 case 4:
260 _debug("extract CB array");
261 ret = afs_extract_data(call, call->buffer,
262 call->count * 3 * 4, false);
263 if (ret < 0)
264 return ret;
266 _debug("unmarshall CB array");
267 cb = call->request;
268 bp = call->buffer;
269 for (loop = call->count; loop > 0; loop--, cb++) {
270 cb->version = ntohl(*bp++);
271 cb->expiry = ntohl(*bp++);
272 cb->type = ntohl(*bp++);
275 call->offset = 0;
276 call->unmarshall++;
278 /* Record that the message was unmarshalled successfully so
279 * that the call destructor can know do the callback breaking
280 * work, even if the final ACK isn't received.
282 * If the step number changes, then afs_cm_destructor() must be
283 * updated also.
285 call->unmarshall++;
286 case 5:
287 break;
290 call->state = AFS_CALL_REPLYING;
292 /* we'll need the file server record as that tells us which set of
293 * vnodes to operate upon */
294 server = afs_find_server(&srx);
295 if (!server)
296 return -ENOTCONN;
297 call->server = server;
299 return afs_queue_call_work(call);
303 * allow the fileserver to request callback state (re-)initialisation
305 static void SRXAFSCB_InitCallBackState(struct work_struct *work)
307 struct afs_call *call = container_of(work, struct afs_call, work);
309 _enter("{%p}", call->server);
311 afs_init_callback_state(call->server);
312 afs_send_empty_reply(call);
313 afs_put_call(call);
314 _leave("");
318 * deliver request data to a CB.InitCallBackState call
320 static int afs_deliver_cb_init_call_back_state(struct afs_call *call)
322 struct sockaddr_rxrpc srx;
323 struct afs_server *server;
324 int ret;
326 _enter("");
328 rxrpc_kernel_get_peer(afs_socket, call->rxcall, &srx);
330 ret = afs_extract_data(call, NULL, 0, false);
331 if (ret < 0)
332 return ret;
334 /* no unmarshalling required */
335 call->state = AFS_CALL_REPLYING;
337 /* we'll need the file server record as that tells us which set of
338 * vnodes to operate upon */
339 server = afs_find_server(&srx);
340 if (!server)
341 return -ENOTCONN;
342 call->server = server;
344 return afs_queue_call_work(call);
348 * deliver request data to a CB.InitCallBackState3 call
350 static int afs_deliver_cb_init_call_back_state3(struct afs_call *call)
352 struct sockaddr_rxrpc srx;
353 struct afs_server *server;
354 struct uuid_v1 *r;
355 unsigned loop;
356 __be32 *b;
357 int ret;
359 _enter("");
361 rxrpc_kernel_get_peer(afs_socket, call->rxcall, &srx);
363 _enter("{%u}", call->unmarshall);
365 switch (call->unmarshall) {
366 case 0:
367 call->offset = 0;
368 call->buffer = kmalloc(11 * sizeof(__be32), GFP_KERNEL);
369 if (!call->buffer)
370 return -ENOMEM;
371 call->unmarshall++;
373 case 1:
374 _debug("extract UUID");
375 ret = afs_extract_data(call, call->buffer,
376 11 * sizeof(__be32), false);
377 switch (ret) {
378 case 0: break;
379 case -EAGAIN: return 0;
380 default: return ret;
383 _debug("unmarshall UUID");
384 call->request = kmalloc(sizeof(struct uuid_v1), GFP_KERNEL);
385 if (!call->request)
386 return -ENOMEM;
388 b = call->buffer;
389 r = call->request;
390 r->time_low = b[0];
391 r->time_mid = htons(ntohl(b[1]));
392 r->time_hi_and_version = htons(ntohl(b[2]));
393 r->clock_seq_hi_and_reserved = ntohl(b[3]);
394 r->clock_seq_low = ntohl(b[4]);
396 for (loop = 0; loop < 6; loop++)
397 r->node[loop] = ntohl(b[loop + 5]);
399 call->offset = 0;
400 call->unmarshall++;
402 case 2:
403 break;
406 /* no unmarshalling required */
407 call->state = AFS_CALL_REPLYING;
409 /* we'll need the file server record as that tells us which set of
410 * vnodes to operate upon */
411 server = afs_find_server(&srx);
412 if (!server)
413 return -ENOTCONN;
414 call->server = server;
416 return afs_queue_call_work(call);
420 * allow the fileserver to see if the cache manager is still alive
422 static void SRXAFSCB_Probe(struct work_struct *work)
424 struct afs_call *call = container_of(work, struct afs_call, work);
426 _enter("");
427 afs_send_empty_reply(call);
428 afs_put_call(call);
429 _leave("");
433 * deliver request data to a CB.Probe call
435 static int afs_deliver_cb_probe(struct afs_call *call)
437 int ret;
439 _enter("");
441 ret = afs_extract_data(call, NULL, 0, false);
442 if (ret < 0)
443 return ret;
445 /* no unmarshalling required */
446 call->state = AFS_CALL_REPLYING;
448 return afs_queue_call_work(call);
452 * allow the fileserver to quickly find out if the fileserver has been rebooted
454 static void SRXAFSCB_ProbeUuid(struct work_struct *work)
456 struct afs_call *call = container_of(work, struct afs_call, work);
457 struct uuid_v1 *r = call->request;
459 struct {
460 __be32 match;
461 } reply;
463 _enter("");
465 if (memcmp(r, &afs_uuid, sizeof(afs_uuid)) == 0)
466 reply.match = htonl(0);
467 else
468 reply.match = htonl(1);
470 afs_send_simple_reply(call, &reply, sizeof(reply));
471 afs_put_call(call);
472 _leave("");
476 * deliver request data to a CB.ProbeUuid call
478 static int afs_deliver_cb_probe_uuid(struct afs_call *call)
480 struct uuid_v1 *r;
481 unsigned loop;
482 __be32 *b;
483 int ret;
485 _enter("{%u}", call->unmarshall);
487 switch (call->unmarshall) {
488 case 0:
489 call->offset = 0;
490 call->buffer = kmalloc(11 * sizeof(__be32), GFP_KERNEL);
491 if (!call->buffer)
492 return -ENOMEM;
493 call->unmarshall++;
495 case 1:
496 _debug("extract UUID");
497 ret = afs_extract_data(call, call->buffer,
498 11 * sizeof(__be32), false);
499 switch (ret) {
500 case 0: break;
501 case -EAGAIN: return 0;
502 default: return ret;
505 _debug("unmarshall UUID");
506 call->request = kmalloc(sizeof(struct uuid_v1), GFP_KERNEL);
507 if (!call->request)
508 return -ENOMEM;
510 b = call->buffer;
511 r = call->request;
512 r->time_low = b[0];
513 r->time_mid = htons(ntohl(b[1]));
514 r->time_hi_and_version = htons(ntohl(b[2]));
515 r->clock_seq_hi_and_reserved = ntohl(b[3]);
516 r->clock_seq_low = ntohl(b[4]);
518 for (loop = 0; loop < 6; loop++)
519 r->node[loop] = ntohl(b[loop + 5]);
521 call->offset = 0;
522 call->unmarshall++;
524 case 2:
525 break;
528 call->state = AFS_CALL_REPLYING;
530 return afs_queue_call_work(call);
534 * allow the fileserver to ask about the cache manager's capabilities
536 static void SRXAFSCB_TellMeAboutYourself(struct work_struct *work)
538 struct afs_interface *ifs;
539 struct afs_call *call = container_of(work, struct afs_call, work);
540 int loop, nifs;
542 struct {
543 struct /* InterfaceAddr */ {
544 __be32 nifs;
545 __be32 uuid[11];
546 __be32 ifaddr[32];
547 __be32 netmask[32];
548 __be32 mtu[32];
549 } ia;
550 struct /* Capabilities */ {
551 __be32 capcount;
552 __be32 caps[1];
553 } cap;
554 } reply;
556 _enter("");
558 nifs = 0;
559 ifs = kcalloc(32, sizeof(*ifs), GFP_KERNEL);
560 if (ifs) {
561 nifs = afs_get_ipv4_interfaces(ifs, 32, false);
562 if (nifs < 0) {
563 kfree(ifs);
564 ifs = NULL;
565 nifs = 0;
569 memset(&reply, 0, sizeof(reply));
570 reply.ia.nifs = htonl(nifs);
572 reply.ia.uuid[0] = afs_uuid.time_low;
573 reply.ia.uuid[1] = htonl(ntohs(afs_uuid.time_mid));
574 reply.ia.uuid[2] = htonl(ntohs(afs_uuid.time_hi_and_version));
575 reply.ia.uuid[3] = htonl((s8) afs_uuid.clock_seq_hi_and_reserved);
576 reply.ia.uuid[4] = htonl((s8) afs_uuid.clock_seq_low);
577 for (loop = 0; loop < 6; loop++)
578 reply.ia.uuid[loop + 5] = htonl((s8) afs_uuid.node[loop]);
580 if (ifs) {
581 for (loop = 0; loop < nifs; loop++) {
582 reply.ia.ifaddr[loop] = ifs[loop].address.s_addr;
583 reply.ia.netmask[loop] = ifs[loop].netmask.s_addr;
584 reply.ia.mtu[loop] = htonl(ifs[loop].mtu);
586 kfree(ifs);
589 reply.cap.capcount = htonl(1);
590 reply.cap.caps[0] = htonl(AFS_CAP_ERROR_TRANSLATION);
591 afs_send_simple_reply(call, &reply, sizeof(reply));
592 afs_put_call(call);
593 _leave("");
597 * deliver request data to a CB.TellMeAboutYourself call
599 static int afs_deliver_cb_tell_me_about_yourself(struct afs_call *call)
601 int ret;
603 _enter("");
605 ret = afs_extract_data(call, NULL, 0, false);
606 if (ret < 0)
607 return ret;
609 /* no unmarshalling required */
610 call->state = AFS_CALL_REPLYING;
612 return afs_queue_call_work(call);