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>
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
*);
29 * CB.CallBack operation type
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
,
39 * CB.InitCallBackState operation type
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
,
49 * CB.InitCallBackState3 operation type
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
,
59 * CB.Probe operation type
61 static const struct afs_call_type afs_SRXCBProbe
= {
63 .deliver
= afs_deliver_cb_probe
,
64 .abort_to_error
= afs_abort_to_error
,
65 .destructor
= afs_cm_destructor
,
69 * CB.ProbeUuid operation type
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
,
79 * CB.TellMeAboutYourself operation type
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
,
89 * route an incoming cache manager call
90 * - return T if supported, F if not
92 bool afs_cm_incoming_call(struct afs_call
*call
)
94 u32 operation_id
= ntohl(call
->operation_ID
);
96 _enter("{CB.OP %u}", operation_id
);
98 switch (operation_id
) {
100 call
->type
= &afs_SRXCBCallBack
;
102 case CBInitCallBackState
:
103 call
->type
= &afs_SRXCBInitCallBackState
;
105 case CBInitCallBackState3
:
106 call
->type
= &afs_SRXCBInitCallBackState3
;
109 call
->type
= &afs_SRXCBProbe
;
111 case CBTellMeAboutYourself
:
112 call
->type
= &afs_SRXCBTellMeAboutYourself
;
120 * clean up a cache manager call
122 static void afs_cm_destructor(struct afs_call
*call
)
126 /* Break the callbacks here so that we do it after the final ACK is
127 * received. The step number here must match the final number in
128 * afs_deliver_cb_callback().
130 if (call
->unmarshall
== 5) {
131 ASSERT(call
->server
&& call
->count
&& call
->request
);
132 afs_break_callbacks(call
->server
, call
->count
, call
->request
);
135 afs_put_server(call
->server
);
142 * allow the fileserver to see if the cache manager is still alive
144 static void SRXAFSCB_CallBack(struct work_struct
*work
)
146 struct afs_call
*call
= container_of(work
, struct afs_call
, work
);
150 /* be sure to send the reply *before* attempting to spam the AFS server
151 * with FSFetchStatus requests on the vnodes with broken callbacks lest
152 * the AFS server get into a vicious cycle of trying to break further
153 * callbacks because it hadn't received completion of the CBCallBack op
155 afs_send_empty_reply(call
);
157 afs_break_callbacks(call
->server
, call
->count
, call
->request
);
162 * deliver request data to a CB.CallBack call
164 static int afs_deliver_cb_callback(struct afs_call
*call
)
166 struct sockaddr_rxrpc srx
;
167 struct afs_callback
*cb
;
168 struct afs_server
*server
;
173 _enter("{%u}", call
->unmarshall
);
175 switch (call
->unmarshall
) {
177 rxrpc_kernel_get_peer(afs_socket
, call
->rxcall
, &srx
);
181 /* extract the FID array and its count in two steps */
183 _debug("extract FID count");
184 ret
= afs_extract_data(call
, &call
->tmp
, 4, true);
188 call
->count
= ntohl(call
->tmp
);
189 _debug("FID count: %u", call
->count
);
190 if (call
->count
> AFSCBMAX
)
193 call
->buffer
= kmalloc(call
->count
* 3 * 4, GFP_KERNEL
);
200 _debug("extract FID array");
201 ret
= afs_extract_data(call
, call
->buffer
,
202 call
->count
* 3 * 4, true);
206 _debug("unmarshall FID array");
207 call
->request
= kcalloc(call
->count
,
208 sizeof(struct afs_callback
),
215 for (loop
= call
->count
; loop
> 0; loop
--, cb
++) {
216 cb
->fid
.vid
= ntohl(*bp
++);
217 cb
->fid
.vnode
= ntohl(*bp
++);
218 cb
->fid
.unique
= ntohl(*bp
++);
219 cb
->type
= AFSCM_CB_UNTYPED
;
225 /* extract the callback array and its count in two steps */
227 _debug("extract CB count");
228 ret
= afs_extract_data(call
, &call
->tmp
, 4, true);
232 tmp
= ntohl(call
->tmp
);
233 _debug("CB count: %u", tmp
);
234 if (tmp
!= call
->count
&& tmp
!= 0)
240 _debug("extract CB array");
241 ret
= afs_extract_data(call
, call
->buffer
,
242 call
->count
* 3 * 4, false);
246 _debug("unmarshall CB array");
249 for (loop
= call
->count
; loop
> 0; loop
--, cb
++) {
250 cb
->version
= ntohl(*bp
++);
251 cb
->expiry
= ntohl(*bp
++);
252 cb
->type
= ntohl(*bp
++);
258 /* Record that the message was unmarshalled successfully so
259 * that the call destructor can know do the callback breaking
260 * work, even if the final ACK isn't received.
262 * If the step number changes, then afs_cm_destructor() must be
270 call
->state
= AFS_CALL_REPLYING
;
272 /* we'll need the file server record as that tells us which set of
273 * vnodes to operate upon */
274 server
= afs_find_server(&srx
);
277 call
->server
= server
;
279 INIT_WORK(&call
->work
, SRXAFSCB_CallBack
);
280 queue_work(afs_wq
, &call
->work
);
285 * allow the fileserver to request callback state (re-)initialisation
287 static void SRXAFSCB_InitCallBackState(struct work_struct
*work
)
289 struct afs_call
*call
= container_of(work
, struct afs_call
, work
);
291 _enter("{%p}", call
->server
);
293 afs_init_callback_state(call
->server
);
294 afs_send_empty_reply(call
);
299 * deliver request data to a CB.InitCallBackState call
301 static int afs_deliver_cb_init_call_back_state(struct afs_call
*call
)
303 struct sockaddr_rxrpc srx
;
304 struct afs_server
*server
;
309 rxrpc_kernel_get_peer(afs_socket
, call
->rxcall
, &srx
);
311 ret
= afs_extract_data(call
, NULL
, 0, false);
315 /* no unmarshalling required */
316 call
->state
= AFS_CALL_REPLYING
;
318 /* we'll need the file server record as that tells us which set of
319 * vnodes to operate upon */
320 server
= afs_find_server(&srx
);
323 call
->server
= server
;
325 INIT_WORK(&call
->work
, SRXAFSCB_InitCallBackState
);
326 queue_work(afs_wq
, &call
->work
);
331 * deliver request data to a CB.InitCallBackState3 call
333 static int afs_deliver_cb_init_call_back_state3(struct afs_call
*call
)
335 struct sockaddr_rxrpc srx
;
336 struct afs_server
*server
;
344 rxrpc_kernel_get_peer(afs_socket
, call
->rxcall
, &srx
);
346 _enter("{%u}", call
->unmarshall
);
348 switch (call
->unmarshall
) {
351 call
->buffer
= kmalloc(11 * sizeof(__be32
), GFP_KERNEL
);
357 _debug("extract UUID");
358 ret
= afs_extract_data(call
, call
->buffer
,
359 11 * sizeof(__be32
), false);
362 case -EAGAIN
: return 0;
366 _debug("unmarshall UUID");
367 call
->request
= kmalloc(sizeof(struct afs_uuid
), GFP_KERNEL
);
373 r
->time_low
= ntohl(b
[0]);
374 r
->time_mid
= ntohl(b
[1]);
375 r
->time_hi_and_version
= ntohl(b
[2]);
376 r
->clock_seq_hi_and_reserved
= ntohl(b
[3]);
377 r
->clock_seq_low
= ntohl(b
[4]);
379 for (loop
= 0; loop
< 6; loop
++)
380 r
->node
[loop
] = ntohl(b
[loop
+ 5]);
389 /* no unmarshalling required */
390 call
->state
= AFS_CALL_REPLYING
;
392 /* we'll need the file server record as that tells us which set of
393 * vnodes to operate upon */
394 server
= afs_find_server(&srx
);
397 call
->server
= server
;
399 INIT_WORK(&call
->work
, SRXAFSCB_InitCallBackState
);
400 queue_work(afs_wq
, &call
->work
);
405 * allow the fileserver to see if the cache manager is still alive
407 static void SRXAFSCB_Probe(struct work_struct
*work
)
409 struct afs_call
*call
= container_of(work
, struct afs_call
, work
);
412 afs_send_empty_reply(call
);
417 * deliver request data to a CB.Probe call
419 static int afs_deliver_cb_probe(struct afs_call
*call
)
425 ret
= afs_extract_data(call
, NULL
, 0, false);
429 /* no unmarshalling required */
430 call
->state
= AFS_CALL_REPLYING
;
432 INIT_WORK(&call
->work
, SRXAFSCB_Probe
);
433 queue_work(afs_wq
, &call
->work
);
438 * allow the fileserver to quickly find out if the fileserver has been rebooted
440 static void SRXAFSCB_ProbeUuid(struct work_struct
*work
)
442 struct afs_call
*call
= container_of(work
, struct afs_call
, work
);
443 struct afs_uuid
*r
= call
->request
;
451 if (memcmp(r
, &afs_uuid
, sizeof(afs_uuid
)) == 0)
452 reply
.match
= htonl(0);
454 reply
.match
= htonl(1);
456 afs_send_simple_reply(call
, &reply
, sizeof(reply
));
461 * deliver request data to a CB.ProbeUuid call
463 static int afs_deliver_cb_probe_uuid(struct afs_call
*call
)
470 _enter("{%u}", call
->unmarshall
);
472 switch (call
->unmarshall
) {
475 call
->buffer
= kmalloc(11 * sizeof(__be32
), GFP_KERNEL
);
481 _debug("extract UUID");
482 ret
= afs_extract_data(call
, call
->buffer
,
483 11 * sizeof(__be32
), false);
486 case -EAGAIN
: return 0;
490 _debug("unmarshall UUID");
491 call
->request
= kmalloc(sizeof(struct afs_uuid
), GFP_KERNEL
);
497 r
->time_low
= ntohl(b
[0]);
498 r
->time_mid
= ntohl(b
[1]);
499 r
->time_hi_and_version
= ntohl(b
[2]);
500 r
->clock_seq_hi_and_reserved
= ntohl(b
[3]);
501 r
->clock_seq_low
= ntohl(b
[4]);
503 for (loop
= 0; loop
< 6; loop
++)
504 r
->node
[loop
] = ntohl(b
[loop
+ 5]);
513 call
->state
= AFS_CALL_REPLYING
;
515 INIT_WORK(&call
->work
, SRXAFSCB_ProbeUuid
);
516 queue_work(afs_wq
, &call
->work
);
521 * allow the fileserver to ask about the cache manager's capabilities
523 static void SRXAFSCB_TellMeAboutYourself(struct work_struct
*work
)
525 struct afs_interface
*ifs
;
526 struct afs_call
*call
= container_of(work
, struct afs_call
, work
);
530 struct /* InterfaceAddr */ {
537 struct /* Capabilities */ {
546 ifs
= kcalloc(32, sizeof(*ifs
), GFP_KERNEL
);
548 nifs
= afs_get_ipv4_interfaces(ifs
, 32, false);
556 memset(&reply
, 0, sizeof(reply
));
557 reply
.ia
.nifs
= htonl(nifs
);
559 reply
.ia
.uuid
[0] = htonl(afs_uuid
.time_low
);
560 reply
.ia
.uuid
[1] = htonl(afs_uuid
.time_mid
);
561 reply
.ia
.uuid
[2] = htonl(afs_uuid
.time_hi_and_version
);
562 reply
.ia
.uuid
[3] = htonl((s8
) afs_uuid
.clock_seq_hi_and_reserved
);
563 reply
.ia
.uuid
[4] = htonl((s8
) afs_uuid
.clock_seq_low
);
564 for (loop
= 0; loop
< 6; loop
++)
565 reply
.ia
.uuid
[loop
+ 5] = htonl((s8
) afs_uuid
.node
[loop
]);
568 for (loop
= 0; loop
< nifs
; loop
++) {
569 reply
.ia
.ifaddr
[loop
] = ifs
[loop
].address
.s_addr
;
570 reply
.ia
.netmask
[loop
] = ifs
[loop
].netmask
.s_addr
;
571 reply
.ia
.mtu
[loop
] = htonl(ifs
[loop
].mtu
);
576 reply
.cap
.capcount
= htonl(1);
577 reply
.cap
.caps
[0] = htonl(AFS_CAP_ERROR_TRANSLATION
);
578 afs_send_simple_reply(call
, &reply
, sizeof(reply
));
584 * deliver request data to a CB.TellMeAboutYourself call
586 static int afs_deliver_cb_tell_me_about_yourself(struct afs_call
*call
)
592 ret
= afs_extract_data(call
, NULL
, 0, false);
596 /* no unmarshalling required */
597 call
->state
= AFS_CALL_REPLYING
;
599 INIT_WORK(&call
->work
, SRXAFSCB_TellMeAboutYourself
);
600 queue_work(afs_wq
, &call
->work
);