aboutsummaryrefslogtreecommitdiffstats
path: root/fs/afs/cmservice.c
diff options
context:
space:
mode:
authorDavid Howells <dhowells@redhat.com>2007-04-26 18:55:03 -0400
committerDavid S. Miller <davem@davemloft.net>2007-04-26 18:55:03 -0400
commit08e0e7c82eeadec6f4871a386b86bf0f0fbcb4eb (patch)
tree1c4f7e91e20e56ff2ec755e988a6ee828b1a21c0 /fs/afs/cmservice.c
parent651350d10f93bed7003c9a66e24cf25e0f8eed3d (diff)
[AF_RXRPC]: Make the in-kernel AFS filesystem use AF_RXRPC.
Make the in-kernel AFS filesystem use AF_RXRPC instead of the old RxRPC code. Signed-off-by: David Howells <dhowells@redhat.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'fs/afs/cmservice.c')
-rw-r--r--fs/afs/cmservice.c781
1 files changed, 237 insertions, 544 deletions
diff --git a/fs/afs/cmservice.c b/fs/afs/cmservice.c
index 3f4585765cbf..c7141175391b 100644
--- a/fs/afs/cmservice.c
+++ b/fs/afs/cmservice.c
@@ -12,623 +12,316 @@
12#include <linux/module.h> 12#include <linux/module.h>
13#include <linux/init.h> 13#include <linux/init.h>
14#include <linux/sched.h> 14#include <linux/sched.h>
15#include <linux/completion.h> 15#include <linux/ip.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" 16#include "internal.h"
17#include "afs_cm.h"
25 18
26static unsigned afscm_usage; /* AFS cache manager usage count */ 19struct workqueue_struct *afs_cm_workqueue;
27static struct rw_semaphore afscm_sem; /* AFS cache manager start/stop semaphore */
28
29static int afscm_new_call(struct rxrpc_call *call);
30static void afscm_attention(struct rxrpc_call *call);
31static void afscm_error(struct rxrpc_call *call);
32static void afscm_aemap(struct rxrpc_call *call);
33
34static void _SRXAFSCM_CallBack(struct rxrpc_call *call);
35static void _SRXAFSCM_InitCallBackState(struct rxrpc_call *call);
36static void _SRXAFSCM_Probe(struct rxrpc_call *call);
37
38typedef void (*_SRXAFSCM_xxxx_t)(struct rxrpc_call *call);
39
40static 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 20
87static struct rxrpc_service AFSCM_service = { 21static int afs_deliver_cb_init_call_back_state(struct afs_call *,
88 .name = "AFS/CM", 22 struct sk_buff *, bool);
89 .owner = THIS_MODULE, 23static int afs_deliver_cb_probe(struct afs_call *, struct sk_buff *, bool);
90 .link = LIST_HEAD_INIT(AFSCM_service.link), 24static int afs_deliver_cb_callback(struct afs_call *, struct sk_buff *, bool);
91 .new_call = afscm_new_call, 25static void afs_cm_destructor(struct afs_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[ARRAY_SIZE(AFSCM_ops)],
98};
99
100static DECLARE_COMPLETION(kafscmd_alive);
101static DECLARE_COMPLETION(kafscmd_dead);
102static DECLARE_WAIT_QUEUE_HEAD(kafscmd_sleepq);
103static LIST_HEAD(kafscmd_attention_list);
104static LIST_HEAD(afscm_calls);
105static DEFINE_SPINLOCK(afscm_calls_lock);
106static DEFINE_SPINLOCK(kafscmd_attention_lock);
107static int kafscmd_die;
108 26
109/* 27/*
110 * AFS Cache Manager kernel thread 28 * CB.CallBack operation type
111 */ 29 */
112static int kafscmd(void *arg) 30static const struct afs_call_type afs_SRXCBCallBack = {
113{ 31 .deliver = afs_deliver_cb_callback,
114 DECLARE_WAITQUEUE(myself, current); 32 .abort_to_error = afs_abort_to_error,
115 33 .destructor = afs_cm_destructor,
116 struct rxrpc_call *call; 34};
117 _SRXAFSCM_xxxx_t func;
118 int die;
119
120 printk(KERN_INFO "kAFS: Started kafscmd %d\n", current->pid);
121
122 daemonize("kafscmd");
123
124 complete(&kafscmd_alive);
125
126 /* loop around looking for things to attend to */
127 do {
128 if (list_empty(&kafscmd_attention_list)) {
129 set_current_state(TASK_INTERRUPTIBLE);
130 add_wait_queue(&kafscmd_sleepq, &myself);
131
132 for (;;) {
133 set_current_state(TASK_INTERRUPTIBLE);
134 if (!list_empty(&kafscmd_attention_list) ||
135 signal_pending(current) ||
136 kafscmd_die)
137 break;
138
139 schedule();
140 }
141
142 remove_wait_queue(&kafscmd_sleepq, &myself);
143 set_current_state(TASK_RUNNING);
144 }
145
146 die = kafscmd_die;
147
148 /* dequeue the next call requiring attention */
149 call = NULL;
150 spin_lock(&kafscmd_attention_lock);
151
152 if (!list_empty(&kafscmd_attention_list)) {
153 call = list_entry(kafscmd_attention_list.next,
154 struct rxrpc_call,
155 app_attn_link);
156 list_del_init(&call->app_attn_link);
157 die = 0;
158 }
159
160 spin_unlock(&kafscmd_attention_lock);
161
162 if (call) {
163 /* act upon it */
164 _debug("@@@ Begin Attend Call %p", call);
165
166 func = call->app_user;
167 if (func)
168 func(call);
169
170 rxrpc_put_call(call);
171
172 _debug("@@@ End Attend Call %p", call);
173 }
174
175 } while(!die);
176
177 /* and that's all */
178 complete_and_exit(&kafscmd_dead, 0);
179}
180 35
181/* 36/*
182 * handle a call coming in to the cache manager 37 * CB.InitCallBackState operation type
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
185 * non-zero
186 * - serialised by virtue of there only being one krxiod
187 */ 38 */
188static int afscm_new_call(struct rxrpc_call *call) 39static const struct afs_call_type afs_SRXCBInitCallBackState = {
189{ 40 .deliver = afs_deliver_cb_init_call_back_state,
190 _enter("%p{cid=%u u=%d}", 41 .abort_to_error = afs_abort_to_error,
191 call, ntohl(call->call_id), atomic_read(&call->usage)); 42 .destructor = afs_cm_destructor,
192 43};
193 rxrpc_get_call(call);
194
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);
199
200 _leave(" = 0");
201 return 0;
202}
203 44
204/* 45/*
205 * queue on the kafscmd queue for attention 46 * CB.Probe operation type
206 */ 47 */
207static void afscm_attention(struct rxrpc_call *call) 48static const struct afs_call_type afs_SRXCBProbe = {
208{ 49 .deliver = afs_deliver_cb_probe,
209 _enter("%p{cid=%u u=%d}", 50 .abort_to_error = afs_abort_to_error,
210 call, ntohl(call->call_id), atomic_read(&call->usage)); 51 .destructor = afs_cm_destructor,
211 52};
212 spin_lock(&kafscmd_attention_lock);
213
214 if (list_empty(&call->app_attn_link)) {
215 list_add_tail(&call->app_attn_link, &kafscmd_attention_list);
216 rxrpc_get_call(call);
217 }
218
219 spin_unlock(&kafscmd_attention_lock);
220
221 wake_up(&kafscmd_sleepq);
222
223 _leave(" {u=%d}", atomic_read(&call->usage));
224}
225 53
226/* 54/*
227 * handle my call being aborted 55 * route an incoming cache manager call
228 * - clean up, dequeue and put my ref to the call 56 * - return T if supported, F if not
229 */ 57 */
230static void afscm_error(struct rxrpc_call *call) 58bool afs_cm_incoming_call(struct afs_call *call)
231{ 59{
232 int removed; 60 u32 operation_id = ntohl(call->operation_ID);
233 61
234 _enter("%p{est=%s ac=%u er=%d}", 62 _enter("{CB.OP %u}", operation_id);
235 call, 63
236 rxrpc_call_error_states[call->app_err_state], 64 switch (operation_id) {
237 call->app_abort_code, 65 case CBCallBack:
238 call->app_errno); 66 call->type = &afs_SRXCBCallBack;
239 67 return true;
240 spin_lock(&kafscmd_attention_lock); 68 case CBInitCallBackState:
241 69 call->type = &afs_SRXCBInitCallBackState;
242 if (list_empty(&call->app_attn_link)) { 70 return true;
243 list_add_tail(&call->app_attn_link, &kafscmd_attention_list); 71 case CBProbe:
244 rxrpc_get_call(call); 72 call->type = &afs_SRXCBProbe;
245 } 73 return true;
246 74 default:
247 spin_unlock(&kafscmd_attention_lock); 75 return false;
248
249 removed = 0;
250 spin_lock(&afscm_calls_lock);
251 if (!list_empty(&call->app_link)) {
252 list_del_init(&call->app_link);
253 removed = 1;
254 } 76 }
255 spin_unlock(&afscm_calls_lock);
256
257 if (removed)
258 rxrpc_put_call(call);
259
260 wake_up(&kafscmd_sleepq);
261
262 _leave("");
263} 77}
264 78
265/* 79/*
266 * map afs abort codes to/from Linux error codes 80 * clean up a cache manager call
267 * - called with call->lock held
268 */ 81 */
269static void afscm_aemap(struct rxrpc_call *call) 82static void afs_cm_destructor(struct afs_call *call)
270{ 83{
271 switch (call->app_err_state) { 84 _enter("");
272 case RXRPC_ESTATE_LOCAL_ABORT: 85
273 call->app_abort_code = -call->app_errno; 86 afs_put_server(call->server);
274 break; 87 call->server = NULL;
275 case RXRPC_ESTATE_PEER_ABORT: 88 kfree(call->buffer);
276 call->app_errno = -ECONNABORTED; 89 call->buffer = NULL;
277 break;
278 default:
279 break;
280 }
281} 90}
282 91
283/* 92/*
284 * start the cache manager service if not already started 93 * allow the fileserver to see if the cache manager is still alive
285 */ 94 */
286int afscm_start(void) 95static void SRXAFSCB_CallBack(struct work_struct *work)
287{ 96{
288 int ret; 97 struct afs_call *call = container_of(work, struct afs_call, work);
289
290 down_write(&afscm_sem);
291 if (!afscm_usage) {
292 ret = kernel_thread(kafscmd, NULL, 0);
293 if (ret < 0)
294 goto out;
295
296 wait_for_completion(&kafscmd_alive);
297
298 ret = rxrpc_add_service(afs_transport, &AFSCM_service);
299 if (ret < 0)
300 goto kill;
301 98
302 afs_kafstimod_add_timer(&afs_mntpt_expiry_timer, 99 _enter("");
303 afs_mntpt_expiry_timeout * HZ);
304 }
305
306 afscm_usage++;
307 up_write(&afscm_sem);
308
309 return 0;
310 100
311kill: 101 /* be sure to send the reply *before* attempting to spam the AFS server
312 kafscmd_die = 1; 102 * with FSFetchStatus requests on the vnodes with broken callbacks lest
313 wake_up(&kafscmd_sleepq); 103 * the AFS server get into a vicious cycle of trying to break further
314 wait_for_completion(&kafscmd_dead); 104 * callbacks because it hadn't received completion of the CBCallBack op
105 * yet */
106 afs_send_empty_reply(call);
315 107
316out: 108 afs_break_callbacks(call->server, call->count, call->request);
317 up_write(&afscm_sem); 109 _leave("");
318 return ret;
319} 110}
320 111
321/* 112/*
322 * stop the cache manager service 113 * deliver request data to a CB.CallBack call
323 */ 114 */
324void afscm_stop(void) 115static int afs_deliver_cb_callback(struct afs_call *call, struct sk_buff *skb,
116 bool last)
325{ 117{
326 struct rxrpc_call *call; 118 struct afs_callback *cb;
327 119 struct afs_server *server;
328 down_write(&afscm_sem); 120 struct in_addr addr;
329 121 __be32 *bp;
330 BUG_ON(afscm_usage == 0); 122 u32 tmp;
331 afscm_usage--; 123 int ret, loop;
332 124
333 if (afscm_usage == 0) { 125 _enter("{%u},{%u},%d", call->unmarshall, skb->len, last);
334 /* don't want more incoming calls */ 126
335 rxrpc_del_service(afs_transport, &AFSCM_service); 127 switch (call->unmarshall) {
336 128 case 0:
337 /* abort any calls I've still got open (the afscm_error() will 129 call->offset = 0;
338 * dequeue them) */ 130 call->unmarshall++;
339 spin_lock(&afscm_calls_lock); 131
340 while (!list_empty(&afscm_calls)) { 132 /* extract the FID array and its count in two steps */
341 call = list_entry(afscm_calls.next, 133 case 1:
342 struct rxrpc_call, 134 _debug("extract FID count");
343 app_link); 135 ret = afs_extract_data(call, skb, last, &call->tmp, 4);
344 136 switch (ret) {
345 list_del_init(&call->app_link); 137 case 0: break;
346 rxrpc_get_call(call); 138 case -EAGAIN: return 0;
347 spin_unlock(&afscm_calls_lock); 139 default: return ret;
348
349 rxrpc_call_abort(call, -ESRCH); /* abort, dequeue and
350 * put */
351
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);
357
358 spin_lock(&afscm_calls_lock);
359 } 140 }
360 spin_unlock(&afscm_calls_lock);
361
362 /* get rid of my daemon */
363 kafscmd_die = 1;
364 wake_up(&kafscmd_sleepq);
365 wait_for_completion(&kafscmd_dead);
366
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,
371 struct rxrpc_call,
372 app_attn_link);
373
374 list_del_init(&call->app_attn_link);
375 spin_unlock(&kafscmd_attention_lock);
376 141
377 rxrpc_put_call(call); 142 call->count = ntohl(call->tmp);
378 143 _debug("FID count: %u", call->count);
379 spin_lock(&kafscmd_attention_lock); 144 if (call->count > AFSCBMAX)
145 return -EBADMSG;
146
147 call->buffer = kmalloc(call->count * 3 * 4, GFP_KERNEL);
148 if (!call->buffer)
149 return -ENOMEM;
150 call->offset = 0;
151 call->unmarshall++;
152
153 case 2:
154 _debug("extract FID array");
155 ret = afs_extract_data(call, skb, last, call->buffer,
156 call->count * 3 * 4);
157 switch (ret) {
158 case 0: break;
159 case -EAGAIN: return 0;
160 default: return ret;
380 } 161 }
381 spin_unlock(&kafscmd_attention_lock);
382
383 afs_kafstimod_del_timer(&afs_mntpt_expiry_timer);
384 }
385
386 up_write(&afscm_sem);
387}
388 162
389/* 163 _debug("unmarshall FID array");
390 * handle the fileserver breaking a set of callbacks 164 call->request = kcalloc(call->count,
391 */ 165 sizeof(struct afs_callback),
392static void _SRXAFSCM_CallBack(struct rxrpc_call *call) 166 GFP_KERNEL);
393{ 167 if (!call->request)
394 struct afs_server *server; 168 return -ENOMEM;
395 size_t count, qty, tmp; 169
396 int ret = 0, removed; 170 cb = call->request;
397 171 bp = call->buffer;
398 _enter("%p{acs=%s}", call, rxrpc_call_states[call->app_call_state]); 172 for (loop = call->count; loop > 0; loop--, cb++) {
399 173 cb->fid.vid = ntohl(*bp++);
400 server = afs_server_get_from_peer(call->conn->peer); 174 cb->fid.vnode = ntohl(*bp++);
401 175 cb->fid.unique = ntohl(*bp++);
402 switch (call->app_call_state) { 176 cb->type = AFSCM_CB_UNTYPED;
403 /* we've received the last packet
404 * - drain all the data from the call and send the reply
405 */
406 case RXRPC_CSTATE_SRVR_GOT_ARGS:
407 ret = -EBADMSG;
408 qty = call->app_ready_qty;
409 if (qty < 8 || qty > 50 * (6 * 4) + 8)
410 break;
411
412 {
413 struct afs_callback *cb, *pcb;
414 int loop;
415 __be32 *fp, *bp;
416
417 fp = rxrpc_call_alloc_scratch(call, qty);
418
419 /* drag the entire argument block out to the scratch
420 * space */
421 ret = rxrpc_call_read_data(call, fp, qty, 0);
422 if (ret < 0)
423 break;
424
425 /* and unmarshall the parameter block */
426 ret = -EBADMSG;
427 count = ntohl(*fp++);
428 if (count>AFSCBMAX ||
429 (count * (3 * 4) + 8 != qty &&
430 count * (6 * 4) + 8 != qty))
431 break;
432
433 bp = fp + count*3;
434 tmp = ntohl(*bp++);
435 if (tmp > 0 && tmp != count)
436 break;
437 if (tmp == 0)
438 bp = NULL;
439
440 pcb = cb = rxrpc_call_alloc_scratch_s(
441 call, struct afs_callback);
442
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++);
447 if (bp) {
448 pcb->version = ntohl(*bp++);
449 pcb->expiry = ntohl(*bp++);
450 pcb->type = ntohl(*bp++);
451 } else {
452 pcb->version = 0;
453 pcb->expiry = 0;
454 pcb->type = AFSCM_CB_UNTYPED;
455 }
456 pcb++;
457 }
458
459 /* invoke the actual service routine */
460 ret = SRXAFSCM_CallBack(server, count, cb);
461 if (ret < 0)
462 break;
463 } 177 }
464 178
465 /* send the reply */ 179 call->offset = 0;
466 ret = rxrpc_call_write_data(call, 0, NULL, RXRPC_LAST_PACKET, 180 call->unmarshall++;
467 GFP_KERNEL, 0, &count); 181
468 if (ret < 0) 182 /* extract the callback array and its count in two steps */
469 break; 183 case 3:
470 break; 184 _debug("extract CB count");
185 ret = afs_extract_data(call, skb, last, &call->tmp, 4);
186 switch (ret) {
187 case 0: break;
188 case -EAGAIN: return 0;
189 default: return ret;
190 }
471 191
472 /* operation complete */ 192 tmp = ntohl(call->tmp);
473 case RXRPC_CSTATE_COMPLETE: 193 _debug("CB count: %u", tmp);
474 call->app_user = NULL; 194 if (tmp != call->count && tmp != 0)
475 removed = 0; 195 return -EBADMSG;
476 spin_lock(&afscm_calls_lock); 196 call->offset = 0;
477 if (!list_empty(&call->app_link)) { 197 call->unmarshall++;
478 list_del_init(&call->app_link); 198 if (tmp == 0)
479 removed = 1; 199 goto empty_cb_array;
200
201 case 4:
202 _debug("extract CB array");
203 ret = afs_extract_data(call, skb, last, call->request,
204 call->count * 3 * 4);
205 switch (ret) {
206 case 0: break;
207 case -EAGAIN: return 0;
208 default: return ret;
480 } 209 }
481 spin_unlock(&afscm_calls_lock);
482 210
483 if (removed) 211 _debug("unmarshall CB array");
484 rxrpc_put_call(call); 212 cb = call->request;
485 break; 213 bp = call->buffer;
214 for (loop = call->count; loop > 0; loop--, cb++) {
215 cb->version = ntohl(*bp++);
216 cb->expiry = ntohl(*bp++);
217 cb->type = ntohl(*bp++);
218 }
486 219
487 /* operation terminated on error */ 220 empty_cb_array:
488 case RXRPC_CSTATE_ERROR: 221 call->offset = 0;
489 call->app_user = NULL; 222 call->unmarshall++;
490 break;
491 223
492 default: 224 case 5:
225 _debug("trailer");
226 if (skb->len != 0)
227 return -EBADMSG;
493 break; 228 break;
494 } 229 }
495 230
496 if (ret < 0) 231 if (!last)
497 rxrpc_call_abort(call, ret); 232 return 0;
498 233
499 afs_put_server(server); 234 call->state = AFS_CALL_REPLYING;
500 235
501 _leave(" = %d", ret); 236 /* we'll need the file server record as that tells us which set of
237 * vnodes to operate upon */
238 memcpy(&addr, &ip_hdr(skb)->saddr, 4);
239 server = afs_find_server(&addr);
240 if (!server)
241 return -ENOTCONN;
242 call->server = server;
243
244 INIT_WORK(&call->work, SRXAFSCB_CallBack);
245 schedule_work(&call->work);
246 return 0;
502} 247}
503 248
504/* 249/*
505 * handle the fileserver asking us to initialise our callback state 250 * allow the fileserver to request callback state (re-)initialisation
506 */ 251 */
507static void _SRXAFSCM_InitCallBackState(struct rxrpc_call *call) 252static void SRXAFSCB_InitCallBackState(struct work_struct *work)
508{ 253{
509 struct afs_server *server; 254 struct afs_call *call = container_of(work, struct afs_call, work);
510 size_t count;
511 int ret = 0, removed;
512
513 _enter("%p{acs=%s}", call, rxrpc_call_states[call->app_call_state]);
514
515 server = afs_server_get_from_peer(call->conn->peer);
516
517 switch (call->app_call_state) {
518 /* we've received the last packet - drain all the data from the
519 * call */
520 case RXRPC_CSTATE_SRVR_GOT_ARGS:
521 /* shouldn't be any args */
522 ret = -EBADMSG;
523 break;
524 255
525 /* send the reply when asked for it */ 256 _enter("{%p}", call->server);
526 case RXRPC_CSTATE_SRVR_SND_REPLY:
527 /* invoke the actual service routine */
528 ret = SRXAFSCM_InitCallBackState(server);
529 if (ret < 0)
530 break;
531
532 ret = rxrpc_call_write_data(call, 0, NULL, RXRPC_LAST_PACKET,
533 GFP_KERNEL, 0, &count);
534 if (ret < 0)
535 break;
536 break;
537 257
538 /* operation complete */ 258 afs_init_callback_state(call->server);
539 case RXRPC_CSTATE_COMPLETE: 259 afs_send_empty_reply(call);
540 call->app_user = NULL; 260 _leave("");
541 removed = 0;
542 spin_lock(&afscm_calls_lock);
543 if (!list_empty(&call->app_link)) {
544 list_del_init(&call->app_link);
545 removed = 1;
546 }
547 spin_unlock(&afscm_calls_lock);
548
549 if (removed)
550 rxrpc_put_call(call);
551 break;
552
553 /* operation terminated on error */
554 case RXRPC_CSTATE_ERROR:
555 call->app_user = NULL;
556 break;
557
558 default:
559 break;
560 }
561
562 if (ret < 0)
563 rxrpc_call_abort(call, ret);
564
565 afs_put_server(server);
566
567 _leave(" = %d", ret);
568} 261}
569 262
570/* 263/*
571 * handle a probe from a fileserver 264 * deliver request data to a CB.InitCallBackState call
572 */ 265 */
573static void _SRXAFSCM_Probe(struct rxrpc_call *call) 266static int afs_deliver_cb_init_call_back_state(struct afs_call *call,
267 struct sk_buff *skb,
268 bool last)
574{ 269{
575 struct afs_server *server; 270 struct afs_server *server;
576 size_t count; 271 struct in_addr addr;
577 int ret = 0, removed;
578 272
579 _enter("%p{acs=%s}", call, rxrpc_call_states[call->app_call_state]); 273 _enter(",{%u},%d", skb->len, last);
580 274
581 server = afs_server_get_from_peer(call->conn->peer); 275 if (skb->len > 0)
276 return -EBADMSG;
277 if (!last)
278 return 0;
582 279
583 switch (call->app_call_state) { 280 /* no unmarshalling required */
584 /* we've received the last packet - drain all the data from the 281 call->state = AFS_CALL_REPLYING;
585 * call */
586 case RXRPC_CSTATE_SRVR_GOT_ARGS:
587 /* shouldn't be any args */
588 ret = -EBADMSG;
589 break;
590 282
591 /* send the reply when asked for it */ 283 /* we'll need the file server record as that tells us which set of
592 case RXRPC_CSTATE_SRVR_SND_REPLY: 284 * vnodes to operate upon */
593 /* invoke the actual service routine */ 285 memcpy(&addr, &ip_hdr(skb)->saddr, 4);
594 ret = SRXAFSCM_Probe(server); 286 server = afs_find_server(&addr);
595 if (ret < 0) 287 if (!server)
596 break; 288 return -ENOTCONN;
597 289 call->server = server;
598 ret = rxrpc_call_write_data(call, 0, NULL, RXRPC_LAST_PACKET,
599 GFP_KERNEL, 0, &count);
600 if (ret < 0)
601 break;
602 break;
603 290
604 /* operation complete */ 291 INIT_WORK(&call->work, SRXAFSCB_InitCallBackState);
605 case RXRPC_CSTATE_COMPLETE: 292 schedule_work(&call->work);
606 call->app_user = NULL; 293 return 0;
607 removed = 0; 294}
608 spin_lock(&afscm_calls_lock);
609 if (!list_empty(&call->app_link)) {
610 list_del_init(&call->app_link);
611 removed = 1;
612 }
613 spin_unlock(&afscm_calls_lock);
614 295
615 if (removed) 296/*
616 rxrpc_put_call(call); 297 * allow the fileserver to see if the cache manager is still alive
617 break; 298 */
299static void SRXAFSCB_Probe(struct work_struct *work)
300{
301 struct afs_call *call = container_of(work, struct afs_call, work);
618 302
619 /* operation terminated on error */ 303 _enter("");
620 case RXRPC_CSTATE_ERROR: 304 afs_send_empty_reply(call);
621 call->app_user = NULL; 305 _leave("");
622 break; 306}
623 307
624 default: 308/*
625 break; 309 * deliver request data to a CB.Probe call
626 } 310 */
311static int afs_deliver_cb_probe(struct afs_call *call, struct sk_buff *skb,
312 bool last)
313{
314 _enter(",{%u},%d", skb->len, last);
627 315
628 if (ret < 0) 316 if (skb->len > 0)
629 rxrpc_call_abort(call, ret); 317 return -EBADMSG;
318 if (!last)
319 return 0;
630 320
631 afs_put_server(server); 321 /* no unmarshalling required */
322 call->state = AFS_CALL_REPLYING;
632 323
633 _leave(" = %d", ret); 324 INIT_WORK(&call->work, SRXAFSCB_Probe);
325 schedule_work(&call->work);
326 return 0;
634} 327}