blob: dac9faa70ff468d5a86e1d6f190e5c5483643ca4 [file] [log] [blame]
David Howellsec268152007-04-26 15:49:28 -07001/* AFS Volume Location Service client
Linus Torvalds1da177e2005-04-16 15:20:36 -07002 *
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/init.h>
13#include <linux/sched.h>
14#include <rxrpc/rxrpc.h>
15#include <rxrpc/transport.h>
16#include <rxrpc/connection.h>
17#include <rxrpc/call.h>
18#include "server.h"
19#include "volume.h"
20#include "vlclient.h"
21#include "kafsasyncd.h"
22#include "kafstimod.h"
23#include "errors.h"
24#include "internal.h"
25
26#define VLGETENTRYBYID 503 /* AFS Get Cache Entry By ID operation ID */
27#define VLGETENTRYBYNAME 504 /* AFS Get Cache Entry By Name operation ID */
28#define VLPROBE 514 /* AFS Probe Volume Location Service operation ID */
29
30static void afs_rxvl_get_entry_by_id_attn(struct rxrpc_call *call);
31static void afs_rxvl_get_entry_by_id_error(struct rxrpc_call *call);
32
Linus Torvalds1da177e2005-04-16 15:20:36 -070033/*
34 * map afs VL abort codes to/from Linux error codes
35 * - called with call->lock held
36 */
37static void afs_rxvl_aemap(struct rxrpc_call *call)
38{
39 int err;
40
41 _enter("{%u,%u,%d}",
42 call->app_err_state, call->app_abort_code, call->app_errno);
43
44 switch (call->app_err_state) {
45 case RXRPC_ESTATE_LOCAL_ABORT:
46 call->app_abort_code = -call->app_errno;
47 return;
48
49 case RXRPC_ESTATE_PEER_ABORT:
50 switch (call->app_abort_code) {
51 case AFSVL_IDEXIST: err = -EEXIST; break;
52 case AFSVL_IO: err = -EREMOTEIO; break;
53 case AFSVL_NAMEEXIST: err = -EEXIST; break;
54 case AFSVL_CREATEFAIL: err = -EREMOTEIO; break;
55 case AFSVL_NOENT: err = -ENOMEDIUM; break;
56 case AFSVL_EMPTY: err = -ENOMEDIUM; break;
57 case AFSVL_ENTDELETED: err = -ENOMEDIUM; break;
58 case AFSVL_BADNAME: err = -EINVAL; break;
59 case AFSVL_BADINDEX: err = -EINVAL; break;
60 case AFSVL_BADVOLTYPE: err = -EINVAL; break;
61 case AFSVL_BADSERVER: err = -EINVAL; break;
62 case AFSVL_BADPARTITION: err = -EINVAL; break;
63 case AFSVL_REPSFULL: err = -EFBIG; break;
64 case AFSVL_NOREPSERVER: err = -ENOENT; break;
65 case AFSVL_DUPREPSERVER: err = -EEXIST; break;
66 case AFSVL_RWNOTFOUND: err = -ENOENT; break;
67 case AFSVL_BADREFCOUNT: err = -EINVAL; break;
68 case AFSVL_SIZEEXCEEDED: err = -EINVAL; break;
69 case AFSVL_BADENTRY: err = -EINVAL; break;
70 case AFSVL_BADVOLIDBUMP: err = -EINVAL; break;
71 case AFSVL_IDALREADYHASHED: err = -EINVAL; break;
72 case AFSVL_ENTRYLOCKED: err = -EBUSY; break;
73 case AFSVL_BADVOLOPER: err = -EBADRQC; break;
74 case AFSVL_BADRELLOCKTYPE: err = -EINVAL; break;
75 case AFSVL_RERELEASE: err = -EREMOTEIO; break;
76 case AFSVL_BADSERVERFLAG: err = -EINVAL; break;
77 case AFSVL_PERM: err = -EACCES; break;
78 case AFSVL_NOMEM: err = -EREMOTEIO; break;
79 default:
80 err = afs_abort_to_error(call->app_abort_code);
81 break;
82 }
83 call->app_errno = err;
84 return;
85
86 default:
87 return;
88 }
David Howellsec268152007-04-26 15:49:28 -070089}
Linus Torvalds1da177e2005-04-16 15:20:36 -070090
91#if 0
Linus Torvalds1da177e2005-04-16 15:20:36 -070092/*
93 * probe a volume location server to see if it is still alive -- unused
94 */
95static int afs_rxvl_probe(struct afs_server *server, int alloc_flags)
96{
97 struct rxrpc_connection *conn;
98 struct rxrpc_call *call;
99 struct kvec piov[1];
100 size_t sent;
101 int ret;
102 __be32 param[1];
103
104 DECLARE_WAITQUEUE(myself, current);
105
106 /* get hold of the vlserver connection */
107 ret = afs_server_get_vlconn(server, &conn);
108 if (ret < 0)
109 goto out;
110
111 /* create a call through that connection */
112 ret = rxrpc_create_call(conn, NULL, NULL, afs_rxvl_aemap, &call);
113 if (ret < 0) {
114 printk("kAFS: Unable to create call: %d\n", ret);
115 goto out_put_conn;
116 }
117 call->app_opcode = VLPROBE;
118
119 /* we want to get event notifications from the call */
120 add_wait_queue(&call->waitq, &myself);
121
122 /* marshall the parameters */
123 param[0] = htonl(VLPROBE);
124 piov[0].iov_len = sizeof(param);
125 piov[0].iov_base = param;
126
127 /* send the parameters to the server */
128 ret = rxrpc_call_write_data(call, 1, piov, RXRPC_LAST_PACKET,
129 alloc_flags, 0, &sent);
130 if (ret < 0)
131 goto abort;
132
133 /* wait for the reply to completely arrive */
134 for (;;) {
135 set_current_state(TASK_INTERRUPTIBLE);
136 if (call->app_call_state != RXRPC_CSTATE_CLNT_RCV_REPLY ||
137 signal_pending(current))
138 break;
139 schedule();
140 }
141 set_current_state(TASK_RUNNING);
142
143 ret = -EINTR;
144 if (signal_pending(current))
145 goto abort;
146
147 switch (call->app_call_state) {
148 case RXRPC_CSTATE_ERROR:
149 ret = call->app_errno;
150 goto out_unwait;
151
152 case RXRPC_CSTATE_CLNT_GOT_REPLY:
153 ret = 0;
154 goto out_unwait;
155
156 default:
157 BUG();
158 }
159
David Howellsec268152007-04-26 15:49:28 -0700160abort:
Linus Torvalds1da177e2005-04-16 15:20:36 -0700161 set_current_state(TASK_UNINTERRUPTIBLE);
162 rxrpc_call_abort(call, ret);
163 schedule();
164
David Howellsec268152007-04-26 15:49:28 -0700165out_unwait:
Linus Torvalds1da177e2005-04-16 15:20:36 -0700166 set_current_state(TASK_RUNNING);
167 remove_wait_queue(&call->waitq, &myself);
168 rxrpc_put_call(call);
David Howellsec268152007-04-26 15:49:28 -0700169out_put_conn:
Linus Torvalds1da177e2005-04-16 15:20:36 -0700170 rxrpc_put_connection(conn);
David Howellsec268152007-04-26 15:49:28 -0700171out:
Linus Torvalds1da177e2005-04-16 15:20:36 -0700172 return ret;
David Howellsec268152007-04-26 15:49:28 -0700173}
Linus Torvalds1da177e2005-04-16 15:20:36 -0700174#endif
175
Linus Torvalds1da177e2005-04-16 15:20:36 -0700176/*
177 * look up a volume location database entry by name
178 */
179int afs_rxvl_get_entry_by_name(struct afs_server *server,
180 const char *volname,
181 unsigned volnamesz,
182 struct afs_cache_vlocation *entry)
183{
184 DECLARE_WAITQUEUE(myself, current);
185
186 struct rxrpc_connection *conn;
187 struct rxrpc_call *call;
188 struct kvec piov[3];
189 unsigned tmp;
190 size_t sent;
191 int ret, loop;
192 __be32 *bp, param[2], zero;
193
194 _enter(",%*.*s,%u,", volnamesz, volnamesz, volname, volnamesz);
195
196 memset(entry, 0, sizeof(*entry));
197
198 /* get hold of the vlserver connection */
199 ret = afs_server_get_vlconn(server, &conn);
200 if (ret < 0)
201 goto out;
202
203 /* create a call through that connection */
204 ret = rxrpc_create_call(conn, NULL, NULL, afs_rxvl_aemap, &call);
205 if (ret < 0) {
206 printk("kAFS: Unable to create call: %d\n", ret);
207 goto out_put_conn;
208 }
209 call->app_opcode = VLGETENTRYBYNAME;
210
211 /* we want to get event notifications from the call */
212 add_wait_queue(&call->waitq, &myself);
213
214 /* marshall the parameters */
215 piov[1].iov_len = volnamesz;
216 piov[1].iov_base = (char *) volname;
217
218 zero = 0;
219 piov[2].iov_len = (4 - (piov[1].iov_len & 3)) & 3;
220 piov[2].iov_base = &zero;
221
222 param[0] = htonl(VLGETENTRYBYNAME);
223 param[1] = htonl(piov[1].iov_len);
224
225 piov[0].iov_len = sizeof(param);
226 piov[0].iov_base = param;
227
228 /* send the parameters to the server */
229 ret = rxrpc_call_write_data(call, 3, piov, RXRPC_LAST_PACKET, GFP_NOFS,
230 0, &sent);
231 if (ret < 0)
232 goto abort;
233
234 /* wait for the reply to completely arrive */
235 bp = rxrpc_call_alloc_scratch(call, 384);
236
237 ret = rxrpc_call_read_data(call, bp, 384,
238 RXRPC_CALL_READ_BLOCK |
239 RXRPC_CALL_READ_ALL);
240 if (ret < 0) {
241 if (ret == -ECONNABORTED) {
242 ret = call->app_errno;
243 goto out_unwait;
244 }
245 goto abort;
246 }
247
248 /* unmarshall the reply */
249 for (loop = 0; loop < 64; loop++)
250 entry->name[loop] = ntohl(*bp++);
251 bp++; /* final NUL */
252
253 bp++; /* type */
254 entry->nservers = ntohl(*bp++);
255
256 for (loop = 0; loop < 8; loop++)
257 entry->servers[loop].s_addr = *bp++;
258
259 bp += 8; /* partition IDs */
260
261 for (loop = 0; loop < 8; loop++) {
262 tmp = ntohl(*bp++);
263 if (tmp & AFS_VLSF_RWVOL)
264 entry->srvtmask[loop] |= AFS_VOL_VTM_RW;
265 if (tmp & AFS_VLSF_ROVOL)
266 entry->srvtmask[loop] |= AFS_VOL_VTM_RO;
267 if (tmp & AFS_VLSF_BACKVOL)
268 entry->srvtmask[loop] |= AFS_VOL_VTM_BAK;
269 }
270
271 entry->vid[0] = ntohl(*bp++);
272 entry->vid[1] = ntohl(*bp++);
273 entry->vid[2] = ntohl(*bp++);
274
275 bp++; /* clone ID */
276
277 tmp = ntohl(*bp++); /* flags */
278 if (tmp & AFS_VLF_RWEXISTS)
279 entry->vidmask |= AFS_VOL_VTM_RW;
280 if (tmp & AFS_VLF_ROEXISTS)
281 entry->vidmask |= AFS_VOL_VTM_RO;
282 if (tmp & AFS_VLF_BACKEXISTS)
283 entry->vidmask |= AFS_VOL_VTM_BAK;
284
285 ret = -ENOMEDIUM;
286 if (!entry->vidmask)
287 goto abort;
288
289 /* success */
290 entry->rtime = get_seconds();
291 ret = 0;
292
David Howellsec268152007-04-26 15:49:28 -0700293out_unwait:
Linus Torvalds1da177e2005-04-16 15:20:36 -0700294 set_current_state(TASK_RUNNING);
295 remove_wait_queue(&call->waitq, &myself);
296 rxrpc_put_call(call);
David Howellsec268152007-04-26 15:49:28 -0700297out_put_conn:
Linus Torvalds1da177e2005-04-16 15:20:36 -0700298 rxrpc_put_connection(conn);
David Howellsec268152007-04-26 15:49:28 -0700299out:
Linus Torvalds1da177e2005-04-16 15:20:36 -0700300 _leave(" = %d", ret);
301 return ret;
302
David Howellsec268152007-04-26 15:49:28 -0700303abort:
Linus Torvalds1da177e2005-04-16 15:20:36 -0700304 set_current_state(TASK_UNINTERRUPTIBLE);
305 rxrpc_call_abort(call, ret);
306 schedule();
307 goto out_unwait;
David Howellsec268152007-04-26 15:49:28 -0700308}
Linus Torvalds1da177e2005-04-16 15:20:36 -0700309
Linus Torvalds1da177e2005-04-16 15:20:36 -0700310/*
311 * look up a volume location database entry by ID
312 */
313int afs_rxvl_get_entry_by_id(struct afs_server *server,
314 afs_volid_t volid,
315 afs_voltype_t voltype,
316 struct afs_cache_vlocation *entry)
317{
318 DECLARE_WAITQUEUE(myself, current);
319
320 struct rxrpc_connection *conn;
321 struct rxrpc_call *call;
322 struct kvec piov[1];
323 unsigned tmp;
324 size_t sent;
325 int ret, loop;
326 __be32 *bp, param[3];
327
328 _enter(",%x,%d,", volid, voltype);
329
330 memset(entry, 0, sizeof(*entry));
331
332 /* get hold of the vlserver connection */
333 ret = afs_server_get_vlconn(server, &conn);
334 if (ret < 0)
335 goto out;
336
337 /* create a call through that connection */
338 ret = rxrpc_create_call(conn, NULL, NULL, afs_rxvl_aemap, &call);
339 if (ret < 0) {
340 printk("kAFS: Unable to create call: %d\n", ret);
341 goto out_put_conn;
342 }
343 call->app_opcode = VLGETENTRYBYID;
344
345 /* we want to get event notifications from the call */
346 add_wait_queue(&call->waitq, &myself);
347
348 /* marshall the parameters */
349 param[0] = htonl(VLGETENTRYBYID);
350 param[1] = htonl(volid);
351 param[2] = htonl(voltype);
352
353 piov[0].iov_len = sizeof(param);
354 piov[0].iov_base = param;
355
356 /* send the parameters to the server */
357 ret = rxrpc_call_write_data(call, 1, piov, RXRPC_LAST_PACKET, GFP_NOFS,
358 0, &sent);
359 if (ret < 0)
360 goto abort;
361
362 /* wait for the reply to completely arrive */
363 bp = rxrpc_call_alloc_scratch(call, 384);
364
365 ret = rxrpc_call_read_data(call, bp, 384,
366 RXRPC_CALL_READ_BLOCK |
367 RXRPC_CALL_READ_ALL);
368 if (ret < 0) {
369 if (ret == -ECONNABORTED) {
370 ret = call->app_errno;
371 goto out_unwait;
372 }
373 goto abort;
374 }
375
376 /* unmarshall the reply */
377 for (loop = 0; loop < 64; loop++)
378 entry->name[loop] = ntohl(*bp++);
379 bp++; /* final NUL */
380
381 bp++; /* type */
382 entry->nservers = ntohl(*bp++);
383
384 for (loop = 0; loop < 8; loop++)
385 entry->servers[loop].s_addr = *bp++;
386
387 bp += 8; /* partition IDs */
388
389 for (loop = 0; loop < 8; loop++) {
390 tmp = ntohl(*bp++);
391 if (tmp & AFS_VLSF_RWVOL)
392 entry->srvtmask[loop] |= AFS_VOL_VTM_RW;
393 if (tmp & AFS_VLSF_ROVOL)
394 entry->srvtmask[loop] |= AFS_VOL_VTM_RO;
395 if (tmp & AFS_VLSF_BACKVOL)
396 entry->srvtmask[loop] |= AFS_VOL_VTM_BAK;
397 }
398
399 entry->vid[0] = ntohl(*bp++);
400 entry->vid[1] = ntohl(*bp++);
401 entry->vid[2] = ntohl(*bp++);
402
403 bp++; /* clone ID */
404
405 tmp = ntohl(*bp++); /* flags */
406 if (tmp & AFS_VLF_RWEXISTS)
407 entry->vidmask |= AFS_VOL_VTM_RW;
408 if (tmp & AFS_VLF_ROEXISTS)
409 entry->vidmask |= AFS_VOL_VTM_RO;
410 if (tmp & AFS_VLF_BACKEXISTS)
411 entry->vidmask |= AFS_VOL_VTM_BAK;
412
413 ret = -ENOMEDIUM;
414 if (!entry->vidmask)
415 goto abort;
416
417#if 0 /* TODO: remove */
418 entry->nservers = 3;
419 entry->servers[0].s_addr = htonl(0xac101249);
420 entry->servers[1].s_addr = htonl(0xac101243);
421 entry->servers[2].s_addr = htonl(0xac10125b /*0xac10125b*/);
422
423 entry->srvtmask[0] = AFS_VOL_VTM_RO;
424 entry->srvtmask[1] = AFS_VOL_VTM_RO;
425 entry->srvtmask[2] = AFS_VOL_VTM_RO | AFS_VOL_VTM_RW;
426#endif
427
428 /* success */
429 entry->rtime = get_seconds();
430 ret = 0;
431
David Howellsec268152007-04-26 15:49:28 -0700432out_unwait:
Linus Torvalds1da177e2005-04-16 15:20:36 -0700433 set_current_state(TASK_RUNNING);
434 remove_wait_queue(&call->waitq, &myself);
435 rxrpc_put_call(call);
David Howellsec268152007-04-26 15:49:28 -0700436out_put_conn:
Linus Torvalds1da177e2005-04-16 15:20:36 -0700437 rxrpc_put_connection(conn);
David Howellsec268152007-04-26 15:49:28 -0700438out:
Linus Torvalds1da177e2005-04-16 15:20:36 -0700439 _leave(" = %d", ret);
440 return ret;
441
David Howellsec268152007-04-26 15:49:28 -0700442abort:
Linus Torvalds1da177e2005-04-16 15:20:36 -0700443 set_current_state(TASK_UNINTERRUPTIBLE);
444 rxrpc_call_abort(call, ret);
445 schedule();
446 goto out_unwait;
David Howellsec268152007-04-26 15:49:28 -0700447}
Linus Torvalds1da177e2005-04-16 15:20:36 -0700448
Linus Torvalds1da177e2005-04-16 15:20:36 -0700449/*
450 * look up a volume location database entry by ID asynchronously
451 */
452int afs_rxvl_get_entry_by_id_async(struct afs_async_op *op,
453 afs_volid_t volid,
454 afs_voltype_t voltype)
455{
456 struct rxrpc_connection *conn;
457 struct rxrpc_call *call;
458 struct kvec piov[1];
459 size_t sent;
460 int ret;
461 __be32 param[3];
462
463 _enter(",%x,%d,", volid, voltype);
464
465 /* get hold of the vlserver connection */
466 ret = afs_server_get_vlconn(op->server, &conn);
467 if (ret < 0) {
468 _leave(" = %d", ret);
469 return ret;
470 }
471
472 /* create a call through that connection */
473 ret = rxrpc_create_call(conn,
474 afs_rxvl_get_entry_by_id_attn,
475 afs_rxvl_get_entry_by_id_error,
476 afs_rxvl_aemap,
477 &op->call);
478 rxrpc_put_connection(conn);
479
480 if (ret < 0) {
481 printk("kAFS: Unable to create call: %d\n", ret);
482 _leave(" = %d", ret);
483 return ret;
484 }
485
486 op->call->app_opcode = VLGETENTRYBYID;
487 op->call->app_user = op;
488
489 call = op->call;
490 rxrpc_get_call(call);
491
492 /* send event notifications from the call to kafsasyncd */
493 afs_kafsasyncd_begin_op(op);
494
495 /* marshall the parameters */
496 param[0] = htonl(VLGETENTRYBYID);
497 param[1] = htonl(volid);
498 param[2] = htonl(voltype);
499
500 piov[0].iov_len = sizeof(param);
501 piov[0].iov_base = param;
502
503 /* allocate result read buffer in scratch space */
504 call->app_scr_ptr = rxrpc_call_alloc_scratch(op->call, 384);
505
506 /* send the parameters to the server */
507 ret = rxrpc_call_write_data(call, 1, piov, RXRPC_LAST_PACKET, GFP_NOFS,
508 0, &sent);
509 if (ret < 0) {
510 rxrpc_call_abort(call, ret); /* handle from kafsasyncd */
511 ret = 0;
512 goto out;
513 }
514
515 /* wait for the reply to completely arrive */
516 ret = rxrpc_call_read_data(call, call->app_scr_ptr, 384, 0);
517 switch (ret) {
518 case 0:
519 case -EAGAIN:
520 case -ECONNABORTED:
521 ret = 0;
522 break; /* all handled by kafsasyncd */
523
524 default:
525 rxrpc_call_abort(call, ret); /* make kafsasyncd handle it */
526 ret = 0;
527 break;
528 }
529
David Howellsec268152007-04-26 15:49:28 -0700530out:
Linus Torvalds1da177e2005-04-16 15:20:36 -0700531 rxrpc_put_call(call);
532 _leave(" = %d", ret);
533 return ret;
David Howellsec268152007-04-26 15:49:28 -0700534}
Linus Torvalds1da177e2005-04-16 15:20:36 -0700535
Linus Torvalds1da177e2005-04-16 15:20:36 -0700536/*
537 * attend to the asynchronous get VLDB entry by ID
538 */
539int afs_rxvl_get_entry_by_id_async2(struct afs_async_op *op,
540 struct afs_cache_vlocation *entry)
541{
542 __be32 *bp;
543 __u32 tmp;
544 int loop, ret;
545
546 _enter("{op=%p cst=%u}", op, op->call->app_call_state);
547
548 memset(entry, 0, sizeof(*entry));
549
550 if (op->call->app_call_state == RXRPC_CSTATE_COMPLETE) {
551 /* operation finished */
552 afs_kafsasyncd_terminate_op(op);
553
554 bp = op->call->app_scr_ptr;
555
556 /* unmarshall the reply */
557 for (loop = 0; loop < 64; loop++)
558 entry->name[loop] = ntohl(*bp++);
559 bp++; /* final NUL */
560
561 bp++; /* type */
562 entry->nservers = ntohl(*bp++);
563
564 for (loop = 0; loop < 8; loop++)
565 entry->servers[loop].s_addr = *bp++;
566
567 bp += 8; /* partition IDs */
568
569 for (loop = 0; loop < 8; loop++) {
570 tmp = ntohl(*bp++);
571 if (tmp & AFS_VLSF_RWVOL)
572 entry->srvtmask[loop] |= AFS_VOL_VTM_RW;
573 if (tmp & AFS_VLSF_ROVOL)
574 entry->srvtmask[loop] |= AFS_VOL_VTM_RO;
575 if (tmp & AFS_VLSF_BACKVOL)
576 entry->srvtmask[loop] |= AFS_VOL_VTM_BAK;
577 }
578
579 entry->vid[0] = ntohl(*bp++);
580 entry->vid[1] = ntohl(*bp++);
581 entry->vid[2] = ntohl(*bp++);
582
583 bp++; /* clone ID */
584
585 tmp = ntohl(*bp++); /* flags */
586 if (tmp & AFS_VLF_RWEXISTS)
587 entry->vidmask |= AFS_VOL_VTM_RW;
588 if (tmp & AFS_VLF_ROEXISTS)
589 entry->vidmask |= AFS_VOL_VTM_RO;
590 if (tmp & AFS_VLF_BACKEXISTS)
591 entry->vidmask |= AFS_VOL_VTM_BAK;
592
593 ret = -ENOMEDIUM;
594 if (!entry->vidmask) {
595 rxrpc_call_abort(op->call, ret);
596 goto done;
597 }
598
599#if 0 /* TODO: remove */
600 entry->nservers = 3;
601 entry->servers[0].s_addr = htonl(0xac101249);
602 entry->servers[1].s_addr = htonl(0xac101243);
603 entry->servers[2].s_addr = htonl(0xac10125b /*0xac10125b*/);
604
605 entry->srvtmask[0] = AFS_VOL_VTM_RO;
606 entry->srvtmask[1] = AFS_VOL_VTM_RO;
607 entry->srvtmask[2] = AFS_VOL_VTM_RO | AFS_VOL_VTM_RW;
608#endif
609
610 /* success */
611 entry->rtime = get_seconds();
612 ret = 0;
613 goto done;
614 }
615
616 if (op->call->app_call_state == RXRPC_CSTATE_ERROR) {
617 /* operation error */
618 ret = op->call->app_errno;
619 goto done;
620 }
621
622 _leave(" = -EAGAIN");
623 return -EAGAIN;
624
David Howellsec268152007-04-26 15:49:28 -0700625done:
Linus Torvalds1da177e2005-04-16 15:20:36 -0700626 rxrpc_put_call(op->call);
627 op->call = NULL;
628 _leave(" = %d", ret);
629 return ret;
David Howellsec268152007-04-26 15:49:28 -0700630}
Linus Torvalds1da177e2005-04-16 15:20:36 -0700631
Linus Torvalds1da177e2005-04-16 15:20:36 -0700632/*
633 * handle attention events on an async get-entry-by-ID op
634 * - called from krxiod
635 */
636static void afs_rxvl_get_entry_by_id_attn(struct rxrpc_call *call)
637{
638 struct afs_async_op *op = call->app_user;
639
640 _enter("{op=%p cst=%u}", op, call->app_call_state);
641
642 switch (call->app_call_state) {
643 case RXRPC_CSTATE_COMPLETE:
644 afs_kafsasyncd_attend_op(op);
645 break;
646 case RXRPC_CSTATE_CLNT_RCV_REPLY:
647 if (call->app_async_read)
648 break;
649 case RXRPC_CSTATE_CLNT_GOT_REPLY:
650 if (call->app_read_count == 0)
651 break;
652 printk("kAFS: Reply bigger than expected"
653 " {cst=%u asyn=%d mark=%Zu rdy=%Zu pr=%u%s}",
654 call->app_call_state,
655 call->app_async_read,
656 call->app_mark,
657 call->app_ready_qty,
658 call->pkt_rcv_count,
659 call->app_last_rcv ? " last" : "");
660
661 rxrpc_call_abort(call, -EBADMSG);
662 break;
663 default:
664 BUG();
665 }
666
667 _leave("");
David Howellsec268152007-04-26 15:49:28 -0700668}
Linus Torvalds1da177e2005-04-16 15:20:36 -0700669
Linus Torvalds1da177e2005-04-16 15:20:36 -0700670/*
671 * handle error events on an async get-entry-by-ID op
672 * - called from krxiod
673 */
674static void afs_rxvl_get_entry_by_id_error(struct rxrpc_call *call)
675{
676 struct afs_async_op *op = call->app_user;
677
678 _enter("{op=%p cst=%u}", op, call->app_call_state);
679
680 afs_kafsasyncd_attend_op(op);
681
682 _leave("");
David Howellsec268152007-04-26 15:49:28 -0700683}