[AFS]: Clean up the AFS sources
[powerpc.git] / fs / afs / vlclient.c
1 /* AFS Volume Location Service client
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/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
30 static void afs_rxvl_get_entry_by_id_attn(struct rxrpc_call *call);
31 static void afs_rxvl_get_entry_by_id_error(struct rxrpc_call *call);
32
33 /*
34  * map afs VL abort codes to/from Linux error codes
35  * - called with call->lock held
36  */
37 static 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         }
89 }
90
91 #if 0
92 /*
93  * probe a volume location server to see if it is still alive -- unused
94  */
95 static 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
160 abort:
161         set_current_state(TASK_UNINTERRUPTIBLE);
162         rxrpc_call_abort(call, ret);
163         schedule();
164
165 out_unwait:
166         set_current_state(TASK_RUNNING);
167         remove_wait_queue(&call->waitq, &myself);
168         rxrpc_put_call(call);
169 out_put_conn:
170         rxrpc_put_connection(conn);
171 out:
172         return ret;
173 }
174 #endif
175
176 /*
177  * look up a volume location database entry by name
178  */
179 int 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
293 out_unwait:
294         set_current_state(TASK_RUNNING);
295         remove_wait_queue(&call->waitq, &myself);
296         rxrpc_put_call(call);
297 out_put_conn:
298         rxrpc_put_connection(conn);
299 out:
300         _leave(" = %d", ret);
301         return ret;
302
303 abort:
304         set_current_state(TASK_UNINTERRUPTIBLE);
305         rxrpc_call_abort(call, ret);
306         schedule();
307         goto out_unwait;
308 }
309
310 /*
311  * look up a volume location database entry by ID
312  */
313 int 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
432 out_unwait:
433         set_current_state(TASK_RUNNING);
434         remove_wait_queue(&call->waitq, &myself);
435         rxrpc_put_call(call);
436 out_put_conn:
437         rxrpc_put_connection(conn);
438 out:
439         _leave(" = %d", ret);
440         return ret;
441
442 abort:
443         set_current_state(TASK_UNINTERRUPTIBLE);
444         rxrpc_call_abort(call, ret);
445         schedule();
446         goto out_unwait;
447 }
448
449 /*
450  * look up a volume location database entry by ID asynchronously
451  */
452 int 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
530 out:
531         rxrpc_put_call(call);
532         _leave(" = %d", ret);
533         return ret;
534 }
535
536 /*
537  * attend to the asynchronous get VLDB entry by ID
538  */
539 int 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
625 done:
626         rxrpc_put_call(op->call);
627         op->call = NULL;
628         _leave(" = %d", ret);
629         return ret;
630 }
631
632 /*
633  * handle attention events on an async get-entry-by-ID op
634  * - called from krxiod
635  */
636 static 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("");
668 }
669
670 /*
671  * handle error events on an async get-entry-by-ID op
672  * - called from krxiod
673  */
674 static 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("");
683 }