1 /* cmservice.c: 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
[sizeof(AFSCM_ops
) / sizeof(AFSCM_ops
[0])],
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 spinlock_t afscm_calls_lock
= SPIN_LOCK_UNLOCKED
;
106 static spinlock_t kafscmd_attention_lock
= SPIN_LOCK_UNLOCKED
;
107 static int kafscmd_die
;
109 /*****************************************************************************/
111 * AFS Cache Manager kernel thread
113 static int kafscmd(void *arg
)
115 DECLARE_WAITQUEUE(myself
, current
);
117 struct rxrpc_call
*call
;
118 _SRXAFSCM_xxxx_t func
;
121 printk("kAFS: Started kafscmd %d\n", current
->pid
);
123 daemonize("kafscmd");
125 complete(&kafscmd_alive
);
127 /* loop around looking for things to attend to */
129 if (list_empty(&kafscmd_attention_list
)) {
130 set_current_state(TASK_INTERRUPTIBLE
);
131 add_wait_queue(&kafscmd_sleepq
, &myself
);
134 set_current_state(TASK_INTERRUPTIBLE
);
135 if (!list_empty(&kafscmd_attention_list
) ||
136 signal_pending(current
) ||
143 remove_wait_queue(&kafscmd_sleepq
, &myself
);
144 set_current_state(TASK_RUNNING
);
149 /* dequeue the next call requiring attention */
151 spin_lock(&kafscmd_attention_lock
);
153 if (!list_empty(&kafscmd_attention_list
)) {
154 call
= list_entry(kafscmd_attention_list
.next
,
157 list_del_init(&call
->app_attn_link
);
161 spin_unlock(&kafscmd_attention_lock
);
165 _debug("@@@ Begin Attend Call %p", call
);
167 func
= call
->app_user
;
171 rxrpc_put_call(call
);
173 _debug("@@@ End Attend Call %p", call
);
179 complete_and_exit(&kafscmd_dead
, 0);
181 } /* end kafscmd() */
183 /*****************************************************************************/
185 * handle a call coming in to the cache manager
186 * - if I want to keep the call, I must increment its usage count
187 * - the return value will be negated and passed back in an abort packet if
189 * - serialised by virtue of there only being one krxiod
191 static int afscm_new_call(struct rxrpc_call
*call
)
193 _enter("%p{cid=%u u=%d}",
194 call
, ntohl(call
->call_id
), atomic_read(&call
->usage
));
196 rxrpc_get_call(call
);
198 /* add to my current call list */
199 spin_lock(&afscm_calls_lock
);
200 list_add(&call
->app_link
,&afscm_calls
);
201 spin_unlock(&afscm_calls_lock
);
206 } /* end afscm_new_call() */
208 /*****************************************************************************/
210 * queue on the kafscmd queue for attention
212 static void afscm_attention(struct rxrpc_call
*call
)
214 _enter("%p{cid=%u u=%d}",
215 call
, ntohl(call
->call_id
), atomic_read(&call
->usage
));
217 spin_lock(&kafscmd_attention_lock
);
219 if (list_empty(&call
->app_attn_link
)) {
220 list_add_tail(&call
->app_attn_link
, &kafscmd_attention_list
);
221 rxrpc_get_call(call
);
224 spin_unlock(&kafscmd_attention_lock
);
226 wake_up(&kafscmd_sleepq
);
228 _leave(" {u=%d}", atomic_read(&call
->usage
));
229 } /* end afscm_attention() */
231 /*****************************************************************************/
233 * handle my call being aborted
234 * - clean up, dequeue and put my ref to the call
236 static void afscm_error(struct rxrpc_call
*call
)
240 _enter("%p{est=%s ac=%u er=%d}",
242 rxrpc_call_error_states
[call
->app_err_state
],
243 call
->app_abort_code
,
246 spin_lock(&kafscmd_attention_lock
);
248 if (list_empty(&call
->app_attn_link
)) {
249 list_add_tail(&call
->app_attn_link
, &kafscmd_attention_list
);
250 rxrpc_get_call(call
);
253 spin_unlock(&kafscmd_attention_lock
);
256 spin_lock(&afscm_calls_lock
);
257 if (!list_empty(&call
->app_link
)) {
258 list_del_init(&call
->app_link
);
261 spin_unlock(&afscm_calls_lock
);
264 rxrpc_put_call(call
);
266 wake_up(&kafscmd_sleepq
);
269 } /* end afscm_error() */
271 /*****************************************************************************/
273 * map afs abort codes to/from Linux error codes
274 * - called with call->lock held
276 static void afscm_aemap(struct rxrpc_call
*call
)
278 switch (call
->app_err_state
) {
279 case RXRPC_ESTATE_LOCAL_ABORT
:
280 call
->app_abort_code
= -call
->app_errno
;
282 case RXRPC_ESTATE_PEER_ABORT
:
283 call
->app_errno
= -ECONNABORTED
;
288 } /* end afscm_aemap() */
290 /*****************************************************************************/
292 * start the cache manager service if not already started
294 int afscm_start(void)
298 down_write(&afscm_sem
);
300 ret
= kernel_thread(kafscmd
, NULL
, 0);
304 wait_for_completion(&kafscmd_alive
);
306 ret
= rxrpc_add_service(afs_transport
, &AFSCM_service
);
310 afs_kafstimod_add_timer(&afs_mntpt_expiry_timer
,
311 afs_mntpt_expiry_timeout
* HZ
);
315 up_write(&afscm_sem
);
321 wake_up(&kafscmd_sleepq
);
322 wait_for_completion(&kafscmd_dead
);
325 up_write(&afscm_sem
);
328 } /* end afscm_start() */
330 /*****************************************************************************/
332 * stop the cache manager service
334 void afscm_stop(void)
336 struct rxrpc_call
*call
;
338 down_write(&afscm_sem
);
340 BUG_ON(afscm_usage
== 0);
343 if (afscm_usage
== 0) {
344 /* don't want more incoming calls */
345 rxrpc_del_service(afs_transport
, &AFSCM_service
);
347 /* abort any calls I've still got open (the afscm_error() will
349 spin_lock(&afscm_calls_lock
);
350 while (!list_empty(&afscm_calls
)) {
351 call
= list_entry(afscm_calls
.next
,
355 list_del_init(&call
->app_link
);
356 rxrpc_get_call(call
);
357 spin_unlock(&afscm_calls_lock
);
359 rxrpc_call_abort(call
, -ESRCH
); /* abort, dequeue and
362 _debug("nuking active call %08x.%d",
363 ntohl(call
->conn
->conn_id
),
364 ntohl(call
->call_id
));
365 rxrpc_put_call(call
);
366 rxrpc_put_call(call
);
368 spin_lock(&afscm_calls_lock
);
370 spin_unlock(&afscm_calls_lock
);
372 /* get rid of my daemon */
374 wake_up(&kafscmd_sleepq
);
375 wait_for_completion(&kafscmd_dead
);
377 /* dispose of any calls waiting for attention */
378 spin_lock(&kafscmd_attention_lock
);
379 while (!list_empty(&kafscmd_attention_list
)) {
380 call
= list_entry(kafscmd_attention_list
.next
,
384 list_del_init(&call
->app_attn_link
);
385 spin_unlock(&kafscmd_attention_lock
);
387 rxrpc_put_call(call
);
389 spin_lock(&kafscmd_attention_lock
);
391 spin_unlock(&kafscmd_attention_lock
);
393 afs_kafstimod_del_timer(&afs_mntpt_expiry_timer
);
396 up_write(&afscm_sem
);
398 } /* end afscm_stop() */
400 /*****************************************************************************/
402 * handle the fileserver breaking a set of callbacks
404 static void _SRXAFSCM_CallBack(struct rxrpc_call
*call
)
406 struct afs_server
*server
;
407 size_t count
, qty
, tmp
;
408 int ret
= 0, removed
;
410 _enter("%p{acs=%s}", call
, rxrpc_call_states
[call
->app_call_state
]);
412 server
= afs_server_get_from_peer(call
->conn
->peer
);
414 switch (call
->app_call_state
) {
415 /* we've received the last packet
416 * - drain all the data from the call and send the reply
418 case RXRPC_CSTATE_SRVR_GOT_ARGS
:
420 qty
= call
->app_ready_qty
;
421 if (qty
< 8 || qty
> 50 * (6 * 4) + 8)
425 struct afs_callback
*cb
, *pcb
;
429 fp
= rxrpc_call_alloc_scratch(call
, qty
);
431 /* drag the entire argument block out to the scratch
433 ret
= rxrpc_call_read_data(call
, fp
, qty
, 0);
437 /* and unmarshall the parameter block */
439 count
= ntohl(*fp
++);
440 if (count
>AFSCBMAX
||
441 (count
* (3 * 4) + 8 != qty
&&
442 count
* (6 * 4) + 8 != qty
))
447 if (tmp
> 0 && tmp
!= count
)
452 pcb
= cb
= rxrpc_call_alloc_scratch_s(
453 call
, struct afs_callback
);
455 for (loop
= count
- 1; loop
>= 0; loop
--) {
456 pcb
->fid
.vid
= ntohl(*fp
++);
457 pcb
->fid
.vnode
= ntohl(*fp
++);
458 pcb
->fid
.unique
= ntohl(*fp
++);
460 pcb
->version
= ntohl(*bp
++);
461 pcb
->expiry
= ntohl(*bp
++);
462 pcb
->type
= ntohl(*bp
++);
467 pcb
->type
= AFSCM_CB_UNTYPED
;
472 /* invoke the actual service routine */
473 ret
= SRXAFSCM_CallBack(server
, count
, cb
);
479 ret
= rxrpc_call_write_data(call
, 0, NULL
, RXRPC_LAST_PACKET
,
480 GFP_KERNEL
, 0, &count
);
485 /* operation complete */
486 case RXRPC_CSTATE_COMPLETE
:
487 call
->app_user
= NULL
;
489 spin_lock(&afscm_calls_lock
);
490 if (!list_empty(&call
->app_link
)) {
491 list_del_init(&call
->app_link
);
494 spin_unlock(&afscm_calls_lock
);
497 rxrpc_put_call(call
);
500 /* operation terminated on error */
501 case RXRPC_CSTATE_ERROR
:
502 call
->app_user
= NULL
;
510 rxrpc_call_abort(call
, ret
);
512 afs_put_server(server
);
514 _leave(" = %d", ret
);
516 } /* end _SRXAFSCM_CallBack() */
518 /*****************************************************************************/
520 * handle the fileserver asking us to initialise our callback state
522 static void _SRXAFSCM_InitCallBackState(struct rxrpc_call
*call
)
524 struct afs_server
*server
;
526 int ret
= 0, removed
;
528 _enter("%p{acs=%s}", call
, rxrpc_call_states
[call
->app_call_state
]);
530 server
= afs_server_get_from_peer(call
->conn
->peer
);
532 switch (call
->app_call_state
) {
533 /* we've received the last packet - drain all the data from the
535 case RXRPC_CSTATE_SRVR_GOT_ARGS
:
536 /* shouldn't be any args */
540 /* send the reply when asked for it */
541 case RXRPC_CSTATE_SRVR_SND_REPLY
:
542 /* invoke the actual service routine */
543 ret
= SRXAFSCM_InitCallBackState(server
);
547 ret
= rxrpc_call_write_data(call
, 0, NULL
, RXRPC_LAST_PACKET
,
548 GFP_KERNEL
, 0, &count
);
553 /* operation complete */
554 case RXRPC_CSTATE_COMPLETE
:
555 call
->app_user
= NULL
;
557 spin_lock(&afscm_calls_lock
);
558 if (!list_empty(&call
->app_link
)) {
559 list_del_init(&call
->app_link
);
562 spin_unlock(&afscm_calls_lock
);
565 rxrpc_put_call(call
);
568 /* operation terminated on error */
569 case RXRPC_CSTATE_ERROR
:
570 call
->app_user
= NULL
;
578 rxrpc_call_abort(call
, ret
);
580 afs_put_server(server
);
582 _leave(" = %d", ret
);
584 } /* end _SRXAFSCM_InitCallBackState() */
586 /*****************************************************************************/
588 * handle a probe from a fileserver
590 static void _SRXAFSCM_Probe(struct rxrpc_call
*call
)
592 struct afs_server
*server
;
594 int ret
= 0, removed
;
596 _enter("%p{acs=%s}", call
, rxrpc_call_states
[call
->app_call_state
]);
598 server
= afs_server_get_from_peer(call
->conn
->peer
);
600 switch (call
->app_call_state
) {
601 /* we've received the last packet - drain all the data from the
603 case RXRPC_CSTATE_SRVR_GOT_ARGS
:
604 /* shouldn't be any args */
608 /* send the reply when asked for it */
609 case RXRPC_CSTATE_SRVR_SND_REPLY
:
610 /* invoke the actual service routine */
611 ret
= SRXAFSCM_Probe(server
);
615 ret
= rxrpc_call_write_data(call
, 0, NULL
, RXRPC_LAST_PACKET
,
616 GFP_KERNEL
, 0, &count
);
621 /* operation complete */
622 case RXRPC_CSTATE_COMPLETE
:
623 call
->app_user
= NULL
;
625 spin_lock(&afscm_calls_lock
);
626 if (!list_empty(&call
->app_link
)) {
627 list_del_init(&call
->app_link
);
630 spin_unlock(&afscm_calls_lock
);
633 rxrpc_put_call(call
);
636 /* operation terminated on error */
637 case RXRPC_CSTATE_ERROR
:
638 call
->app_user
= NULL
;
646 rxrpc_call_abort(call
, ret
);
648 afs_put_server(server
);
650 _leave(" = %d", ret
);
652 } /* end _SRXAFSCM_Probe() */