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 #ifdef AFS_AUTOMOUNT_SUPPORT
311 afs_kafstimod_add_timer(&afs_mntpt_expiry_timer,
312 afs_mntpt_expiry_timeout * HZ);
317 up_write(&afscm_sem);
323 wake_up(&kafscmd_sleepq);
324 wait_for_completion(&kafscmd_dead);
327 up_write(&afscm_sem);
330 } /* end afscm_start() */
332 /*****************************************************************************/
334 * stop the cache manager service
336 void afscm_stop(void)
338 struct rxrpc_call *call;
340 down_write(&afscm_sem);
342 BUG_ON(afscm_usage == 0);
345 if (afscm_usage == 0) {
346 /* don't want more incoming calls */
347 rxrpc_del_service(afs_transport, &AFSCM_service);
349 /* abort any calls I've still got open (the afscm_error() will
351 spin_lock(&afscm_calls_lock);
352 while (!list_empty(&afscm_calls)) {
353 call = list_entry(afscm_calls.next,
357 list_del_init(&call->app_link);
358 rxrpc_get_call(call);
359 spin_unlock(&afscm_calls_lock);
361 rxrpc_call_abort(call, -ESRCH); /* abort, dequeue and
364 _debug("nuking active call %08x.%d",
365 ntohl(call->conn->conn_id),
366 ntohl(call->call_id));
367 rxrpc_put_call(call);
368 rxrpc_put_call(call);
370 spin_lock(&afscm_calls_lock);
372 spin_unlock(&afscm_calls_lock);
374 /* get rid of my daemon */
376 wake_up(&kafscmd_sleepq);
377 wait_for_completion(&kafscmd_dead);
379 /* dispose of any calls waiting for attention */
380 spin_lock(&kafscmd_attention_lock);
381 while (!list_empty(&kafscmd_attention_list)) {
382 call = list_entry(kafscmd_attention_list.next,
386 list_del_init(&call->app_attn_link);
387 spin_unlock(&kafscmd_attention_lock);
389 rxrpc_put_call(call);
391 spin_lock(&kafscmd_attention_lock);
393 spin_unlock(&kafscmd_attention_lock);
395 #ifdef AFS_AUTOMOUNT_SUPPORT
396 afs_kafstimod_del_timer(&afs_mntpt_expiry_timer);
400 up_write(&afscm_sem);
402 } /* end afscm_stop() */
404 /*****************************************************************************/
406 * handle the fileserver breaking a set of callbacks
408 static void _SRXAFSCM_CallBack(struct rxrpc_call *call)
410 struct afs_server *server;
411 size_t count, qty, tmp;
412 int ret = 0, removed;
414 _enter("%p{acs=%s}", call, rxrpc_call_states[call->app_call_state]);
416 server = afs_server_get_from_peer(call->conn->peer);
418 switch (call->app_call_state) {
419 /* we've received the last packet
420 * - drain all the data from the call and send the reply
422 case RXRPC_CSTATE_SRVR_GOT_ARGS:
424 qty = call->app_ready_qty;
425 if (qty < 8 || qty > 50 * (6 * 4) + 8)
429 struct afs_callback *cb, *pcb;
433 fp = rxrpc_call_alloc_scratch(call, qty);
435 /* drag the entire argument block out to the scratch
437 ret = rxrpc_call_read_data(call, fp, qty, 0);
441 /* and unmarshall the parameter block */
443 count = ntohl(*fp++);
444 if (count>AFSCBMAX ||
445 (count * (3 * 4) + 8 != qty &&
446 count * (6 * 4) + 8 != qty))
451 if (tmp > 0 && tmp != count)
456 pcb = cb = rxrpc_call_alloc_scratch_s(
457 call, struct afs_callback);
459 for (loop = count - 1; loop >= 0; loop--) {
460 pcb->fid.vid = ntohl(*fp++);
461 pcb->fid.vnode = ntohl(*fp++);
462 pcb->fid.unique = ntohl(*fp++);
464 pcb->version = ntohl(*bp++);
465 pcb->expiry = ntohl(*bp++);
466 pcb->type = ntohl(*bp++);
471 pcb->type = AFSCM_CB_UNTYPED;
476 /* invoke the actual service routine */
477 ret = SRXAFSCM_CallBack(server, count, cb);
483 ret = rxrpc_call_write_data(call, 0, NULL, RXRPC_LAST_PACKET,
484 GFP_KERNEL, 0, &count);
489 /* operation complete */
490 case RXRPC_CSTATE_COMPLETE:
491 call->app_user = NULL;
493 spin_lock(&afscm_calls_lock);
494 if (!list_empty(&call->app_link)) {
495 list_del_init(&call->app_link);
498 spin_unlock(&afscm_calls_lock);
501 rxrpc_put_call(call);
504 /* operation terminated on error */
505 case RXRPC_CSTATE_ERROR:
506 call->app_user = NULL;
514 rxrpc_call_abort(call, ret);
516 afs_put_server(server);
518 _leave(" = %d", ret);
520 } /* end _SRXAFSCM_CallBack() */
522 /*****************************************************************************/
524 * handle the fileserver asking us to initialise our callback state
526 static void _SRXAFSCM_InitCallBackState(struct rxrpc_call *call)
528 struct afs_server *server;
530 int ret = 0, removed;
532 _enter("%p{acs=%s}", call, rxrpc_call_states[call->app_call_state]);
534 server = afs_server_get_from_peer(call->conn->peer);
536 switch (call->app_call_state) {
537 /* we've received the last packet - drain all the data from the
539 case RXRPC_CSTATE_SRVR_GOT_ARGS:
540 /* shouldn't be any args */
544 /* send the reply when asked for it */
545 case RXRPC_CSTATE_SRVR_SND_REPLY:
546 /* invoke the actual service routine */
547 ret = SRXAFSCM_InitCallBackState(server);
551 ret = rxrpc_call_write_data(call, 0, NULL, RXRPC_LAST_PACKET,
552 GFP_KERNEL, 0, &count);
557 /* operation complete */
558 case RXRPC_CSTATE_COMPLETE:
559 call->app_user = NULL;
561 spin_lock(&afscm_calls_lock);
562 if (!list_empty(&call->app_link)) {
563 list_del_init(&call->app_link);
566 spin_unlock(&afscm_calls_lock);
569 rxrpc_put_call(call);
572 /* operation terminated on error */
573 case RXRPC_CSTATE_ERROR:
574 call->app_user = NULL;
582 rxrpc_call_abort(call, ret);
584 afs_put_server(server);
586 _leave(" = %d", ret);
588 } /* end _SRXAFSCM_InitCallBackState() */
590 /*****************************************************************************/
592 * handle a probe from a fileserver
594 static void _SRXAFSCM_Probe(struct rxrpc_call *call)
596 struct afs_server *server;
598 int ret = 0, removed;
600 _enter("%p{acs=%s}", call, rxrpc_call_states[call->app_call_state]);
602 server = afs_server_get_from_peer(call->conn->peer);
604 switch (call->app_call_state) {
605 /* we've received the last packet - drain all the data from the
607 case RXRPC_CSTATE_SRVR_GOT_ARGS:
608 /* shouldn't be any args */
612 /* send the reply when asked for it */
613 case RXRPC_CSTATE_SRVR_SND_REPLY:
614 /* invoke the actual service routine */
615 ret = SRXAFSCM_Probe(server);
619 ret = rxrpc_call_write_data(call, 0, NULL, RXRPC_LAST_PACKET,
620 GFP_KERNEL, 0, &count);
625 /* operation complete */
626 case RXRPC_CSTATE_COMPLETE:
627 call->app_user = NULL;
629 spin_lock(&afscm_calls_lock);
630 if (!list_empty(&call->app_link)) {
631 list_del_init(&call->app_link);
634 spin_unlock(&afscm_calls_lock);
637 rxrpc_put_call(call);
640 /* operation terminated on error */
641 case RXRPC_CSTATE_ERROR:
642 call->app_user = NULL;
650 rxrpc_call_abort(call, ret);
652 afs_put_server(server);
654 _leave(" = %d", ret);
656 } /* end _SRXAFSCM_Probe() */