cmservice.c (f26e8817b235d8764363bffcc9cbfc61867371f2) cmservice.c (8e8d7f13b6d5a93b3d2cf9a4ceaaf923809fd5ac)
1/* 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/slab.h>
15#include <linux/sched.h>
16#include <linux/ip.h>
17#include "internal.h"
18#include "afs_cm.h"
19
1/* 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/slab.h>
15#include <linux/sched.h>
16#include <linux/ip.h>
17#include "internal.h"
18#include "afs_cm.h"
19
20#if 0
21struct workqueue_struct *afs_cm_workqueue;
22#endif /* 0 */
23
24static int afs_deliver_cb_init_call_back_state(struct afs_call *,
25 struct sk_buff *, bool);
26static int afs_deliver_cb_init_call_back_state3(struct afs_call *,
27 struct sk_buff *, bool);
28static int afs_deliver_cb_probe(struct afs_call *, struct sk_buff *, bool);
29static int afs_deliver_cb_callback(struct afs_call *, struct sk_buff *, bool);
30static int afs_deliver_cb_probe_uuid(struct afs_call *, struct sk_buff *, bool);
31static int afs_deliver_cb_tell_me_about_yourself(struct afs_call *,
32 struct sk_buff *, bool);
20static int afs_deliver_cb_init_call_back_state(struct afs_call *);
21static int afs_deliver_cb_init_call_back_state3(struct afs_call *);
22static int afs_deliver_cb_probe(struct afs_call *);
23static int afs_deliver_cb_callback(struct afs_call *);
24static int afs_deliver_cb_probe_uuid(struct afs_call *);
25static int afs_deliver_cb_tell_me_about_yourself(struct afs_call *);
33static void afs_cm_destructor(struct afs_call *);
34
26static void afs_cm_destructor(struct afs_call *);
27
28#define CM_NAME(name) \
29 const char afs_SRXCB##name##_name[] __tracepoint_string = \
30 "CB." #name
31
35/*
36 * CB.CallBack operation type
37 */
32/*
33 * CB.CallBack operation type
34 */
35static CM_NAME(CallBack);
38static const struct afs_call_type afs_SRXCBCallBack = {
36static const struct afs_call_type afs_SRXCBCallBack = {
39 .name = "CB.CallBack",
37 .name = afs_SRXCBCallBack_name,
40 .deliver = afs_deliver_cb_callback,
41 .abort_to_error = afs_abort_to_error,
42 .destructor = afs_cm_destructor,
43};
44
45/*
46 * CB.InitCallBackState operation type
47 */
38 .deliver = afs_deliver_cb_callback,
39 .abort_to_error = afs_abort_to_error,
40 .destructor = afs_cm_destructor,
41};
42
43/*
44 * CB.InitCallBackState operation type
45 */
46static CM_NAME(InitCallBackState);
48static const struct afs_call_type afs_SRXCBInitCallBackState = {
47static const struct afs_call_type afs_SRXCBInitCallBackState = {
49 .name = "CB.InitCallBackState",
48 .name = afs_SRXCBInitCallBackState_name,
50 .deliver = afs_deliver_cb_init_call_back_state,
51 .abort_to_error = afs_abort_to_error,
52 .destructor = afs_cm_destructor,
53};
54
55/*
56 * CB.InitCallBackState3 operation type
57 */
49 .deliver = afs_deliver_cb_init_call_back_state,
50 .abort_to_error = afs_abort_to_error,
51 .destructor = afs_cm_destructor,
52};
53
54/*
55 * CB.InitCallBackState3 operation type
56 */
57static CM_NAME(InitCallBackState3);
58static const struct afs_call_type afs_SRXCBInitCallBackState3 = {
58static const struct afs_call_type afs_SRXCBInitCallBackState3 = {
59 .name = "CB.InitCallBackState3",
59 .name = afs_SRXCBInitCallBackState3_name,
60 .deliver = afs_deliver_cb_init_call_back_state3,
61 .abort_to_error = afs_abort_to_error,
62 .destructor = afs_cm_destructor,
63};
64
65/*
66 * CB.Probe operation type
67 */
60 .deliver = afs_deliver_cb_init_call_back_state3,
61 .abort_to_error = afs_abort_to_error,
62 .destructor = afs_cm_destructor,
63};
64
65/*
66 * CB.Probe operation type
67 */
68static CM_NAME(Probe);
68static const struct afs_call_type afs_SRXCBProbe = {
69static const struct afs_call_type afs_SRXCBProbe = {
69 .name = "CB.Probe",
70 .name = afs_SRXCBProbe_name,
70 .deliver = afs_deliver_cb_probe,
71 .abort_to_error = afs_abort_to_error,
72 .destructor = afs_cm_destructor,
73};
74
75/*
76 * CB.ProbeUuid operation type
77 */
71 .deliver = afs_deliver_cb_probe,
72 .abort_to_error = afs_abort_to_error,
73 .destructor = afs_cm_destructor,
74};
75
76/*
77 * CB.ProbeUuid operation type
78 */
79static CM_NAME(ProbeUuid);
78static const struct afs_call_type afs_SRXCBProbeUuid = {
80static const struct afs_call_type afs_SRXCBProbeUuid = {
79 .name = "CB.ProbeUuid",
81 .name = afs_SRXCBProbeUuid_name,
80 .deliver = afs_deliver_cb_probe_uuid,
81 .abort_to_error = afs_abort_to_error,
82 .destructor = afs_cm_destructor,
83};
84
85/*
86 * CB.TellMeAboutYourself operation type
87 */
82 .deliver = afs_deliver_cb_probe_uuid,
83 .abort_to_error = afs_abort_to_error,
84 .destructor = afs_cm_destructor,
85};
86
87/*
88 * CB.TellMeAboutYourself operation type
89 */
90static CM_NAME(TellMeAboutYourself);
88static const struct afs_call_type afs_SRXCBTellMeAboutYourself = {
91static const struct afs_call_type afs_SRXCBTellMeAboutYourself = {
89 .name = "CB.TellMeAboutYourself",
92 .name = afs_SRXCBTellMeAboutYourself_name,
90 .deliver = afs_deliver_cb_tell_me_about_yourself,
91 .abort_to_error = afs_abort_to_error,
92 .destructor = afs_cm_destructor,
93};
94
95/*
96 * route an incoming cache manager call
97 * - return T if supported, F if not
98 */
99bool afs_cm_incoming_call(struct afs_call *call)
100{
93 .deliver = afs_deliver_cb_tell_me_about_yourself,
94 .abort_to_error = afs_abort_to_error,
95 .destructor = afs_cm_destructor,
96};
97
98/*
99 * route an incoming cache manager call
100 * - return T if supported, F if not
101 */
102bool afs_cm_incoming_call(struct afs_call *call)
103{
101 u32 operation_id = ntohl(call->operation_ID);
104 _enter("{CB.OP %u}", call->operation_ID);
102
105
103 _enter("{CB.OP %u}", operation_id);
104
105 switch (operation_id) {
106 switch (call->operation_ID) {
106 case CBCallBack:
107 call->type = &afs_SRXCBCallBack;
108 return true;
109 case CBInitCallBackState:
110 call->type = &afs_SRXCBInitCallBackState;
111 return true;
112 case CBInitCallBackState3:
113 call->type = &afs_SRXCBInitCallBackState3;

--- 15 unchanged lines hidden (view full) ---

129static void afs_cm_destructor(struct afs_call *call)
130{
131 _enter("");
132
133 /* Break the callbacks here so that we do it after the final ACK is
134 * received. The step number here must match the final number in
135 * afs_deliver_cb_callback().
136 */
107 case CBCallBack:
108 call->type = &afs_SRXCBCallBack;
109 return true;
110 case CBInitCallBackState:
111 call->type = &afs_SRXCBInitCallBackState;
112 return true;
113 case CBInitCallBackState3:
114 call->type = &afs_SRXCBInitCallBackState3;

--- 15 unchanged lines hidden (view full) ---

130static void afs_cm_destructor(struct afs_call *call)
131{
132 _enter("");
133
134 /* Break the callbacks here so that we do it after the final ACK is
135 * received. The step number here must match the final number in
136 * afs_deliver_cb_callback().
137 */
137 if (call->unmarshall == 6) {
138 if (call->unmarshall == 5) {
138 ASSERT(call->server && call->count && call->request);
139 afs_break_callbacks(call->server, call->count, call->request);
140 }
141
142 afs_put_server(call->server);
143 call->server = NULL;
144 kfree(call->buffer);
145 call->buffer = NULL;

--- 17 unchanged lines hidden (view full) ---

163
164 afs_break_callbacks(call->server, call->count, call->request);
165 _leave("");
166}
167
168/*
169 * deliver request data to a CB.CallBack call
170 */
139 ASSERT(call->server && call->count && call->request);
140 afs_break_callbacks(call->server, call->count, call->request);
141 }
142
143 afs_put_server(call->server);
144 call->server = NULL;
145 kfree(call->buffer);
146 call->buffer = NULL;

--- 17 unchanged lines hidden (view full) ---

164
165 afs_break_callbacks(call->server, call->count, call->request);
166 _leave("");
167}
168
169/*
170 * deliver request data to a CB.CallBack call
171 */
171static int afs_deliver_cb_callback(struct afs_call *call, struct sk_buff *skb,
172 bool last)
172static int afs_deliver_cb_callback(struct afs_call *call)
173{
173{
174 struct sockaddr_rxrpc srx;
174 struct afs_callback *cb;
175 struct afs_server *server;
175 struct afs_callback *cb;
176 struct afs_server *server;
176 struct in_addr addr;
177 __be32 *bp;
178 u32 tmp;
179 int ret, loop;
180
177 __be32 *bp;
178 u32 tmp;
179 int ret, loop;
180
181 _enter("{%u},{%u},%d", call->unmarshall, skb->len, last);
181 _enter("{%u}", call->unmarshall);
182
183 switch (call->unmarshall) {
184 case 0:
182
183 switch (call->unmarshall) {
184 case 0:
185 rxrpc_kernel_get_peer(afs_socket, call->rxcall, &srx);
185 call->offset = 0;
186 call->unmarshall++;
187
188 /* extract the FID array and its count in two steps */
189 case 1:
190 _debug("extract FID count");
186 call->offset = 0;
187 call->unmarshall++;
188
189 /* extract the FID array and its count in two steps */
190 case 1:
191 _debug("extract FID count");
191 ret = afs_extract_data(call, skb, last, &call->tmp, 4);
192 ret = afs_extract_data(call, &call->tmp, 4, true);
192 if (ret < 0)
193 return ret;
194
195 call->count = ntohl(call->tmp);
196 _debug("FID count: %u", call->count);
197 if (call->count > AFSCBMAX)
198 return -EBADMSG;
199
200 call->buffer = kmalloc(call->count * 3 * 4, GFP_KERNEL);
201 if (!call->buffer)
202 return -ENOMEM;
203 call->offset = 0;
204 call->unmarshall++;
205
206 case 2:
207 _debug("extract FID array");
193 if (ret < 0)
194 return ret;
195
196 call->count = ntohl(call->tmp);
197 _debug("FID count: %u", call->count);
198 if (call->count > AFSCBMAX)
199 return -EBADMSG;
200
201 call->buffer = kmalloc(call->count * 3 * 4, GFP_KERNEL);
202 if (!call->buffer)
203 return -ENOMEM;
204 call->offset = 0;
205 call->unmarshall++;
206
207 case 2:
208 _debug("extract FID array");
208 ret = afs_extract_data(call, skb, last, call->buffer,
209 call->count * 3 * 4);
209 ret = afs_extract_data(call, call->buffer,
210 call->count * 3 * 4, true);
210 if (ret < 0)
211 return ret;
212
213 _debug("unmarshall FID array");
214 call->request = kcalloc(call->count,
215 sizeof(struct afs_callback),
216 GFP_KERNEL);
217 if (!call->request)

--- 9 unchanged lines hidden (view full) ---

227 }
228
229 call->offset = 0;
230 call->unmarshall++;
231
232 /* extract the callback array and its count in two steps */
233 case 3:
234 _debug("extract CB count");
211 if (ret < 0)
212 return ret;
213
214 _debug("unmarshall FID array");
215 call->request = kcalloc(call->count,
216 sizeof(struct afs_callback),
217 GFP_KERNEL);
218 if (!call->request)

--- 9 unchanged lines hidden (view full) ---

228 }
229
230 call->offset = 0;
231 call->unmarshall++;
232
233 /* extract the callback array and its count in two steps */
234 case 3:
235 _debug("extract CB count");
235 ret = afs_extract_data(call, skb, last, &call->tmp, 4);
236 ret = afs_extract_data(call, &call->tmp, 4, true);
236 if (ret < 0)
237 return ret;
238
239 tmp = ntohl(call->tmp);
240 _debug("CB count: %u", tmp);
241 if (tmp != call->count && tmp != 0)
242 return -EBADMSG;
243 call->offset = 0;
244 call->unmarshall++;
237 if (ret < 0)
238 return ret;
239
240 tmp = ntohl(call->tmp);
241 _debug("CB count: %u", tmp);
242 if (tmp != call->count && tmp != 0)
243 return -EBADMSG;
244 call->offset = 0;
245 call->unmarshall++;
245 if (tmp == 0)
246 goto empty_cb_array;
247
248 case 4:
249 _debug("extract CB array");
246
247 case 4:
248 _debug("extract CB array");
250 ret = afs_extract_data(call, skb, last, call->request,
251 call->count * 3 * 4);
249 ret = afs_extract_data(call, call->buffer,
250 call->count * 3 * 4, false);
252 if (ret < 0)
253 return ret;
254
255 _debug("unmarshall CB array");
256 cb = call->request;
257 bp = call->buffer;
258 for (loop = call->count; loop > 0; loop--, cb++) {
259 cb->version = ntohl(*bp++);
260 cb->expiry = ntohl(*bp++);
261 cb->type = ntohl(*bp++);
262 }
263
251 if (ret < 0)
252 return ret;
253
254 _debug("unmarshall CB array");
255 cb = call->request;
256 bp = call->buffer;
257 for (loop = call->count; loop > 0; loop--, cb++) {
258 cb->version = ntohl(*bp++);
259 cb->expiry = ntohl(*bp++);
260 cb->type = ntohl(*bp++);
261 }
262
264 empty_cb_array:
265 call->offset = 0;
266 call->unmarshall++;
267
263 call->offset = 0;
264 call->unmarshall++;
265
268 case 5:
269 ret = afs_data_complete(call, skb, last);
270 if (ret < 0)
271 return ret;
272
273 /* Record that the message was unmarshalled successfully so
274 * that the call destructor can know do the callback breaking
275 * work, even if the final ACK isn't received.
276 *
277 * If the step number changes, then afs_cm_destructor() must be
278 * updated also.
279 */
280 call->unmarshall++;
266 /* Record that the message was unmarshalled successfully so
267 * that the call destructor can know do the callback breaking
268 * work, even if the final ACK isn't received.
269 *
270 * If the step number changes, then afs_cm_destructor() must be
271 * updated also.
272 */
273 call->unmarshall++;
281 case 6:
274 case 5:
282 break;
283 }
284
275 break;
276 }
277
285
286 call->state = AFS_CALL_REPLYING;
287
288 /* we'll need the file server record as that tells us which set of
289 * vnodes to operate upon */
278 call->state = AFS_CALL_REPLYING;
279
280 /* we'll need the file server record as that tells us which set of
281 * vnodes to operate upon */
290 memcpy(&addr, &ip_hdr(skb)->saddr, 4);
291 server = afs_find_server(&addr);
282 server = afs_find_server(&srx);
292 if (!server)
293 return -ENOTCONN;
294 call->server = server;
295
296 INIT_WORK(&call->work, SRXAFSCB_CallBack);
297 queue_work(afs_wq, &call->work);
298 return 0;
299}

--- 10 unchanged lines hidden (view full) ---

310 afs_init_callback_state(call->server);
311 afs_send_empty_reply(call);
312 _leave("");
313}
314
315/*
316 * deliver request data to a CB.InitCallBackState call
317 */
283 if (!server)
284 return -ENOTCONN;
285 call->server = server;
286
287 INIT_WORK(&call->work, SRXAFSCB_CallBack);
288 queue_work(afs_wq, &call->work);
289 return 0;
290}

--- 10 unchanged lines hidden (view full) ---

301 afs_init_callback_state(call->server);
302 afs_send_empty_reply(call);
303 _leave("");
304}
305
306/*
307 * deliver request data to a CB.InitCallBackState call
308 */
318static int afs_deliver_cb_init_call_back_state(struct afs_call *call,
319 struct sk_buff *skb,
320 bool last)
309static int afs_deliver_cb_init_call_back_state(struct afs_call *call)
321{
310{
311 struct sockaddr_rxrpc srx;
322 struct afs_server *server;
312 struct afs_server *server;
323 struct in_addr addr;
324 int ret;
325
313 int ret;
314
326 _enter(",{%u},%d", skb->len, last);
315 _enter("");
327
316
328 ret = afs_data_complete(call, skb, last);
317 rxrpc_kernel_get_peer(afs_socket, call->rxcall, &srx);
318
319 ret = afs_extract_data(call, NULL, 0, false);
329 if (ret < 0)
330 return ret;
331
332 /* no unmarshalling required */
333 call->state = AFS_CALL_REPLYING;
334
335 /* we'll need the file server record as that tells us which set of
336 * vnodes to operate upon */
320 if (ret < 0)
321 return ret;
322
323 /* no unmarshalling required */
324 call->state = AFS_CALL_REPLYING;
325
326 /* we'll need the file server record as that tells us which set of
327 * vnodes to operate upon */
337 memcpy(&addr, &ip_hdr(skb)->saddr, 4);
338 server = afs_find_server(&addr);
328 server = afs_find_server(&srx);
339 if (!server)
340 return -ENOTCONN;
341 call->server = server;
342
343 INIT_WORK(&call->work, SRXAFSCB_InitCallBackState);
344 queue_work(afs_wq, &call->work);
345 return 0;
346}
347
348/*
349 * deliver request data to a CB.InitCallBackState3 call
350 */
329 if (!server)
330 return -ENOTCONN;
331 call->server = server;
332
333 INIT_WORK(&call->work, SRXAFSCB_InitCallBackState);
334 queue_work(afs_wq, &call->work);
335 return 0;
336}
337
338/*
339 * deliver request data to a CB.InitCallBackState3 call
340 */
351static int afs_deliver_cb_init_call_back_state3(struct afs_call *call,
352 struct sk_buff *skb,
353 bool last)
341static int afs_deliver_cb_init_call_back_state3(struct afs_call *call)
354{
342{
343 struct sockaddr_rxrpc srx;
355 struct afs_server *server;
344 struct afs_server *server;
356 struct in_addr addr;
345 struct afs_uuid *r;
346 unsigned loop;
347 __be32 *b;
348 int ret;
357
349
358 _enter(",{%u},%d", skb->len, last);
350 _enter("");
359
351
360 /* There are some arguments that we ignore */
361 afs_data_consumed(call, skb);
362 if (!last)
363 return -EAGAIN;
352 rxrpc_kernel_get_peer(afs_socket, call->rxcall, &srx);
364
353
354 _enter("{%u}", call->unmarshall);
355
356 switch (call->unmarshall) {
357 case 0:
358 call->offset = 0;
359 call->buffer = kmalloc(11 * sizeof(__be32), GFP_KERNEL);
360 if (!call->buffer)
361 return -ENOMEM;
362 call->unmarshall++;
363
364 case 1:
365 _debug("extract UUID");
366 ret = afs_extract_data(call, call->buffer,
367 11 * sizeof(__be32), false);
368 switch (ret) {
369 case 0: break;
370 case -EAGAIN: return 0;
371 default: return ret;
372 }
373
374 _debug("unmarshall UUID");
375 call->request = kmalloc(sizeof(struct afs_uuid), GFP_KERNEL);
376 if (!call->request)
377 return -ENOMEM;
378
379 b = call->buffer;
380 r = call->request;
381 r->time_low = ntohl(b[0]);
382 r->time_mid = ntohl(b[1]);
383 r->time_hi_and_version = ntohl(b[2]);
384 r->clock_seq_hi_and_reserved = ntohl(b[3]);
385 r->clock_seq_low = ntohl(b[4]);
386
387 for (loop = 0; loop < 6; loop++)
388 r->node[loop] = ntohl(b[loop + 5]);
389
390 call->offset = 0;
391 call->unmarshall++;
392
393 case 2:
394 break;
395 }
396
365 /* no unmarshalling required */
366 call->state = AFS_CALL_REPLYING;
367
368 /* we'll need the file server record as that tells us which set of
369 * vnodes to operate upon */
397 /* no unmarshalling required */
398 call->state = AFS_CALL_REPLYING;
399
400 /* we'll need the file server record as that tells us which set of
401 * vnodes to operate upon */
370 memcpy(&addr, &ip_hdr(skb)->saddr, 4);
371 server = afs_find_server(&addr);
402 server = afs_find_server(&srx);
372 if (!server)
373 return -ENOTCONN;
374 call->server = server;
375
376 INIT_WORK(&call->work, SRXAFSCB_InitCallBackState);
377 queue_work(afs_wq, &call->work);
378 return 0;
379}

--- 8 unchanged lines hidden (view full) ---

388 _enter("");
389 afs_send_empty_reply(call);
390 _leave("");
391}
392
393/*
394 * deliver request data to a CB.Probe call
395 */
403 if (!server)
404 return -ENOTCONN;
405 call->server = server;
406
407 INIT_WORK(&call->work, SRXAFSCB_InitCallBackState);
408 queue_work(afs_wq, &call->work);
409 return 0;
410}

