]> git.proxmox.com Git - mirror_ubuntu-zesty-kernel.git/blob - fs/afs/cmservice.c
Linux-2.6.12-rc2
[mirror_ubuntu-zesty-kernel.git] / fs / afs / cmservice.c
1 /* cmservice.c: 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/sched.h>
15 #include <linux/completion.h>
16 #include "server.h"
17 #include "cell.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"
24 #include "internal.h"
25
26 static unsigned afscm_usage; /* AFS cache manager usage count */
27 static struct rw_semaphore afscm_sem; /* AFS cache manager start/stop semaphore */
28
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);
33
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);
37
38 typedef void (*_SRXAFSCM_xxxx_t)(struct rxrpc_call *call);
39
40 static const struct rxrpc_operation AFSCM_ops[] = {
41 {
42 .id = 204,
43 .asize = RXRPC_APP_MARK_EOF,
44 .name = "CallBack",
45 .user = _SRXAFSCM_CallBack,
46 },
47 {
48 .id = 205,
49 .asize = RXRPC_APP_MARK_EOF,
50 .name = "InitCallBackState",
51 .user = _SRXAFSCM_InitCallBackState,
52 },
53 {
54 .id = 206,
55 .asize = RXRPC_APP_MARK_EOF,
56 .name = "Probe",
57 .user = _SRXAFSCM_Probe,
58 },
59 #if 0
60 {
61 .id = 207,
62 .asize = RXRPC_APP_MARK_EOF,
63 .name = "GetLock",
64 .user = _SRXAFSCM_GetLock,
65 },
66 {
67 .id = 208,
68 .asize = RXRPC_APP_MARK_EOF,
69 .name = "GetCE",
70 .user = _SRXAFSCM_GetCE,
71 },
72 {
73 .id = 209,
74 .asize = RXRPC_APP_MARK_EOF,
75 .name = "GetXStatsVersion",
76 .user = _SRXAFSCM_GetXStatsVersion,
77 },
78 {
79 .id = 210,
80 .asize = RXRPC_APP_MARK_EOF,
81 .name = "GetXStats",
82 .user = _SRXAFSCM_GetXStats,
83 }
84 #endif
85 };
86
87 static struct rxrpc_service AFSCM_service = {
88 .name = "AFS/CM",
89 .owner = THIS_MODULE,
90 .link = LIST_HEAD_INIT(AFSCM_service.link),
91 .new_call = afscm_new_call,
92 .service_id = 1,
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])],
98 };
99
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;
108
109 /*****************************************************************************/
110 /*
111 * AFS Cache Manager kernel thread
112 */
113 static int kafscmd(void *arg)
114 {
115 DECLARE_WAITQUEUE(myself, current);
116
117 struct rxrpc_call *call;
118 _SRXAFSCM_xxxx_t func;
119 int die;
120
121 printk("kAFS: Started kafscmd %d\n", current->pid);
122
123 daemonize("kafscmd");
124
125 complete(&kafscmd_alive);
126
127 /* loop around looking for things to attend to */
128 do {
129 if (list_empty(&kafscmd_attention_list)) {
130 set_current_state(TASK_INTERRUPTIBLE);
131 add_wait_queue(&kafscmd_sleepq, &myself);
132
133 for (;;) {
134 set_current_state(TASK_INTERRUPTIBLE);
135 if (!list_empty(&kafscmd_attention_list) ||
136 signal_pending(current) ||
137 kafscmd_die)
138 break;
139
140 schedule();
141 }
142
143 remove_wait_queue(&kafscmd_sleepq, &myself);
144 set_current_state(TASK_RUNNING);
145 }
146
147 die = kafscmd_die;
148
149 /* dequeue the next call requiring attention */
150 call = NULL;
151 spin_lock(&kafscmd_attention_lock);
152
153 if (!list_empty(&kafscmd_attention_list)) {
154 call = list_entry(kafscmd_attention_list.next,
155 struct rxrpc_call,
156 app_attn_link);
157 list_del_init(&call->app_attn_link);
158 die = 0;
159 }
160
161 spin_unlock(&kafscmd_attention_lock);
162
163 if (call) {
164 /* act upon it */
165 _debug("@@@ Begin Attend Call %p", call);
166
167 func = call->app_user;
168 if (func)
169 func(call);
170
171 rxrpc_put_call(call);
172
173 _debug("@@@ End Attend Call %p", call);
174 }
175
176 } while(!die);
177
178 /* and that's all */
179 complete_and_exit(&kafscmd_dead, 0);
180
181 } /* end kafscmd() */
182
183 /*****************************************************************************/
184 /*
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
188 * non-zero
189 * - serialised by virtue of there only being one krxiod
190 */
191 static int afscm_new_call(struct rxrpc_call *call)
192 {
193 _enter("%p{cid=%u u=%d}",
194 call, ntohl(call->call_id), atomic_read(&call->usage));
195
196 rxrpc_get_call(call);
197
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);
202
203 _leave(" = 0");
204 return 0;
205
206 } /* end afscm_new_call() */
207
208 /*****************************************************************************/
209 /*
210 * queue on the kafscmd queue for attention
211 */
212 static void afscm_attention(struct rxrpc_call *call)
213 {
214 _enter("%p{cid=%u u=%d}",
215 call, ntohl(call->call_id), atomic_read(&call->usage));
216
217 spin_lock(&kafscmd_attention_lock);
218
219 if (list_empty(&call->app_attn_link)) {
220 list_add_tail(&call->app_attn_link, &kafscmd_attention_list);
221 rxrpc_get_call(call);
222 }
223
224 spin_unlock(&kafscmd_attention_lock);
225
226 wake_up(&kafscmd_sleepq);
227
228 _leave(" {u=%d}", atomic_read(&call->usage));
229 } /* end afscm_attention() */
230
231 /*****************************************************************************/
232 /*
233 * handle my call being aborted
234 * - clean up, dequeue and put my ref to the call
235 */
236 static void afscm_error(struct rxrpc_call *call)
237 {
238 int removed;
239
240 _enter("%p{est=%s ac=%u er=%d}",
241 call,
242 rxrpc_call_error_states[call->app_err_state],
243 call->app_abort_code,
244 call->app_errno);
245
246 spin_lock(&kafscmd_attention_lock);
247
248 if (list_empty(&call->app_attn_link)) {
249 list_add_tail(&call->app_attn_link, &kafscmd_attention_list);
250 rxrpc_get_call(call);
251 }
252
253 spin_unlock(&kafscmd_attention_lock);
254
255 removed = 0;
256 spin_lock(&afscm_calls_lock);
257 if (!list_empty(&call->app_link)) {
258 list_del_init(&call->app_link);
259 removed = 1;
260 }
261 spin_unlock(&afscm_calls_lock);
262
263 if (removed)
264 rxrpc_put_call(call);
265
266 wake_up(&kafscmd_sleepq);
267
268 _leave("");
269 } /* end afscm_error() */
270
271 /*****************************************************************************/
272 /*
273 * map afs abort codes to/from Linux error codes
274 * - called with call->lock held
275 */
276 static void afscm_aemap(struct rxrpc_call *call)
277 {
278 switch (call->app_err_state) {
279 case RXRPC_ESTATE_LOCAL_ABORT:
280 call->app_abort_code = -call->app_errno;
281 break;
282 case RXRPC_ESTATE_PEER_ABORT:
283 call->app_errno = -ECONNABORTED;
284 break;
285 default:
286 break;
287 }
288 } /* end afscm_aemap() */
289
290 /*****************************************************************************/
291 /*
292 * start the cache manager service if not already started
293 */
294 int afscm_start(void)
295 {
296 int ret;
297
298 down_write(&afscm_sem);
299 if (!afscm_usage) {
300 ret = kernel_thread(kafscmd, NULL, 0);
301 if (ret < 0)
302 goto out;
303
304 wait_for_completion(&kafscmd_alive);
305
306 ret = rxrpc_add_service(afs_transport, &AFSCM_service);
307 if (ret < 0)
308 goto kill;
309
310 afs_kafstimod_add_timer(&afs_mntpt_expiry_timer,
311 afs_mntpt_expiry_timeout * HZ);
312 }
313
314 afscm_usage++;
315 up_write(&afscm_sem);
316
317 return 0;
318
319 kill:
320 kafscmd_die = 1;
321 wake_up(&kafscmd_sleepq);
322 wait_for_completion(&kafscmd_dead);
323
324 out:
325 up_write(&afscm_sem);
326 return ret;
327
328 } /* end afscm_start() */
329
330 /*****************************************************************************/
331 /*
332 * stop the cache manager service
333 */
334 void afscm_stop(void)
335 {
336 struct rxrpc_call *call;
337
338 down_write(&afscm_sem);
339
340 BUG_ON(afscm_usage == 0);
341 afscm_usage--;
342
343 if (afscm_usage == 0) {
344 /* don't want more incoming calls */
345 rxrpc_del_service(afs_transport, &AFSCM_service);
346
347 /* abort any calls I've still got open (the afscm_error() will
348 * dequeue them) */
349 spin_lock(&afscm_calls_lock);
350 while (!list_empty(&afscm_calls)) {
351 call = list_entry(afscm_calls.next,
352 struct rxrpc_call,
353 app_link);
354
355 list_del_init(&call->app_link);
356 rxrpc_get_call(call);
357 spin_unlock(&afscm_calls_lock);
358
359 rxrpc_call_abort(call, -ESRCH); /* abort, dequeue and
360 * put */
361
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);
367
368 spin_lock(&afscm_calls_lock);
369 }
370 spin_unlock(&afscm_calls_lock);
371
372 /* get rid of my daemon */
373 kafscmd_die = 1;
374 wake_up(&kafscmd_sleepq);
375 wait_for_completion(&kafscmd_dead);
376
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,
381 struct rxrpc_call,
382 app_attn_link);
383
384 list_del_init(&call->app_attn_link);
385 spin_unlock(&kafscmd_attention_lock);
386
387 rxrpc_put_call(call);
388
389 spin_lock(&kafscmd_attention_lock);
390 }
391 spin_unlock(&kafscmd_attention_lock);
392
393 afs_kafstimod_del_timer(&afs_mntpt_expiry_timer);
394 }
395
396 up_write(&afscm_sem);
397
398 } /* end afscm_stop() */
399
400 /*****************************************************************************/
401 /*
402 * handle the fileserver breaking a set of callbacks
403 */
404 static void _SRXAFSCM_CallBack(struct rxrpc_call *call)
405 {
406 struct afs_server *server;
407 size_t count, qty, tmp;
408 int ret = 0, removed;
409
410 _enter("%p{acs=%s}", call, rxrpc_call_states[call->app_call_state]);
411
412 server = afs_server_get_from_peer(call->conn->peer);
413
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
417 */
418 case RXRPC_CSTATE_SRVR_GOT_ARGS:
419 ret = -EBADMSG;
420 qty = call->app_ready_qty;
421 if (qty < 8 || qty > 50 * (6 * 4) + 8)
422 break;
423
424 {
425 struct afs_callback *cb, *pcb;
426 int loop;
427 __be32 *fp, *bp;
428
429 fp = rxrpc_call_alloc_scratch(call, qty);
430
431 /* drag the entire argument block out to the scratch
432 * space */
433 ret = rxrpc_call_read_data(call, fp, qty, 0);
434 if (ret < 0)
435 break;
436
437 /* and unmarshall the parameter block */
438 ret = -EBADMSG;
439 count = ntohl(*fp++);
440 if (count>AFSCBMAX ||
441 (count * (3 * 4) + 8 != qty &&
442 count * (6 * 4) + 8 != qty))
443 break;
444
445 bp = fp + count*3;
446 tmp = ntohl(*bp++);
447 if (tmp > 0 && tmp != count)
448 break;
449 if (tmp == 0)
450 bp = NULL;
451
452 pcb = cb = rxrpc_call_alloc_scratch_s(
453 call, struct afs_callback);
454
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++);
459 if (bp) {
460 pcb->version = ntohl(*bp++);
461 pcb->expiry = ntohl(*bp++);
462 pcb->type = ntohl(*bp++);
463 }
464 else {
465 pcb->version = 0;
466 pcb->expiry = 0;
467 pcb->type = AFSCM_CB_UNTYPED;
468 }
469 pcb++;
470 }
471
472 /* invoke the actual service routine */
473 ret = SRXAFSCM_CallBack(server, count, cb);
474 if (ret < 0)
475 break;
476 }
477
478 /* send the reply */
479 ret = rxrpc_call_write_data(call, 0, NULL, RXRPC_LAST_PACKET,
480 GFP_KERNEL, 0, &count);
481 if (ret < 0)
482 break;
483 break;
484
485 /* operation complete */
486 case RXRPC_CSTATE_COMPLETE:
487 call->app_user = NULL;
488 removed = 0;
489 spin_lock(&afscm_calls_lock);
490 if (!list_empty(&call->app_link)) {
491 list_del_init(&call->app_link);
492 removed = 1;
493 }
494 spin_unlock(&afscm_calls_lock);
495
496 if (removed)
497 rxrpc_put_call(call);
498 break;
499
500 /* operation terminated on error */
501 case RXRPC_CSTATE_ERROR:
502 call->app_user = NULL;
503 break;
504
505 default:
506 break;
507 }
508
509 if (ret < 0)
510 rxrpc_call_abort(call, ret);
511
512 afs_put_server(server);
513
514 _leave(" = %d", ret);
515
516 } /* end _SRXAFSCM_CallBack() */
517
518 /*****************************************************************************/
519 /*
520 * handle the fileserver asking us to initialise our callback state
521 */
522 static void _SRXAFSCM_InitCallBackState(struct rxrpc_call *call)
523 {
524 struct afs_server *server;
525 size_t count;
526 int ret = 0, removed;
527
528 _enter("%p{acs=%s}", call, rxrpc_call_states[call->app_call_state]);
529
530 server = afs_server_get_from_peer(call->conn->peer);
531
532 switch (call->app_call_state) {
533 /* we've received the last packet - drain all the data from the
534 * call */
535 case RXRPC_CSTATE_SRVR_GOT_ARGS:
536 /* shouldn't be any args */
537 ret = -EBADMSG;
538 break;
539
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);
544 if (ret < 0)
545 break;
546
547 ret = rxrpc_call_write_data(call, 0, NULL, RXRPC_LAST_PACKET,
548 GFP_KERNEL, 0, &count);
549 if (ret < 0)
550 break;
551 break;
552
553 /* operation complete */
554 case RXRPC_CSTATE_COMPLETE:
555 call->app_user = NULL;
556 removed = 0;
557 spin_lock(&afscm_calls_lock);
558 if (!list_empty(&call->app_link)) {
559 list_del_init(&call->app_link);
560 removed = 1;
561 }
562 spin_unlock(&afscm_calls_lock);
563
564 if (removed)
565 rxrpc_put_call(call);
566 break;
567
568 /* operation terminated on error */
569 case RXRPC_CSTATE_ERROR:
570 call->app_user = NULL;
571 break;
572
573 default:
574 break;
575 }
576
577 if (ret < 0)
578 rxrpc_call_abort(call, ret);
579
580 afs_put_server(server);
581
582 _leave(" = %d", ret);
583
584 } /* end _SRXAFSCM_InitCallBackState() */
585
586 /*****************************************************************************/
587 /*
588 * handle a probe from a fileserver
589 */
590 static void _SRXAFSCM_Probe(struct rxrpc_call *call)
591 {
592 struct afs_server *server;
593 size_t count;
594 int ret = 0, removed;
595
596 _enter("%p{acs=%s}", call, rxrpc_call_states[call->app_call_state]);
597
598 server = afs_server_get_from_peer(call->conn->peer);
599
600 switch (call->app_call_state) {
601 /* we've received the last packet - drain all the data from the
602 * call */
603 case RXRPC_CSTATE_SRVR_GOT_ARGS:
604 /* shouldn't be any args */
605 ret = -EBADMSG;
606 break;
607
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);
612 if (ret < 0)
613 break;
614
615 ret = rxrpc_call_write_data(call, 0, NULL, RXRPC_LAST_PACKET,
616 GFP_KERNEL, 0, &count);
617 if (ret < 0)
618 break;
619 break;
620
621 /* operation complete */
622 case RXRPC_CSTATE_COMPLETE:
623 call->app_user = NULL;
624 removed = 0;
625 spin_lock(&afscm_calls_lock);
626 if (!list_empty(&call->app_link)) {
627 list_del_init(&call->app_link);
628 removed = 1;
629 }
630 spin_unlock(&afscm_calls_lock);
631
632 if (removed)
633 rxrpc_put_call(call);
634 break;
635
636 /* operation terminated on error */
637 case RXRPC_CSTATE_ERROR:
638 call->app_user = NULL;
639 break;
640
641 default:
642 break;
643 }
644
645 if (ret < 0)
646 rxrpc_call_abort(call, ret);
647
648 afs_put_server(server);
649
650 _leave(" = %d", ret);
651
652 } /* end _SRXAFSCM_Probe() */