OSDN Git Service

Merge tag 'efi-urgent' of git://git.kernel.org/pub/scm/linux/kernel/git/efi/efi into...
[uclinux-h8/linux.git] / fs / afs / cmservice.c
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 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 *);
32
33 #define CM_NAME(name) \
34         const char afs_SRXCB##name##_name[] __tracepoint_string =       \
35                 "CB." #name
36
37 /*
38  * CB.CallBack operation type
39  */
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,
47 };
48
49 /*
50  * CB.InitCallBackState operation type
51  */
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,
59 };
60
61 /*
62  * CB.InitCallBackState3 operation type
63  */
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,
71 };
72
73 /*
74  * CB.Probe operation type
75  */
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,
83 };
84
85 /*
86  * CB.ProbeUuid operation type
87  */
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,
95 };
96
97 /*
98  * CB.TellMeAboutYourself operation type
99  */
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,
107 };
108
109 /*
110  * route an incoming cache manager call
111  * - return T if supported, F if not
112  */
113 bool afs_cm_incoming_call(struct afs_call *call)
114 {
115         _enter("{CB.OP %u}", call->operation_ID);
116
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;
135         }
136 }
137
138 /*
139  * clean up a cache manager call
140  */
141 static void afs_cm_destructor(struct afs_call *call)
142 {
143         _enter("");
144
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().
148          */
149         if (call->unmarshall == 5) {
150                 ASSERT(call->server && call->count && call->request);
151                 afs_break_callbacks(call->server, call->count, call->request);
152         }
153
154         afs_put_server(call->server);
155         call->server = NULL;
156         kfree(call->buffer);
157         call->buffer = NULL;
158 }
159
160 /*
161  * allow the fileserver to see if the cache manager is still alive
162  */
163 static void SRXAFSCB_CallBack(struct work_struct *work)
164 {
165         struct afs_call *call = container_of(work, struct afs_call, work);
166
167         _enter("");
168
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);
175
176         afs_break_callbacks(call->server, call->count, call->request);
177         afs_put_call(call);
178         _leave("");
179 }
180
181 /*
182  * deliver request data to a CB.CallBack call
183  */
184 static int afs_deliver_cb_callback(struct afs_call *call)
185 {
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;
192
193         _enter("{%u}", call->unmarshall);
194
195         switch (call->unmarshall) {
196         case 0:
197                 rxrpc_kernel_get_peer(afs_socket, call->rxcall, &srx);
198                 call->offset = 0;
199                 call->unmarshall++;
200
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;
207
208                 call->count = ntohl(call->tmp);
209                 _debug("FID count: %u", call->count);
210                 if (call->count > AFSCBMAX)
211                         return -EBADMSG;
212
213                 call->buffer = kmalloc(call->count * 3 * 4, GFP_KERNEL);
214                 if (!call->buffer)
215                         return -ENOMEM;
216                 call->offset = 0;
217                 call->unmarshall++;
218
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;
225
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;
232
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;
240                 }
241
242                 call->offset = 0;
243                 call->unmarshall++;
244
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;
251
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++;
258
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;
265
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++);
273                 }
274
275                 call->offset = 0;
276                 call->unmarshall++;
277
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.
281                  *
282                  * If the step number changes, then afs_cm_destructor() must be
283                  * updated also.
284                  */
285                 call->unmarshall++;
286         case 5:
287                 break;
288         }
289
290         call->state = AFS_CALL_REPLYING;
291
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;
298
299         return afs_queue_call_work(call);
300 }
301
302 /*
303  * allow the fileserver to request callback state (re-)initialisation
304  */
305 static void SRXAFSCB_InitCallBackState(struct work_struct *work)
306 {
307         struct afs_call *call = container_of(work, struct afs_call, work);
308
309         _enter("{%p}", call->server);
310
311         afs_init_callback_state(call->server);
312         afs_send_empty_reply(call);
313         afs_put_call(call);
314         _leave("");
315 }
316
317 /*
318  * deliver request data to a CB.InitCallBackState call
319  */
320 static int afs_deliver_cb_init_call_back_state(struct afs_call *call)
321 {
322         struct sockaddr_rxrpc srx;
323         struct afs_server *server;
324         int ret;
325
326         _enter("");
327
328         rxrpc_kernel_get_peer(afs_socket, call->rxcall, &srx);
329
330         ret = afs_extract_data(call, NULL, 0, false);
331         if (ret < 0)
332                 return ret;
333
334         /* no unmarshalling required */
335         call->state = AFS_CALL_REPLYING;
336
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;
343
344         return afs_queue_call_work(call);
345 }
346
347 /*
348  * deliver request data to a CB.InitCallBackState3 call
349  */
350 static int afs_deliver_cb_init_call_back_state3(struct afs_call *call)
351 {
352         struct sockaddr_rxrpc srx;
353         struct afs_server *server;
354         struct uuid_v1 *r;
355         unsigned loop;
356         __be32 *b;
357         int ret;
358
359         _enter("");
360
361         rxrpc_kernel_get_peer(afs_socket, call->rxcall, &srx);
362
363         _enter("{%u}", call->unmarshall);
364
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++;
372
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;
381                 }
382
383                 _debug("unmarshall UUID");
384                 call->request = kmalloc(sizeof(struct uuid_v1), GFP_KERNEL);
385                 if (!call->request)
386                         return -ENOMEM;
387
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]);
395
396                 for (loop = 0; loop < 6; loop++)
397                         r->node[loop] = ntohl(b[loop + 5]);
398
399                 call->offset = 0;
400                 call->unmarshall++;
401
402         case 2:
403                 break;
404         }
405
406         /* no unmarshalling required */
407         call->state = AFS_CALL_REPLYING;
408
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;
415
416         return afs_queue_call_work(call);
417 }
418
419 /*
420  * allow the fileserver to see if the cache manager is still alive
421  */
422 static void SRXAFSCB_Probe(struct work_struct *work)
423 {
424         struct afs_call *call = container_of(work, struct afs_call, work);
425
426         _enter("");
427         afs_send_empty_reply(call);
428         afs_put_call(call);
429         _leave("");
430 }
431
432 /*
433  * deliver request data to a CB.Probe call
434  */
435 static int afs_deliver_cb_probe(struct afs_call *call)
436 {
437         int ret;
438
439         _enter("");
440
441         ret = afs_extract_data(call, NULL, 0, false);
442         if (ret < 0)
443                 return ret;
444
445         /* no unmarshalling required */
446         call->state = AFS_CALL_REPLYING;
447
448         return afs_queue_call_work(call);
449 }
450
451 /*
452  * allow the fileserver to quickly find out if the fileserver has been rebooted
453  */
454 static void SRXAFSCB_ProbeUuid(struct work_struct *work)
455 {
456         struct afs_call *call = container_of(work, struct afs_call, work);
457         struct uuid_v1 *r = call->request;
458
459         struct {
460                 __be32  match;
461         } reply;
462
463         _enter("");
464
465         if (memcmp(r, &afs_uuid, sizeof(afs_uuid)) == 0)
466                 reply.match = htonl(0);
467         else
468                 reply.match = htonl(1);
469
470         afs_send_simple_reply(call, &reply, sizeof(reply));
471         afs_put_call(call);
472         _leave("");
473 }
474
475 /*
476  * deliver request data to a CB.ProbeUuid call
477  */
478 static int afs_deliver_cb_probe_uuid(struct afs_call *call)
479 {
480         struct uuid_v1 *r;
481         unsigned loop;
482         __be32 *b;
483         int ret;
484
485         _enter("{%u}", call->unmarshall);
486
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++;
494
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;
503                 }
504
505                 _debug("unmarshall UUID");
506                 call->request = kmalloc(sizeof(struct uuid_v1), GFP_KERNEL);
507                 if (!call->request)
508                         return -ENOMEM;
509
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]);
517
518                 for (loop = 0; loop < 6; loop++)
519                         r->node[loop] = ntohl(b[loop + 5]);
520
521                 call->offset = 0;
522                 call->unmarshall++;
523
524         case 2:
525                 break;
526         }
527
528         call->state = AFS_CALL_REPLYING;
529
530         return afs_queue_call_work(call);
531 }
532
533 /*
534  * allow the fileserver to ask about the cache manager's capabilities
535  */
536 static void SRXAFSCB_TellMeAboutYourself(struct work_struct *work)
537 {
538         struct afs_interface *ifs;
539         struct afs_call *call = container_of(work, struct afs_call, work);
540         int loop, nifs;
541
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;
555
556         _enter("");
557
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;
566                 }
567         }
568
569         memset(&reply, 0, sizeof(reply));
570         reply.ia.nifs = htonl(nifs);
571
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]);
579
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);
585                 }
586                 kfree(ifs);
587         }
588
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("");
594 }
595
596 /*
597  * deliver request data to a CB.TellMeAboutYourself call
598  */
599 static int afs_deliver_cb_tell_me_about_yourself(struct afs_call *call)
600 {
601         int ret;
602
603         _enter("");
604
605         ret = afs_extract_data(call, NULL, 0, false);
606         if (ret < 0)
607                 return ret;
608
609         /* no unmarshalling required */
610         call->state = AFS_CALL_REPLYING;
611
612         return afs_queue_call_work(call);
613 }