--- 8 unchanged lines hidden (view full) ---

419 _enter("");
420 afs_send_empty_reply(call);
421 _leave("");
422}
423
424/*
425 * deliver request data to a CB.Probe call
426 */
396static int afs_deliver_cb_probe(struct afs_call *call, struct sk_buff *skb,
397 bool last)
427static int afs_deliver_cb_probe(struct afs_call *call)
398{
399 int ret;
400
428{
429 int ret;
430
401 _enter(",{%u},%d", skb->len, last);
431 _enter("");
402
432
403 ret = afs_data_complete(call, skb, last);
433 ret = afs_extract_data(call, NULL, 0, false);
404 if (ret < 0)
405 return ret;
406
407 /* no unmarshalling required */
408 call->state = AFS_CALL_REPLYING;
409
410 INIT_WORK(&call->work, SRXAFSCB_Probe);
411 queue_work(afs_wq, &call->work);

--- 9 unchanged lines hidden (view full) ---

421 struct afs_uuid *r = call->request;
422
423 struct {
424 __be32 match;
425 } reply;
426
427 _enter("");
428
434 if (ret < 0)
435 return ret;
436
437 /* no unmarshalling required */
438 call->state = AFS_CALL_REPLYING;
439
440 INIT_WORK(&call->work, SRXAFSCB_Probe);
441 queue_work(afs_wq, &call->work);

--- 9 unchanged lines hidden (view full) ---

451 struct afs_uuid *r = call->request;
452
453 struct {
454 __be32 match;
455 } reply;
456
457 _enter("");
458
429
430 if (memcmp(r, &afs_uuid, sizeof(afs_uuid)) == 0)
431 reply.match = htonl(0);
432 else
433 reply.match = htonl(1);
434
435 afs_send_simple_reply(call, &reply, sizeof(reply));
436 _leave("");
437}
438
439/*
440 * deliver request data to a CB.ProbeUuid call
441 */
459 if (memcmp(r, &afs_uuid, sizeof(afs_uuid)) == 0)
460 reply.match = htonl(0);
461 else
462 reply.match = htonl(1);
463
464 afs_send_simple_reply(call, &reply, sizeof(reply));
465 _leave("");
466}
467
468/*
469 * deliver request data to a CB.ProbeUuid call
470 */
442static int afs_deliver_cb_probe_uuid(struct afs_call *call, struct sk_buff *skb,
443 bool last)
471static int afs_deliver_cb_probe_uuid(struct afs_call *call)
444{
445 struct afs_uuid *r;
446 unsigned loop;
447 __be32 *b;
448 int ret;
449
472{
473 struct afs_uuid *r;
474 unsigned loop;
475 __be32 *b;
476 int ret;
477
450 _enter("{%u},{%u},%d", call->unmarshall, skb->len, last);
478 _enter("{%u}", call->unmarshall);
451
479
452 ret = afs_data_complete(call, skb, last);
453 if (ret < 0)
454 return ret;
455
456 switch (call->unmarshall) {
457 case 0:
458 call->offset = 0;
459 call->buffer = kmalloc(11 * sizeof(__be32), GFP_KERNEL);
460 if (!call->buffer)
461 return -ENOMEM;
462 call->unmarshall++;
463
464 case 1:
465 _debug("extract UUID");
480 switch (call->unmarshall) {
481 case 0:
482 call->offset = 0;
483 call->buffer = kmalloc(11 * sizeof(__be32), GFP_KERNEL);
484 if (!call->buffer)
485 return -ENOMEM;
486 call->unmarshall++;
487
488 case 1:
489 _debug("extract UUID");
466 ret = afs_extract_data(call, skb, last, call->buffer,
467 11 * sizeof(__be32));
490 ret = afs_extract_data(call, call->buffer,
491 11 * sizeof(__be32), false);
468 switch (ret) {
469 case 0: break;
470 case -EAGAIN: return 0;
471 default: return ret;
472 }
473
474 _debug("unmarshall UUID");
475 call->request = kmalloc(sizeof(struct afs_uuid), GFP_KERNEL);

--- 10 unchanged lines hidden (view full) ---

486
487 for (loop = 0; loop < 6; loop++)
488 r->node[loop] = ntohl(b[loop + 5]);
489
490 call->offset = 0;
491 call->unmarshall++;
492
493 case 2:
492 switch (ret) {
493 case 0: break;
494 case -EAGAIN: return 0;
495 default: return ret;
496 }
497
498 _debug("unmarshall UUID");
499 call->request = kmalloc(sizeof(struct afs_uuid), GFP_KERNEL);

--- 10 unchanged lines hidden (view full) ---

510
511 for (loop = 0; loop < 6; loop++)
512 r->node[loop] = ntohl(b[loop + 5]);
513
514 call->offset = 0;
515 call->unmarshall++;
516
517 case 2:
494 _debug("trailer");
495 if (skb->len != 0)
496 return -EBADMSG;
497 break;
498 }
499
518 break;
519 }
520
500 ret = afs_data_complete(call, skb, last);
501 if (ret < 0)
502 return ret;
503
504 call->state = AFS_CALL_REPLYING;
505
506 INIT_WORK(&call->work, SRXAFSCB_ProbeUuid);
507 queue_work(afs_wq, &call->work);
508 return 0;
509}
510
511/*

--- 57 unchanged lines hidden (view full) ---

569 afs_send_simple_reply(call, &reply, sizeof(reply));
570
571 _leave("");
572}
573
574/*
575 * deliver request data to a CB.TellMeAboutYourself call
576 */
521 call->state = AFS_CALL_REPLYING;
522
523 INIT_WORK(&call->work, SRXAFSCB_ProbeUuid);
524 queue_work(afs_wq, &call->work);
525 return 0;
526}
527
528/*

--- 57 unchanged lines hidden (view full) ---

586 afs_send_simple_reply(call, &reply, sizeof(reply));
587
588 _leave("");
589}
590
591/*
592 * deliver request data to a CB.TellMeAboutYourself call
593 */
577static int afs_deliver_cb_tell_me_about_yourself(struct afs_call *call,
578 struct sk_buff *skb, bool last)
594static int afs_deliver_cb_tell_me_about_yourself(struct afs_call *call)
579{
580 int ret;
581
595{
596 int ret;
597
582 _enter(",{%u},%d", skb->len, last);
598 _enter("");
583
599
584 ret = afs_data_complete(call, skb, last);
600 ret = afs_extract_data(call, NULL, 0, false);
585 if (ret < 0)
586 return ret;
587
588 /* no unmarshalling required */
589 call->state = AFS_CALL_REPLYING;
590
591 INIT_WORK(&call->work, SRXAFSCB_TellMeAboutYourself);
592 queue_work(afs_wq, &call->work);
593 return 0;
594}
601 if (ret < 0)
602 return ret;
603
604 /* no unmarshalling required */
605 call->state = AFS_CALL_REPLYING;
606
607 INIT_WORK(&call->work, SRXAFSCB_TellMeAboutYourself);
608 queue_work(afs_wq, &call->work);
609 return 0;
610}