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/sched.h>
15 #include <linux/completion.h>
18 #include "transport.h"
19 #include <rxrpc/rxrpc.h>
20 #include <rxrpc/transport.h>
21 #include <rxrpc/connection.h>
22 #include <rxrpc/call.h>
23 #include "cmservice.h"
26 static unsigned afscm_usage
; /* AFS cache manager usage count */
27 static struct rw_semaphore afscm_sem
; /* AFS cache manager start/stop semaphore */
29 static int afscm_new_call(struct rxrpc_call
*call
);
30 static void afscm_attention(struct rxrpc_call
*call
);
31 static void afscm_error(struct rxrpc_call
*call
);
32 static void afscm_aemap(struct rxrpc_call
*call
);
34 static void _SRXAFSCM_CallBack(struct rxrpc_call
*call
);
35 static void _SRXAFSCM_InitCallBackState(struct rxrpc_call
*call
);
36 static void _SRXAFSCM_Probe(struct rxrpc_call
*call
);
38 typedef void (*_SRXAFSCM_xxxx_t
)(struct rxrpc_call
*call
);
40 static const struct rxrpc_operation AFSCM_ops
[] = {
43 .asize
= RXRPC_APP_MARK_EOF
,
45 .user
= _SRXAFSCM_CallBack
,
49 .asize
= RXRPC_APP_MARK_EOF
,
50 .name
= "InitCallBackState",
51 .user
= _SRXAFSCM_InitCallBackState
,
55 .asize
= RXRPC_APP_MARK_EOF
,
57 .user
= _SRXAFSCM_Probe
,
62 .asize
= RXRPC_APP_MARK_EOF
,
64 .user
= _SRXAFSCM_GetLock
,
68 .asize
= RXRPC_APP_MARK_EOF
,
70 .user
= _SRXAFSCM_GetCE
,
74 .asize
= RXRPC_APP_MARK_EOF
,
75 .name
= "GetXStatsVersion",
76 .user
= _SRXAFSCM_GetXStatsVersion
,
80 .asize
= RXRPC_APP_MARK_EOF
,
82 .user
= _SRXAFSCM_GetXStats
,
87 static struct rxrpc_service AFSCM_service
= {
90 .link
= LIST_HEAD_INIT(AFSCM_service
.link
),
91 .new_call
= afscm_new_call
,
93 .attn_func
= afscm_attention
,
94 .error_func
= afscm_error
,
95 .aemap_func
= afscm_aemap
,
96 .ops_begin
= &AFSCM_ops
[0],
97 .ops_end
= &AFSCM_ops
[ARRAY_SIZE(AFSCM_ops
)],
100 static DECLARE_COMPLETION(kafscmd_alive
);
101 static DECLARE_COMPLETION(kafscmd_dead
);
102 static DECLARE_WAIT_QUEUE_HEAD(kafscmd_sleepq
);
103 static LIST_HEAD(kafscmd_attention_list
);
104 static LIST_HEAD(afscm_calls
);
105 static DEFINE_SPINLOCK(afscm_calls_lock
);
106 static DEFINE_SPINLOCK(kafscmd_attention_lock
);
107 static int kafscmd_die
;
110 * AFS Cache Manager kernel thread
112 static int kafscmd(void *arg
)
114 DECLARE_WAITQUEUE(myself
, current
);
116 struct rxrpc_call
*call
;
117 _SRXAFSCM_xxxx_t func
;
120 printk(KERN_INFO
"kAFS: Started kafscmd %d\n", current
->pid
);
122 daemonize("kafscmd");
124 complete(&kafscmd_alive
);
126 /* loop around looking for things to attend to */
128 if (list_empty(&kafscmd_attention_list
)) {
129 set_current_state(TASK_INTERRUPTIBLE
);
130 add_wait_queue(&kafscmd_sleepq
, &myself
);
133 set_current_state(TASK_INTERRUPTIBLE
);
134 if (!list_empty(&kafscmd_attention_list
) ||
135 signal_pending(current
) ||
142 remove_wait_queue(&kafscmd_sleepq
, &myself
);
143 set_current_state(TASK_RUNNING
);
148 /* dequeue the next call requiring attention */
150 spin_lock(&kafscmd_attention_lock
);
152 if (!list_empty(&kafscmd_attention_list
)) {
153 call
= list_entry(kafscmd_attention_list
.next
,
156 list_del_init(&call
->app_attn_link
);
160 spin_unlock(&kafscmd_attention_lock
);
164 _debug("@@@ Begin Attend Call %p", call
);
166 func
= call
->app_user
;
170 rxrpc_put_call(call
);
172 _debug("@@@ End Attend Call %p", call
);
178 complete_and_exit(&kafscmd_dead
, 0);
182 * handle a call coming in to the cache manager
183 * - if I want to keep the call, I must increment its usage count
184 * - the return value will be negated and passed back in an abort packet if
186 * - serialised by virtue of there only being one krxiod
188 static int afscm_new_call(struct rxrpc_call
*call
)
190 _enter("%p{cid=%u u=%d}",
191 call
, ntohl(call
->call_id
), atomic_read(&call
->usage
));
193 rxrpc_get_call(call
);
195 /* add to my current call list */
196 spin_lock(&afscm_calls_lock
);
197 list_add(&call
->app_link
,&afscm_calls
);
198 spin_unlock(&afscm_calls_lock
);
205 * queue on the kafscmd queue for attention
207 static void afscm_attention(struct rxrpc_call
*call
)
209 _enter("%p{cid=%u u=%d}",
210 call
, ntohl(call
->call_id
), atomic_read(&call
->usage
));
212 spin_lock(&kafscmd_attention_lock
);
214 if (list_empty(&call
->app_attn_link
)) {
215 list_add_tail(&call
->app_attn_link
, &kafscmd_attention_list
);
216 rxrpc_get_call(call
);
219 spin_unlock(&kafscmd_attention_lock
);
221 wake_up(&kafscmd_sleepq
);
223 _leave(" {u=%d}", atomic_read(&call
->usage
));
227 * handle my call being aborted
228 * - clean up, dequeue and put my ref to the call
230 static void afscm_error(struct rxrpc_call
*call
)
234 _enter("%p{est=%s ac=%u er=%d}",
236 rxrpc_call_error_states
[call
->app_err_state
],
237 call
->app_abort_code
,
240 spin_lock(&kafscmd_attention_lock
);
242 if (list_empty(&call
->app_attn_link
)) {
243 list_add_tail(&call
->app_attn_link
, &kafscmd_attention_list
);
244 rxrpc_get_call(call
);
247 spin_unlock(&kafscmd_attention_lock
);
250 spin_lock(&afscm_calls_lock
);
251 if (!list_empty(&call
->app_link
)) {
252 list_del_init(&call
->app_link
);
255 spin_unlock(&afscm_calls_lock
);
258 rxrpc_put_call(call
);
260 wake_up(&kafscmd_sleepq
);
266 * map afs abort codes to/from Linux error codes
267 * - called with call->lock held
269 static void afscm_aemap(struct rxrpc_call
*call
)
271 switch (call
->app_err_state
) {
272 case RXRPC_ESTATE_LOCAL_ABORT
:
273 call
->app_abort_code
= -call
->app_errno
;
275 case RXRPC_ESTATE_PEER_ABORT
:
276 call
->app_errno
= -ECONNABORTED
;
284 * start the cache manager service if not already started
286 int afscm_start(void)
290 down_write(&afscm_sem
);
292 ret
= kernel_thread(kafscmd
, NULL
, 0);
296 wait_for_completion(&kafscmd_alive
);
298 ret
= rxrpc_add_service(afs_transport
, &AFSCM_service
);
302 afs_kafstimod_add_timer(&afs_mntpt_expiry_timer
,
303 afs_mntpt_expiry_timeout
* HZ
);
307 up_write(&afscm_sem
);
313 wake_up(&kafscmd_sleepq
);
314 wait_for_completion(&kafscmd_dead
);
317 up_write(&afscm_sem
);
322 * stop the cache manager service
324 void afscm_stop(void)
326 struct rxrpc_call
*call
;
328 down_write(&afscm_sem
);
330 BUG_ON(afscm_usage
== 0);
333 if (afscm_usage
== 0) {
334 /* don't want more incoming calls */
335 rxrpc_del_service(afs_transport
, &AFSCM_service
);
337 /* abort any calls I've still got open (the afscm_error() will
339 spin_lock(&afscm_calls_lock
);
340 while (!list_empty(&afscm_calls
)) {
341 call
= list_entry(afscm_calls
.next
,
345 list_del_init(&call
->app_link
);
346 rxrpc_get_call(call
);
347 spin_unlock(&afscm_calls_lock
);
349 rxrpc_call_abort(call
, -ESRCH
); /* abort, dequeue and
352 _debug("nuking active call %08x.%d",
353 ntohl(call
->conn
->conn_id
),
354 ntohl(call
->call_id
));
355 rxrpc_put_call(call
);
356 rxrpc_put_call(call
);
358 spin_lock(&afscm_calls_lock
);
360 spin_unlock(&afscm_calls_lock
);
362 /* get rid of my daemon */
364 wake_up(&kafscmd_sleepq
);
365 wait_for_completion(&kafscmd_dead
);
367 /* dispose of any calls waiting for attention */
368 spin_lock(&kafscmd_attention_lock
);
369 while (!list_empty(&kafscmd_attention_list
)) {
370 call
= list_entry(kafscmd_attention_list
.next
,
374 list_del_init(&call
->app_attn_link
);
375 spin_unlock(&kafscmd_attention_lock
);
377 rxrpc_put_call(call
);
379 spin_lock(&kafscmd_attention_lock
);
381 spin_unlock(&kafscmd_attention_lock
);
383 afs_kafstimod_del_timer(&afs_mntpt_expiry_timer
);
386 up_write(&afscm_sem
);
390 * handle the fileserver breaking a set of callbacks
392 static void _SRXAFSCM_CallBack(struct rxrpc_call
*call
)
394 struct afs_server
*server
;
395 size_t count
, qty
, tmp
;
396 int ret
= 0, removed
;
398 _enter("%p{acs=%s}", call
, rxrpc_call_states
[call
->app_call_state
]);
400 server
= afs_server_get_from_peer(call
->conn
->peer
);
402 switch (call
->app_call_state
) {
403 /* we've received the last packet
404 * - drain all the data from the call and send the reply
406 case RXRPC_CSTATE_SRVR_GOT_ARGS
:
408 qty
= call
->app_ready_qty
;
409 if (qty
< 8 || qty
> 50 * (6 * 4) + 8)
413 struct afs_callback
*cb
, *pcb
;
417 fp
= rxrpc_call_alloc_scratch(call
, qty
);
419 /* drag the entire argument block out to the scratch
421 ret
= rxrpc_call_read_data(call
, fp
, qty
, 0);
425 /* and unmarshall the parameter block */
427 count
= ntohl(*fp
++);
428 if (count
>AFSCBMAX
||
429 (count
* (3 * 4) + 8 != qty
&&
430 count
* (6 * 4) + 8 != qty
))
435 if (tmp
> 0 && tmp
!= count
)
440 pcb
= cb
= rxrpc_call_alloc_scratch_s(
441 call
, struct afs_callback
);
443 for (loop
= count
- 1; loop
>= 0; loop
--) {
444 pcb
->fid
.vid
= ntohl(*fp
++);
445 pcb
->fid
.vnode
= ntohl(*fp
++);
446 pcb
->fid
.unique
= ntohl(*fp
++);
448 pcb
->version
= ntohl(*bp
++);
449 pcb
->expiry
= ntohl(*bp
++);
450 pcb
->type
= ntohl(*bp
++);
454 pcb
->type
= AFSCM_CB_UNTYPED
;
459 /* invoke the actual service routine */
460 ret
= SRXAFSCM_CallBack(server
, count
, cb
);
466 ret
= rxrpc_call_write_data(call
, 0, NULL
, RXRPC_LAST_PACKET
,
467 GFP_KERNEL
, 0, &count
);
472 /* operation complete */
473 case RXRPC_CSTATE_COMPLETE
:
474 call
->app_user
= NULL
;
476 spin_lock(&afscm_calls_lock
);
477 if (!list_empty(&call
->app_link
)) {
478 list_del_init(&call
->app_link
);
481 spin_unlock(&afscm_calls_lock
);
484 rxrpc_put_call(call
);
487 /* operation terminated on error */
488 case RXRPC_CSTATE_ERROR
:
489 call
->app_user
= NULL
;
497 rxrpc_call_abort(call
, ret
);
499 afs_put_server(server
);
501 _leave(" = %d", ret
);
505 * handle the fileserver asking us to initialise our callback state
507 static void _SRXAFSCM_InitCallBackState(struct rxrpc_call
*call
)
509 struct afs_server
*server
;
511 int ret
= 0, removed
;
513 _enter("%p{acs=%s}", call
, rxrpc_call_states
[call
->app_call_state
]);
515 server
= afs_server_get_from_peer(call
->conn
->peer
);
517 switch (call
->app_call_state
) {
518 /* we've received the last packet - drain all the data from the
520 case RXRPC_CSTATE_SRVR_GOT_ARGS
:
521 /* shouldn't be any args */
525 /* send the reply when asked for it */
526 case RXRPC_CSTATE_SRVR_SND_REPLY
:
527 /* invoke the actual service routine */
528 ret
= SRXAFSCM_InitCallBackState(server
);
532 ret
= rxrpc_call_write_data(call
, 0, NULL
, RXRPC_LAST_PACKET
,
533 GFP_KERNEL
, 0, &count
);
538 /* operation complete */
539 case RXRPC_CSTATE_COMPLETE
:
540 call
->app_user
= NULL
;
542 spin_lock(&afscm_calls_lock
);
543 if (!list_empty(&call
->app_link
)) {
544 list_del_init(&call
->app_link
);
547 spin_unlock(&afscm_calls_lock
);
550 rxrpc_put_call(call
);
553 /* operation terminated on error */
554 case RXRPC_CSTATE_ERROR
:
555 call
->app_user
= NULL
;
563 rxrpc_call_abort(call
, ret
);
565 afs_put_server(server
);
567 _leave(" = %d", ret
);
571 * handle a probe from a fileserver
573 static void _SRXAFSCM_Probe(struct rxrpc_call
*call
)
575 struct afs_server
*server
;
577 int ret
= 0, removed
;
579 _enter("%p{acs=%s}", call
, rxrpc_call_states
[call
->app_call_state
]);
581 server
= afs_server_get_from_peer(call
->conn
->peer
);
583 switch (call
->app_call_state
) {
584 /* we've received the last packet - drain all the data from the
586 case RXRPC_CSTATE_SRVR_GOT_ARGS
:
587 /* shouldn't be any args */
591 /* send the reply when asked for it */
592 case RXRPC_CSTATE_SRVR_SND_REPLY
:
593 /* invoke the actual service routine */
594 ret
= SRXAFSCM_Probe(server
);
598 ret
= rxrpc_call_write_data(call
, 0, NULL
, RXRPC_LAST_PACKET
,
599 GFP_KERNEL
, 0, &count
);
604 /* operation complete */
605 case RXRPC_CSTATE_COMPLETE
:
606 call
->app_user
= NULL
;
608 spin_lock(&afscm_calls_lock
);
609 if (!list_empty(&call
->app_link
)) {
610 list_del_init(&call
->app_link
);
613 spin_unlock(&afscm_calls_lock
);
616 rxrpc_put_call(call
);
619 /* operation terminated on error */
620 case RXRPC_CSTATE_ERROR
:
621 call
->app_user
= NULL
;
629 rxrpc_call_abort(call
, ret
);
631 afs_put_server(server
);
633 _leave(" = %d", ret
);