Export flush_dcache_page to modules.
[linux-2.6/linux-mips.git] / fs / afs / fsclient.c
blob6a31e03c52bb418c1642c74459838ed7974d2173
1 /* fsclient.c: AFS File Server client stubs
3 * Copyright (C) 2002 Red Hat, Inc. All Rights Reserved.
4 * Written by David Howells (dhowells@redhat.com)
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.
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 "fsclient.h"
19 #include "cmservice.h"
20 #include "vnode.h"
21 #include "server.h"
22 #include "errors.h"
23 #include "internal.h"
25 #define FSFETCHSTATUS 132 /* AFS Fetch file status */
26 #define FSFETCHDATA 130 /* AFS Fetch file data */
27 #define FSGIVEUPCALLBACKS 147 /* AFS Discard server callback promises */
28 #define FSGETVOLUMEINFO 148 /* AFS Get root volume information */
29 #define FSGETROOTVOLUME 151 /* AFS Get root volume name */
30 #define FSLOOKUP 161 /* AFS lookup file in directory */
32 /*****************************************************************************/
34 * map afs abort codes to/from Linux error codes
35 * - called with call->lock held
37 static void afs_rxfs_aemap(struct rxrpc_call *call)
39 switch (call->app_err_state) {
40 case RXRPC_ESTATE_LOCAL_ABORT:
41 call->app_abort_code = -call->app_errno;
42 break;
43 case RXRPC_ESTATE_PEER_ABORT:
44 call->app_errno = afs_abort_to_error(call->app_abort_code);
45 break;
46 default:
47 break;
49 } /* end afs_rxfs_aemap() */
51 /*****************************************************************************/
53 * get the root volume name from a fileserver
54 * - this operation doesn't seem to work correctly in OpenAFS server 1.2.2
56 #if 0
57 int afs_rxfs_get_root_volume(afs_server_t *server, char *buf, size_t *buflen)
59 DECLARE_WAITQUEUE(myself,current);
61 struct rxrpc_connection *conn;
62 struct rxrpc_call *call;
63 struct iovec piov[2];
64 size_t sent;
65 int ret;
66 u32 param[1];
68 kenter("%p,%p,%u",server,buf,*buflen);
70 /* get hold of the fileserver connection */
71 ret = afs_server_get_fsconn(server,&conn);
72 if (ret<0)
73 goto out;
75 /* create a call through that connection */
76 ret = rxrpc_create_call(conn,NULL,NULL,afs_rxfs_aemap,&call);
77 if (ret<0) {
78 printk("kAFS: Unable to create call: %d\n",ret);
79 goto out_put_conn;
81 call->app_opcode = FSGETROOTVOLUME;
83 /* we want to get event notifications from the call */
84 add_wait_queue(&call->waitq,&myself);
86 /* marshall the parameters */
87 param[0] = htonl(FSGETROOTVOLUME);
89 piov[0].iov_len = sizeof(param);
90 piov[0].iov_base = param;
92 /* send the parameters to the server */
93 ret = rxrpc_call_write_data(call,1,piov,RXRPC_LAST_PACKET,GFP_NOFS,0,&sent);
94 if (ret<0)
95 goto abort;
97 /* wait for the reply to completely arrive */
98 for (;;) {
99 set_current_state(TASK_INTERRUPTIBLE);
100 if (call->app_call_state!=RXRPC_CSTATE_CLNT_RCV_REPLY ||
101 signal_pending(current))
102 break;
103 schedule();
105 set_current_state(TASK_RUNNING);
107 ret = -EINTR;
108 if (signal_pending(current))
109 goto abort;
111 switch (call->app_call_state) {
112 case RXRPC_CSTATE_ERROR:
113 ret = call->app_errno;
114 kdebug("Got Error: %d",ret);
115 goto out_unwait;
117 case RXRPC_CSTATE_CLNT_GOT_REPLY:
118 /* read the reply */
119 kdebug("Got Reply: qty=%d",call->app_ready_qty);
121 ret = -EBADMSG;
122 if (call->app_ready_qty <= 4)
123 goto abort;
125 ret = rxrpc_call_read_data(call,NULL,call->app_ready_qty,0);
126 if (ret<0)
127 goto abort;
129 #if 0
130 /* unmarshall the reply */
131 bp = buffer;
132 for (loop=0; loop<65; loop++)
133 entry->name[loop] = ntohl(*bp++);
134 entry->name[64] = 0;
136 entry->type = ntohl(*bp++);
137 entry->num_servers = ntohl(*bp++);
139 for (loop=0; loop<8; loop++)
140 entry->servers[loop].addr.s_addr = *bp++;
142 for (loop=0; loop<8; loop++)
143 entry->servers[loop].partition = ntohl(*bp++);
145 for (loop=0; loop<8; loop++)
146 entry->servers[loop].flags = ntohl(*bp++);
148 for (loop=0; loop<3; loop++)
149 entry->volume_ids[loop] = ntohl(*bp++);
151 entry->clone_id = ntohl(*bp++);
152 entry->flags = ntohl(*bp);
153 #endif
155 /* success */
156 ret = 0;
157 goto out_unwait;
159 default:
160 BUG();
163 abort:
164 set_current_state(TASK_UNINTERRUPTIBLE);
165 rxrpc_call_abort(call,ret);
166 schedule();
167 out_unwait:
168 set_current_state(TASK_RUNNING);
169 remove_wait_queue(&call->waitq,&myself);
170 rxrpc_put_call(call);
171 out_put_conn:
172 afs_server_release_fsconn(server,conn);
173 out:
174 kleave("");
175 return ret;
176 } /* end afs_rxfs_get_root_volume() */
177 #endif
179 /*****************************************************************************/
181 * get information about a volume
183 #if 0
184 int afs_rxfs_get_volume_info(afs_server_t *server,
185 const char *name,
186 afs_volume_info_t *vinfo)
188 DECLARE_WAITQUEUE(myself,current);
190 struct rxrpc_connection *conn;
191 struct rxrpc_call *call;
192 struct iovec piov[3];
193 size_t sent;
194 int ret;
195 u32 param[2], *bp, zero;
197 _enter("%p,%s,%p",server,name,vinfo);
199 /* get hold of the fileserver connection */
200 ret = afs_server_get_fsconn(server,&conn);
201 if (ret<0)
202 goto out;
204 /* create a call through that connection */
205 ret = rxrpc_create_call(conn,NULL,NULL,afs_rxfs_aemap,&call);
206 if (ret<0) {
207 printk("kAFS: Unable to create call: %d\n",ret);
208 goto out_put_conn;
210 call->app_opcode = FSGETVOLUMEINFO;
212 /* we want to get event notifications from the call */
213 add_wait_queue(&call->waitq,&myself);
215 /* marshall the parameters */
216 piov[1].iov_len = strlen(name);
217 piov[1].iov_base = (char*)name;
219 zero = 0;
220 piov[2].iov_len = (4 - (piov[1].iov_len & 3)) & 3;
221 piov[2].iov_base = &zero;
223 param[0] = htonl(FSGETVOLUMEINFO);
224 param[1] = htonl(piov[1].iov_len);
226 piov[0].iov_len = sizeof(param);
227 piov[0].iov_base = param;
229 /* send the parameters to the server */
230 ret = rxrpc_call_write_data(call,3,piov,RXRPC_LAST_PACKET,GFP_NOFS,0,&sent);
231 if (ret<0)
232 goto abort;
234 /* wait for the reply to completely arrive */
235 bp = rxrpc_call_alloc_scratch(call,64);
237 ret = rxrpc_call_read_data(call,bp,64,RXRPC_CALL_READ_BLOCK|RXRPC_CALL_READ_ALL);
238 if (ret<0) {
239 if (ret==-ECONNABORTED) {
240 ret = call->app_errno;
241 goto out_unwait;
243 goto abort;
246 /* unmarshall the reply */
247 vinfo->vid = ntohl(*bp++);
248 vinfo->type = ntohl(*bp++);
250 vinfo->type_vids[0] = ntohl(*bp++);
251 vinfo->type_vids[1] = ntohl(*bp++);
252 vinfo->type_vids[2] = ntohl(*bp++);
253 vinfo->type_vids[3] = ntohl(*bp++);
254 vinfo->type_vids[4] = ntohl(*bp++);
256 vinfo->nservers = ntohl(*bp++);
257 vinfo->servers[0].addr.s_addr = *bp++;
258 vinfo->servers[1].addr.s_addr = *bp++;
259 vinfo->servers[2].addr.s_addr = *bp++;
260 vinfo->servers[3].addr.s_addr = *bp++;
261 vinfo->servers[4].addr.s_addr = *bp++;
262 vinfo->servers[5].addr.s_addr = *bp++;
263 vinfo->servers[6].addr.s_addr = *bp++;
264 vinfo->servers[7].addr.s_addr = *bp++;
266 ret = -EBADMSG;
267 if (vinfo->nservers>8)
268 goto abort;
270 /* success */
271 ret = 0;
273 out_unwait:
274 set_current_state(TASK_RUNNING);
275 remove_wait_queue(&call->waitq,&myself);
276 rxrpc_put_call(call);
277 out_put_conn:
278 afs_server_release_fsconn(server,conn);
279 out:
280 _leave("");
281 return ret;
283 abort:
284 set_current_state(TASK_UNINTERRUPTIBLE);
285 rxrpc_call_abort(call,ret);
286 schedule();
287 goto out_unwait;
289 } /* end afs_rxfs_get_volume_info() */
290 #endif
292 /*****************************************************************************/
294 * fetch the status information for a file
296 int afs_rxfs_fetch_file_status(afs_server_t *server,
297 afs_vnode_t *vnode,
298 afs_volsync_t *volsync)
300 DECLARE_WAITQUEUE(myself,current);
302 struct afs_server_callslot callslot;
303 struct rxrpc_call *call;
304 struct iovec piov[1];
305 size_t sent;
306 int ret;
307 u32 *bp;
309 _enter("%p,{%u,%u,%u}",server,vnode->fid.vid,vnode->fid.vnode,vnode->fid.unique);
311 /* get hold of the fileserver connection */
312 ret = afs_server_request_callslot(server,&callslot);
313 if (ret<0)
314 goto out;
316 /* create a call through that connection */
317 ret = rxrpc_create_call(callslot.conn,NULL,NULL,afs_rxfs_aemap,&call);
318 if (ret<0) {
319 printk("kAFS: Unable to create call: %d\n",ret);
320 goto out_put_conn;
322 call->app_opcode = FSFETCHSTATUS;
324 /* we want to get event notifications from the call */
325 add_wait_queue(&call->waitq,&myself);
327 /* marshall the parameters */
328 bp = rxrpc_call_alloc_scratch(call,16);
329 bp[0] = htonl(FSFETCHSTATUS);
330 bp[1] = htonl(vnode->fid.vid);
331 bp[2] = htonl(vnode->fid.vnode);
332 bp[3] = htonl(vnode->fid.unique);
334 piov[0].iov_len = 16;
335 piov[0].iov_base = bp;
337 /* send the parameters to the server */
338 ret = rxrpc_call_write_data(call,1,piov,RXRPC_LAST_PACKET,GFP_NOFS,0,&sent);
339 if (ret<0)
340 goto abort;
342 /* wait for the reply to completely arrive */
343 bp = rxrpc_call_alloc_scratch(call,120);
345 ret = rxrpc_call_read_data(call,bp,120,RXRPC_CALL_READ_BLOCK|RXRPC_CALL_READ_ALL);
346 if (ret<0) {
347 if (ret==-ECONNABORTED) {
348 ret = call->app_errno;
349 goto out_unwait;
351 goto abort;
354 /* unmarshall the reply */
355 vnode->status.if_version = ntohl(*bp++);
356 vnode->status.type = ntohl(*bp++);
357 vnode->status.nlink = ntohl(*bp++);
358 vnode->status.size = ntohl(*bp++);
359 vnode->status.version = ntohl(*bp++);
360 vnode->status.author = ntohl(*bp++);
361 vnode->status.owner = ntohl(*bp++);
362 vnode->status.caller_access = ntohl(*bp++);
363 vnode->status.anon_access = ntohl(*bp++);
364 vnode->status.mode = ntohl(*bp++);
365 vnode->status.parent.vid = vnode->fid.vid;
366 vnode->status.parent.vnode = ntohl(*bp++);
367 vnode->status.parent.unique = ntohl(*bp++);
368 bp++; /* seg size */
369 vnode->status.mtime_client = ntohl(*bp++);
370 vnode->status.mtime_server = ntohl(*bp++);
371 bp++; /* group */
372 bp++; /* sync counter */
373 vnode->status.version |= ((unsigned long long) ntohl(*bp++)) << 32;
374 bp++; /* spare2 */
375 bp++; /* spare3 */
376 bp++; /* spare4 */
378 vnode->cb_version = ntohl(*bp++);
379 vnode->cb_expiry = ntohl(*bp++);
380 vnode->cb_type = ntohl(*bp++);
382 if (volsync) {
383 volsync->creation = ntohl(*bp++);
384 bp++; /* spare2 */
385 bp++; /* spare3 */
386 bp++; /* spare4 */
387 bp++; /* spare5 */
388 bp++; /* spare6 */
391 /* success */
392 ret = 0;
394 out_unwait:
395 set_current_state(TASK_RUNNING);
396 remove_wait_queue(&call->waitq,&myself);
397 rxrpc_put_call(call);
398 out_put_conn:
399 afs_server_release_callslot(server,&callslot);
400 out:
401 _leave("");
402 return ret;
404 abort:
405 set_current_state(TASK_UNINTERRUPTIBLE);
406 rxrpc_call_abort(call,ret);
407 schedule();
408 goto out_unwait;
409 } /* end afs_rxfs_fetch_file_status() */
411 /*****************************************************************************/
413 * fetch the contents of a file or directory
415 int afs_rxfs_fetch_file_data(afs_server_t *server,
416 afs_vnode_t *vnode,
417 struct afs_rxfs_fetch_descriptor *desc,
418 afs_volsync_t *volsync)
420 DECLARE_WAITQUEUE(myself,current);
422 struct afs_server_callslot callslot;
423 struct rxrpc_call *call;
424 struct iovec piov[1];
425 size_t sent;
426 int ret;
427 u32 *bp;
429 _enter("%p,{fid={%u,%u,%u},sz=%Zu,of=%lu}",
430 server,
431 desc->fid.vid,
432 desc->fid.vnode,
433 desc->fid.unique,
434 desc->size,
435 desc->offset);
437 /* get hold of the fileserver connection */
438 ret = afs_server_request_callslot(server,&callslot);
439 if (ret<0)
440 goto out;
442 /* create a call through that connection */
443 ret = rxrpc_create_call(callslot.conn,NULL,NULL,afs_rxfs_aemap,&call);
444 if (ret<0) {
445 printk("kAFS: Unable to create call: %d\n",ret);
446 goto out_put_conn;
448 call->app_opcode = FSFETCHDATA;
450 /* we want to get event notifications from the call */
451 add_wait_queue(&call->waitq,&myself);
453 /* marshall the parameters */
454 bp = rxrpc_call_alloc_scratch(call,24);
455 bp[0] = htonl(FSFETCHDATA);
456 bp[1] = htonl(desc->fid.vid);
457 bp[2] = htonl(desc->fid.vnode);
458 bp[3] = htonl(desc->fid.unique);
459 bp[4] = htonl(desc->offset);
460 bp[5] = htonl(desc->size);
462 piov[0].iov_len = 24;
463 piov[0].iov_base = bp;
465 /* send the parameters to the server */
466 ret = rxrpc_call_write_data(call,1,piov,RXRPC_LAST_PACKET,GFP_NOFS,0,&sent);
467 if (ret<0)
468 goto abort;
470 /* wait for the data count to arrive */
471 ret = rxrpc_call_read_data(call,bp,4,RXRPC_CALL_READ_BLOCK);
472 if (ret<0)
473 goto read_failed;
475 desc->actual = ntohl(bp[0]);
476 if (desc->actual!=desc->size) {
477 ret = -EBADMSG;
478 goto abort;
481 /* call the app to read the actual data */
482 rxrpc_call_reset_scratch(call);
484 ret = rxrpc_call_read_data(call,desc->buffer,desc->actual,RXRPC_CALL_READ_BLOCK);
485 if (ret<0)
486 goto read_failed;
488 /* wait for the rest of the reply to completely arrive */
489 rxrpc_call_reset_scratch(call);
490 bp = rxrpc_call_alloc_scratch(call,120);
492 ret = rxrpc_call_read_data(call,bp,120,RXRPC_CALL_READ_BLOCK|RXRPC_CALL_READ_ALL);
493 if (ret<0)
494 goto read_failed;
496 /* unmarshall the reply */
497 vnode->status.if_version = ntohl(*bp++);
498 vnode->status.type = ntohl(*bp++);
499 vnode->status.nlink = ntohl(*bp++);
500 vnode->status.size = ntohl(*bp++);
501 vnode->status.version = ntohl(*bp++);
502 vnode->status.author = ntohl(*bp++);
503 vnode->status.owner = ntohl(*bp++);
504 vnode->status.caller_access = ntohl(*bp++);
505 vnode->status.anon_access = ntohl(*bp++);
506 vnode->status.mode = ntohl(*bp++);
507 vnode->status.parent.vid = desc->fid.vid;
508 vnode->status.parent.vnode = ntohl(*bp++);
509 vnode->status.parent.unique = ntohl(*bp++);
510 bp++; /* seg size */
511 vnode->status.mtime_client = ntohl(*bp++);
512 vnode->status.mtime_server = ntohl(*bp++);
513 bp++; /* group */
514 bp++; /* sync counter */
515 vnode->status.version |= ((unsigned long long) ntohl(*bp++)) << 32;
516 bp++; /* spare2 */
517 bp++; /* spare3 */
518 bp++; /* spare4 */
520 vnode->cb_version = ntohl(*bp++);
521 vnode->cb_expiry = ntohl(*bp++);
522 vnode->cb_type = ntohl(*bp++);
524 if (volsync) {
525 volsync->creation = ntohl(*bp++);
526 bp++; /* spare2 */
527 bp++; /* spare3 */
528 bp++; /* spare4 */
529 bp++; /* spare5 */
530 bp++; /* spare6 */
533 /* success */
534 ret = 0;
536 out_unwait:
537 set_current_state(TASK_RUNNING);
538 remove_wait_queue(&call->waitq,&myself);
539 rxrpc_put_call(call);
540 out_put_conn:
541 afs_server_release_callslot(server,&callslot);
542 out:
543 _leave(" = %d",ret);
544 return ret;
546 read_failed:
547 if (ret==-ECONNABORTED) {
548 ret = call->app_errno;
549 goto out_unwait;
552 abort:
553 set_current_state(TASK_UNINTERRUPTIBLE);
554 rxrpc_call_abort(call,ret);
555 schedule();
556 goto out_unwait;
558 } /* end afs_rxfs_fetch_file_data() */
560 /*****************************************************************************/
562 * ask the AFS fileserver to discard a callback request on a file
564 int afs_rxfs_give_up_callback(afs_server_t *server, afs_vnode_t *vnode)
566 DECLARE_WAITQUEUE(myself,current);
568 struct afs_server_callslot callslot;
569 struct rxrpc_call *call;
570 struct iovec piov[1];
571 size_t sent;
572 int ret;
573 u32 *bp;
575 _enter("%p,{%u,%u,%u}",server,vnode->fid.vid,vnode->fid.vnode,vnode->fid.unique);
577 /* get hold of the fileserver connection */
578 ret = afs_server_request_callslot(server,&callslot);
579 if (ret<0)
580 goto out;
582 /* create a call through that connection */
583 ret = rxrpc_create_call(callslot.conn,NULL,NULL,afs_rxfs_aemap,&call);
584 if (ret<0) {
585 printk("kAFS: Unable to create call: %d\n",ret);
586 goto out_put_conn;
588 call->app_opcode = FSGIVEUPCALLBACKS;
590 /* we want to get event notifications from the call */
591 add_wait_queue(&call->waitq,&myself);
593 /* marshall the parameters */
594 bp = rxrpc_call_alloc_scratch(call,(1+4+4)*4);
596 piov[0].iov_len = (1+4+4)*4;
597 piov[0].iov_base = bp;
599 *bp++ = htonl(FSGIVEUPCALLBACKS);
600 *bp++ = htonl(1);
601 *bp++ = htonl(vnode->fid.vid);
602 *bp++ = htonl(vnode->fid.vnode);
603 *bp++ = htonl(vnode->fid.unique);
604 *bp++ = htonl(1);
605 *bp++ = htonl(vnode->cb_version);
606 *bp++ = htonl(vnode->cb_expiry);
607 *bp++ = htonl(vnode->cb_type);
609 /* send the parameters to the server */
610 ret = rxrpc_call_write_data(call,1,piov,RXRPC_LAST_PACKET,GFP_NOFS,0,&sent);
611 if (ret<0)
612 goto abort;
614 /* wait for the reply to completely arrive */
615 for (;;) {
616 set_current_state(TASK_INTERRUPTIBLE);
617 if (call->app_call_state!=RXRPC_CSTATE_CLNT_RCV_REPLY ||
618 signal_pending(current))
619 break;
620 schedule();
622 set_current_state(TASK_RUNNING);
624 ret = -EINTR;
625 if (signal_pending(current))
626 goto abort;
628 switch (call->app_call_state) {
629 case RXRPC_CSTATE_ERROR:
630 ret = call->app_errno;
631 goto out_unwait;
633 case RXRPC_CSTATE_CLNT_GOT_REPLY:
634 ret = 0;
635 goto out_unwait;
637 default:
638 BUG();
641 out_unwait:
642 set_current_state(TASK_RUNNING);
643 remove_wait_queue(&call->waitq,&myself);
644 rxrpc_put_call(call);
645 out_put_conn:
646 afs_server_release_callslot(server,&callslot);
647 out:
648 _leave("");
649 return ret;
651 abort:
652 set_current_state(TASK_UNINTERRUPTIBLE);
653 rxrpc_call_abort(call,ret);
654 schedule();
655 goto out_unwait;
656 } /* end afs_rxfs_give_up_callback() */
658 /*****************************************************************************/
660 * look a filename up in a directory
661 * - this operation doesn't seem to work correctly in OpenAFS server 1.2.2
663 #if 0
664 int afs_rxfs_lookup(afs_server_t *server,
665 afs_vnode_t *dir,
666 const char *filename,
667 afs_vnode_t *vnode,
668 afs_volsync_t *volsync)
670 DECLARE_WAITQUEUE(myself,current);
672 struct rxrpc_connection *conn;
673 struct rxrpc_call *call;
674 struct iovec piov[3];
675 size_t sent;
676 int ret;
677 u32 *bp, zero;
679 kenter("%p,{%u,%u,%u},%s",server,fid->vid,fid->vnode,fid->unique,filename);
681 /* get hold of the fileserver connection */
682 ret = afs_server_get_fsconn(server,&conn);
683 if (ret<0)
684 goto out;
686 /* create a call through that connection */
687 ret = rxrpc_create_call(conn,NULL,NULL,afs_rxfs_aemap,&call);
688 if (ret<0) {
689 printk("kAFS: Unable to create call: %d\n",ret);
690 goto out_put_conn;
692 call->app_opcode = FSLOOKUP;
694 /* we want to get event notifications from the call */
695 add_wait_queue(&call->waitq,&myself);
697 /* marshall the parameters */
698 bp = rxrpc_call_alloc_scratch(call,20);
700 zero = 0;
702 piov[0].iov_len = 20;
703 piov[0].iov_base = bp;
704 piov[1].iov_len = strlen(filename);
705 piov[1].iov_base = (char*) filename;
706 piov[2].iov_len = (4 - (piov[1].iov_len & 3)) & 3;
707 piov[2].iov_base = &zero;
709 *bp++ = htonl(FSLOOKUP);
710 *bp++ = htonl(dirfid->vid);
711 *bp++ = htonl(dirfid->vnode);
712 *bp++ = htonl(dirfid->unique);
713 *bp++ = htonl(piov[1].iov_len);
715 /* send the parameters to the server */
716 ret = rxrpc_call_write_data(call,3,piov,RXRPC_LAST_PACKET,GFP_NOFS,0,&sent);
717 if (ret<0)
718 goto abort;
720 /* wait for the reply to completely arrive */
721 bp = rxrpc_call_alloc_scratch(call,220);
723 ret = rxrpc_call_read_data(call,bp,220,RXRPC_CALL_READ_BLOCK|RXRPC_CALL_READ_ALL);
724 if (ret<0) {
725 if (ret==-ECONNABORTED) {
726 ret = call->app_errno;
727 goto out_unwait;
729 goto abort;
732 /* unmarshall the reply */
733 fid->vid = ntohl(*bp++);
734 fid->vnode = ntohl(*bp++);
735 fid->unique = ntohl(*bp++);
737 vnode->status.if_version = ntohl(*bp++);
738 vnode->status.type = ntohl(*bp++);
739 vnode->status.nlink = ntohl(*bp++);
740 vnode->status.size = ntohl(*bp++);
741 vnode->status.version = ntohl(*bp++);
742 vnode->status.author = ntohl(*bp++);
743 vnode->status.owner = ntohl(*bp++);
744 vnode->status.caller_access = ntohl(*bp++);
745 vnode->status.anon_access = ntohl(*bp++);
746 vnode->status.mode = ntohl(*bp++);
747 vnode->status.parent.vid = dirfid->vid;
748 vnode->status.parent.vnode = ntohl(*bp++);
749 vnode->status.parent.unique = ntohl(*bp++);
750 bp++; /* seg size */
751 vnode->status.mtime_client = ntohl(*bp++);
752 vnode->status.mtime_server = ntohl(*bp++);
753 bp++; /* group */
754 bp++; /* sync counter */
755 vnode->status.version |= ((unsigned long long) ntohl(*bp++)) << 32;
756 bp++; /* spare2 */
757 bp++; /* spare3 */
758 bp++; /* spare4 */
760 dir->status.if_version = ntohl(*bp++);
761 dir->status.type = ntohl(*bp++);
762 dir->status.nlink = ntohl(*bp++);
763 dir->status.size = ntohl(*bp++);
764 dir->status.version = ntohl(*bp++);
765 dir->status.author = ntohl(*bp++);
766 dir->status.owner = ntohl(*bp++);
767 dir->status.caller_access = ntohl(*bp++);
768 dir->status.anon_access = ntohl(*bp++);
769 dir->status.mode = ntohl(*bp++);
770 dir->status.parent.vid = dirfid->vid;
771 dir->status.parent.vnode = ntohl(*bp++);
772 dir->status.parent.unique = ntohl(*bp++);
773 bp++; /* seg size */
774 dir->status.mtime_client = ntohl(*bp++);
775 dir->status.mtime_server = ntohl(*bp++);
776 bp++; /* group */
777 bp++; /* sync counter */
778 dir->status.version |= ((unsigned long long) ntohl(*bp++)) << 32;
779 bp++; /* spare2 */
780 bp++; /* spare3 */
781 bp++; /* spare4 */
783 callback->fid = *fid;
784 callback->version = ntohl(*bp++);
785 callback->expiry = ntohl(*bp++);
786 callback->type = ntohl(*bp++);
788 if (volsync) {
789 volsync->creation = ntohl(*bp++);
790 bp++; /* spare2 */
791 bp++; /* spare3 */
792 bp++; /* spare4 */
793 bp++; /* spare5 */
794 bp++; /* spare6 */
797 /* success */
798 ret = 0;
800 out_unwait:
801 set_current_state(TASK_RUNNING);
802 remove_wait_queue(&call->waitq,&myself);
803 rxrpc_put_call(call);
804 out_put_conn:
805 afs_server_release_fsconn(server,conn);
806 out:
807 kleave("");
808 return ret;
810 abort:
811 set_current_state(TASK_UNINTERRUPTIBLE);
812 rxrpc_call_abort(call,ret);
813 schedule();
814 goto out_unwait;
815 } /* end afs_rxfs_lookup() */
816 #endif