11da177e4SLinus Torvalds /* fsclient.c: AFS File Server client stubs 21da177e4SLinus Torvalds * 31da177e4SLinus Torvalds * Copyright (C) 2002 Red Hat, Inc. All Rights Reserved. 41da177e4SLinus Torvalds * Written by David Howells (dhowells@redhat.com) 51da177e4SLinus Torvalds * 61da177e4SLinus Torvalds * This program is free software; you can redistribute it and/or 71da177e4SLinus Torvalds * modify it under the terms of the GNU General Public License 81da177e4SLinus Torvalds * as published by the Free Software Foundation; either version 91da177e4SLinus Torvalds * 2 of the License, or (at your option) any later version. 101da177e4SLinus Torvalds */ 111da177e4SLinus Torvalds 121da177e4SLinus Torvalds #include <linux/init.h> 131da177e4SLinus Torvalds #include <linux/sched.h> 141da177e4SLinus Torvalds #include <rxrpc/rxrpc.h> 151da177e4SLinus Torvalds #include <rxrpc/transport.h> 161da177e4SLinus Torvalds #include <rxrpc/connection.h> 171da177e4SLinus Torvalds #include <rxrpc/call.h> 181da177e4SLinus Torvalds #include "fsclient.h" 191da177e4SLinus Torvalds #include "cmservice.h" 201da177e4SLinus Torvalds #include "vnode.h" 211da177e4SLinus Torvalds #include "server.h" 221da177e4SLinus Torvalds #include "errors.h" 231da177e4SLinus Torvalds #include "internal.h" 241da177e4SLinus Torvalds 251da177e4SLinus Torvalds #define FSFETCHSTATUS 132 /* AFS Fetch file status */ 261da177e4SLinus Torvalds #define FSFETCHDATA 130 /* AFS Fetch file data */ 271da177e4SLinus Torvalds #define FSGIVEUPCALLBACKS 147 /* AFS Discard callback promises */ 281da177e4SLinus Torvalds #define FSGETVOLUMEINFO 148 /* AFS Get root volume information */ 291da177e4SLinus Torvalds #define FSGETROOTVOLUME 151 /* AFS Get root volume name */ 301da177e4SLinus Torvalds #define FSLOOKUP 161 /* AFS lookup file in directory */ 311da177e4SLinus Torvalds 321da177e4SLinus Torvalds /*****************************************************************************/ 331da177e4SLinus Torvalds /* 341da177e4SLinus Torvalds * map afs abort codes to/from Linux error codes 351da177e4SLinus Torvalds * - called with call->lock held 361da177e4SLinus Torvalds */ 371da177e4SLinus Torvalds static void afs_rxfs_aemap(struct rxrpc_call *call) 381da177e4SLinus Torvalds { 391da177e4SLinus Torvalds switch (call->app_err_state) { 401da177e4SLinus Torvalds case RXRPC_ESTATE_LOCAL_ABORT: 411da177e4SLinus Torvalds call->app_abort_code = -call->app_errno; 421da177e4SLinus Torvalds break; 431da177e4SLinus Torvalds case RXRPC_ESTATE_PEER_ABORT: 441da177e4SLinus Torvalds call->app_errno = afs_abort_to_error(call->app_abort_code); 451da177e4SLinus Torvalds break; 461da177e4SLinus Torvalds default: 471da177e4SLinus Torvalds break; 481da177e4SLinus Torvalds } 491da177e4SLinus Torvalds } /* end afs_rxfs_aemap() */ 501da177e4SLinus Torvalds 511da177e4SLinus Torvalds /*****************************************************************************/ 521da177e4SLinus Torvalds /* 531da177e4SLinus Torvalds * get the root volume name from a fileserver 541da177e4SLinus Torvalds * - this operation doesn't seem to work correctly in OpenAFS server 1.2.2 551da177e4SLinus Torvalds */ 561da177e4SLinus Torvalds #if 0 571da177e4SLinus Torvalds int afs_rxfs_get_root_volume(struct afs_server *server, 581da177e4SLinus Torvalds char *buf, size_t *buflen) 591da177e4SLinus Torvalds { 601da177e4SLinus Torvalds struct rxrpc_connection *conn; 611da177e4SLinus Torvalds struct rxrpc_call *call; 621da177e4SLinus Torvalds struct kvec piov[2]; 631da177e4SLinus Torvalds size_t sent; 641da177e4SLinus Torvalds int ret; 651da177e4SLinus Torvalds u32 param[1]; 661da177e4SLinus Torvalds 671da177e4SLinus Torvalds DECLARE_WAITQUEUE(myself, current); 681da177e4SLinus Torvalds 691da177e4SLinus Torvalds kenter("%p,%p,%u",server, buf, *buflen); 701da177e4SLinus Torvalds 711da177e4SLinus Torvalds /* get hold of the fileserver connection */ 721da177e4SLinus Torvalds ret = afs_server_get_fsconn(server, &conn); 731da177e4SLinus Torvalds if (ret < 0) 741da177e4SLinus Torvalds goto out; 751da177e4SLinus Torvalds 761da177e4SLinus Torvalds /* create a call through that connection */ 771da177e4SLinus Torvalds ret = rxrpc_create_call(conn, NULL, NULL, afs_rxfs_aemap, &call); 781da177e4SLinus Torvalds if (ret < 0) { 791da177e4SLinus Torvalds printk("kAFS: Unable to create call: %d\n", ret); 801da177e4SLinus Torvalds goto out_put_conn; 811da177e4SLinus Torvalds } 821da177e4SLinus Torvalds call->app_opcode = FSGETROOTVOLUME; 831da177e4SLinus Torvalds 841da177e4SLinus Torvalds /* we want to get event notifications from the call */ 851da177e4SLinus Torvalds add_wait_queue(&call->waitq, &myself); 861da177e4SLinus Torvalds 871da177e4SLinus Torvalds /* marshall the parameters */ 881da177e4SLinus Torvalds param[0] = htonl(FSGETROOTVOLUME); 891da177e4SLinus Torvalds 901da177e4SLinus Torvalds piov[0].iov_len = sizeof(param); 911da177e4SLinus Torvalds piov[0].iov_base = param; 921da177e4SLinus Torvalds 931da177e4SLinus Torvalds /* send the parameters to the server */ 941da177e4SLinus Torvalds ret = rxrpc_call_write_data(call, 1, piov, RXRPC_LAST_PACKET, GFP_NOFS, 951da177e4SLinus Torvalds 0, &sent); 961da177e4SLinus Torvalds if (ret < 0) 971da177e4SLinus Torvalds goto abort; 981da177e4SLinus Torvalds 991da177e4SLinus Torvalds /* wait for the reply to completely arrive */ 1001da177e4SLinus Torvalds for (;;) { 1011da177e4SLinus Torvalds set_current_state(TASK_INTERRUPTIBLE); 1021da177e4SLinus Torvalds if (call->app_call_state != RXRPC_CSTATE_CLNT_RCV_REPLY || 1031da177e4SLinus Torvalds signal_pending(current)) 1041da177e4SLinus Torvalds break; 1051da177e4SLinus Torvalds schedule(); 1061da177e4SLinus Torvalds } 1071da177e4SLinus Torvalds set_current_state(TASK_RUNNING); 1081da177e4SLinus Torvalds 1091da177e4SLinus Torvalds ret = -EINTR; 1101da177e4SLinus Torvalds if (signal_pending(current)) 1111da177e4SLinus Torvalds goto abort; 1121da177e4SLinus Torvalds 1131da177e4SLinus Torvalds switch (call->app_call_state) { 1141da177e4SLinus Torvalds case RXRPC_CSTATE_ERROR: 1151da177e4SLinus Torvalds ret = call->app_errno; 1161da177e4SLinus Torvalds kdebug("Got Error: %d", ret); 1171da177e4SLinus Torvalds goto out_unwait; 1181da177e4SLinus Torvalds 1191da177e4SLinus Torvalds case RXRPC_CSTATE_CLNT_GOT_REPLY: 1201da177e4SLinus Torvalds /* read the reply */ 1211da177e4SLinus Torvalds kdebug("Got Reply: qty=%d", call->app_ready_qty); 1221da177e4SLinus Torvalds 1231da177e4SLinus Torvalds ret = -EBADMSG; 1241da177e4SLinus Torvalds if (call->app_ready_qty <= 4) 1251da177e4SLinus Torvalds goto abort; 1261da177e4SLinus Torvalds 1271da177e4SLinus Torvalds ret = rxrpc_call_read_data(call, NULL, call->app_ready_qty, 0); 1281da177e4SLinus Torvalds if (ret < 0) 1291da177e4SLinus Torvalds goto abort; 1301da177e4SLinus Torvalds 1311da177e4SLinus Torvalds #if 0 1321da177e4SLinus Torvalds /* unmarshall the reply */ 1331da177e4SLinus Torvalds bp = buffer; 1341da177e4SLinus Torvalds for (loop = 0; loop < 65; loop++) 1351da177e4SLinus Torvalds entry->name[loop] = ntohl(*bp++); 1361da177e4SLinus Torvalds entry->name[64] = 0; 1371da177e4SLinus Torvalds 1381da177e4SLinus Torvalds entry->type = ntohl(*bp++); 1391da177e4SLinus Torvalds entry->num_servers = ntohl(*bp++); 1401da177e4SLinus Torvalds 1411da177e4SLinus Torvalds for (loop = 0; loop < 8; loop++) 1421da177e4SLinus Torvalds entry->servers[loop].addr.s_addr = *bp++; 1431da177e4SLinus Torvalds 1441da177e4SLinus Torvalds for (loop = 0; loop < 8; loop++) 1451da177e4SLinus Torvalds entry->servers[loop].partition = ntohl(*bp++); 1461da177e4SLinus Torvalds 1471da177e4SLinus Torvalds for (loop = 0; loop < 8; loop++) 1481da177e4SLinus Torvalds entry->servers[loop].flags = ntohl(*bp++); 1491da177e4SLinus Torvalds 1501da177e4SLinus Torvalds for (loop = 0; loop < 3; loop++) 1511da177e4SLinus Torvalds entry->volume_ids[loop] = ntohl(*bp++); 1521da177e4SLinus Torvalds 1531da177e4SLinus Torvalds entry->clone_id = ntohl(*bp++); 1541da177e4SLinus Torvalds entry->flags = ntohl(*bp); 1551da177e4SLinus Torvalds #endif 1561da177e4SLinus Torvalds 1571da177e4SLinus Torvalds /* success */ 1581da177e4SLinus Torvalds ret = 0; 1591da177e4SLinus Torvalds goto out_unwait; 1601da177e4SLinus Torvalds 1611da177e4SLinus Torvalds default: 1621da177e4SLinus Torvalds BUG(); 1631da177e4SLinus Torvalds } 1641da177e4SLinus Torvalds 1651da177e4SLinus Torvalds abort: 1661da177e4SLinus Torvalds set_current_state(TASK_UNINTERRUPTIBLE); 1671da177e4SLinus Torvalds rxrpc_call_abort(call, ret); 1681da177e4SLinus Torvalds schedule(); 1691da177e4SLinus Torvalds out_unwait: 1701da177e4SLinus Torvalds set_current_state(TASK_RUNNING); 1711da177e4SLinus Torvalds remove_wait_queue(&call->waitq, &myself); 1721da177e4SLinus Torvalds rxrpc_put_call(call); 1731da177e4SLinus Torvalds out_put_conn: 1741da177e4SLinus Torvalds afs_server_release_fsconn(server, conn); 1751da177e4SLinus Torvalds out: 1761da177e4SLinus Torvalds kleave(""); 1771da177e4SLinus Torvalds return ret; 1781da177e4SLinus Torvalds } /* end afs_rxfs_get_root_volume() */ 1791da177e4SLinus Torvalds #endif 1801da177e4SLinus Torvalds 1811da177e4SLinus Torvalds /*****************************************************************************/ 1821da177e4SLinus Torvalds /* 1831da177e4SLinus Torvalds * get information about a volume 1841da177e4SLinus Torvalds */ 1851da177e4SLinus Torvalds #if 0 1861da177e4SLinus Torvalds int afs_rxfs_get_volume_info(struct afs_server *server, 1871da177e4SLinus Torvalds const char *name, 1881da177e4SLinus Torvalds struct afs_volume_info *vinfo) 1891da177e4SLinus Torvalds { 1901da177e4SLinus Torvalds struct rxrpc_connection *conn; 1911da177e4SLinus Torvalds struct rxrpc_call *call; 1921da177e4SLinus Torvalds struct kvec piov[3]; 1931da177e4SLinus Torvalds size_t sent; 1941da177e4SLinus Torvalds int ret; 1951da177e4SLinus Torvalds u32 param[2], *bp, zero; 1961da177e4SLinus Torvalds 1971da177e4SLinus Torvalds DECLARE_WAITQUEUE(myself, current); 1981da177e4SLinus Torvalds 1991da177e4SLinus Torvalds _enter("%p,%s,%p", server, name, vinfo); 2001da177e4SLinus Torvalds 2011da177e4SLinus Torvalds /* get hold of the fileserver connection */ 2021da177e4SLinus Torvalds ret = afs_server_get_fsconn(server, &conn); 2031da177e4SLinus Torvalds if (ret < 0) 2041da177e4SLinus Torvalds goto out; 2051da177e4SLinus Torvalds 2061da177e4SLinus Torvalds /* create a call through that connection */ 2071da177e4SLinus Torvalds ret = rxrpc_create_call(conn, NULL, NULL, afs_rxfs_aemap, &call); 2081da177e4SLinus Torvalds if (ret < 0) { 2091da177e4SLinus Torvalds printk("kAFS: Unable to create call: %d\n", ret); 2101da177e4SLinus Torvalds goto out_put_conn; 2111da177e4SLinus Torvalds } 2121da177e4SLinus Torvalds call->app_opcode = FSGETVOLUMEINFO; 2131da177e4SLinus Torvalds 2141da177e4SLinus Torvalds /* we want to get event notifications from the call */ 2151da177e4SLinus Torvalds add_wait_queue(&call->waitq, &myself); 2161da177e4SLinus Torvalds 2171da177e4SLinus Torvalds /* marshall the parameters */ 2181da177e4SLinus Torvalds piov[1].iov_len = strlen(name); 2191da177e4SLinus Torvalds piov[1].iov_base = (char *) name; 2201da177e4SLinus Torvalds 2211da177e4SLinus Torvalds zero = 0; 2221da177e4SLinus Torvalds piov[2].iov_len = (4 - (piov[1].iov_len & 3)) & 3; 2231da177e4SLinus Torvalds piov[2].iov_base = &zero; 2241da177e4SLinus Torvalds 2251da177e4SLinus Torvalds param[0] = htonl(FSGETVOLUMEINFO); 2261da177e4SLinus Torvalds param[1] = htonl(piov[1].iov_len); 2271da177e4SLinus Torvalds 2281da177e4SLinus Torvalds piov[0].iov_len = sizeof(param); 2291da177e4SLinus Torvalds piov[0].iov_base = param; 2301da177e4SLinus Torvalds 2311da177e4SLinus Torvalds /* send the parameters to the server */ 2321da177e4SLinus Torvalds ret = rxrpc_call_write_data(call, 3, piov, RXRPC_LAST_PACKET, GFP_NOFS, 2331da177e4SLinus Torvalds 0, &sent); 2341da177e4SLinus Torvalds if (ret < 0) 2351da177e4SLinus Torvalds goto abort; 2361da177e4SLinus Torvalds 2371da177e4SLinus Torvalds /* wait for the reply to completely arrive */ 2381da177e4SLinus Torvalds bp = rxrpc_call_alloc_scratch(call, 64); 2391da177e4SLinus Torvalds 2401da177e4SLinus Torvalds ret = rxrpc_call_read_data(call, bp, 64, 2411da177e4SLinus Torvalds RXRPC_CALL_READ_BLOCK | 2421da177e4SLinus Torvalds RXRPC_CALL_READ_ALL); 2431da177e4SLinus Torvalds if (ret < 0) { 2441da177e4SLinus Torvalds if (ret == -ECONNABORTED) { 2451da177e4SLinus Torvalds ret = call->app_errno; 2461da177e4SLinus Torvalds goto out_unwait; 2471da177e4SLinus Torvalds } 2481da177e4SLinus Torvalds goto abort; 2491da177e4SLinus Torvalds } 2501da177e4SLinus Torvalds 2511da177e4SLinus Torvalds /* unmarshall the reply */ 2521da177e4SLinus Torvalds vinfo->vid = ntohl(*bp++); 2531da177e4SLinus Torvalds vinfo->type = ntohl(*bp++); 2541da177e4SLinus Torvalds 2551da177e4SLinus Torvalds vinfo->type_vids[0] = ntohl(*bp++); 2561da177e4SLinus Torvalds vinfo->type_vids[1] = ntohl(*bp++); 2571da177e4SLinus Torvalds vinfo->type_vids[2] = ntohl(*bp++); 2581da177e4SLinus Torvalds vinfo->type_vids[3] = ntohl(*bp++); 2591da177e4SLinus Torvalds vinfo->type_vids[4] = ntohl(*bp++); 2601da177e4SLinus Torvalds 2611da177e4SLinus Torvalds vinfo->nservers = ntohl(*bp++); 2621da177e4SLinus Torvalds vinfo->servers[0].addr.s_addr = *bp++; 2631da177e4SLinus Torvalds vinfo->servers[1].addr.s_addr = *bp++; 2641da177e4SLinus Torvalds vinfo->servers[2].addr.s_addr = *bp++; 2651da177e4SLinus Torvalds vinfo->servers[3].addr.s_addr = *bp++; 2661da177e4SLinus Torvalds vinfo->servers[4].addr.s_addr = *bp++; 2671da177e4SLinus Torvalds vinfo->servers[5].addr.s_addr = *bp++; 2681da177e4SLinus Torvalds vinfo->servers[6].addr.s_addr = *bp++; 2691da177e4SLinus Torvalds vinfo->servers[7].addr.s_addr = *bp++; 2701da177e4SLinus Torvalds 2711da177e4SLinus Torvalds ret = -EBADMSG; 2721da177e4SLinus Torvalds if (vinfo->nservers > 8) 2731da177e4SLinus Torvalds goto abort; 2741da177e4SLinus Torvalds 2751da177e4SLinus Torvalds /* success */ 2761da177e4SLinus Torvalds ret = 0; 2771da177e4SLinus Torvalds 2781da177e4SLinus Torvalds out_unwait: 2791da177e4SLinus Torvalds set_current_state(TASK_RUNNING); 2801da177e4SLinus Torvalds remove_wait_queue(&call->waitq, &myself); 2811da177e4SLinus Torvalds rxrpc_put_call(call); 2821da177e4SLinus Torvalds out_put_conn: 2831da177e4SLinus Torvalds afs_server_release_fsconn(server, conn); 2841da177e4SLinus Torvalds out: 2851da177e4SLinus Torvalds _leave(""); 2861da177e4SLinus Torvalds return ret; 2871da177e4SLinus Torvalds 2881da177e4SLinus Torvalds abort: 2891da177e4SLinus Torvalds set_current_state(TASK_UNINTERRUPTIBLE); 2901da177e4SLinus Torvalds rxrpc_call_abort(call, ret); 2911da177e4SLinus Torvalds schedule(); 2921da177e4SLinus Torvalds goto out_unwait; 2931da177e4SLinus Torvalds 2941da177e4SLinus Torvalds } /* end afs_rxfs_get_volume_info() */ 2951da177e4SLinus Torvalds #endif 2961da177e4SLinus Torvalds 2971da177e4SLinus Torvalds /*****************************************************************************/ 2981da177e4SLinus Torvalds /* 2991da177e4SLinus Torvalds * fetch the status information for a file 3001da177e4SLinus Torvalds */ 3011da177e4SLinus Torvalds int afs_rxfs_fetch_file_status(struct afs_server *server, 3021da177e4SLinus Torvalds struct afs_vnode *vnode, 3031da177e4SLinus Torvalds struct afs_volsync *volsync) 3041da177e4SLinus Torvalds { 3051da177e4SLinus Torvalds struct afs_server_callslot callslot; 3061da177e4SLinus Torvalds struct rxrpc_call *call; 3071da177e4SLinus Torvalds struct kvec piov[1]; 3081da177e4SLinus Torvalds size_t sent; 3091da177e4SLinus Torvalds int ret; 3101da177e4SLinus Torvalds __be32 *bp; 3111da177e4SLinus Torvalds 3121da177e4SLinus Torvalds DECLARE_WAITQUEUE(myself, current); 3131da177e4SLinus Torvalds 3141da177e4SLinus Torvalds _enter("%p,{%u,%u,%u}", 3151da177e4SLinus Torvalds server, vnode->fid.vid, vnode->fid.vnode, vnode->fid.unique); 3161da177e4SLinus Torvalds 3171da177e4SLinus Torvalds /* get hold of the fileserver connection */ 3181da177e4SLinus Torvalds ret = afs_server_request_callslot(server, &callslot); 3191da177e4SLinus Torvalds if (ret < 0) 3201da177e4SLinus Torvalds goto out; 3211da177e4SLinus Torvalds 3221da177e4SLinus Torvalds /* create a call through that connection */ 3231da177e4SLinus Torvalds ret = rxrpc_create_call(callslot.conn, NULL, NULL, afs_rxfs_aemap, 3241da177e4SLinus Torvalds &call); 3251da177e4SLinus Torvalds if (ret < 0) { 3261da177e4SLinus Torvalds printk("kAFS: Unable to create call: %d\n", ret); 3271da177e4SLinus Torvalds goto out_put_conn; 3281da177e4SLinus Torvalds } 3291da177e4SLinus Torvalds call->app_opcode = FSFETCHSTATUS; 3301da177e4SLinus Torvalds 3311da177e4SLinus Torvalds /* we want to get event notifications from the call */ 3321da177e4SLinus Torvalds add_wait_queue(&call->waitq, &myself); 3331da177e4SLinus Torvalds 3341da177e4SLinus Torvalds /* marshall the parameters */ 3351da177e4SLinus Torvalds bp = rxrpc_call_alloc_scratch(call, 16); 3361da177e4SLinus Torvalds bp[0] = htonl(FSFETCHSTATUS); 3371da177e4SLinus Torvalds bp[1] = htonl(vnode->fid.vid); 3381da177e4SLinus Torvalds bp[2] = htonl(vnode->fid.vnode); 3391da177e4SLinus Torvalds bp[3] = htonl(vnode->fid.unique); 3401da177e4SLinus Torvalds 3411da177e4SLinus Torvalds piov[0].iov_len = 16; 3421da177e4SLinus Torvalds piov[0].iov_base = bp; 3431da177e4SLinus Torvalds 3441da177e4SLinus Torvalds /* send the parameters to the server */ 3451da177e4SLinus Torvalds ret = rxrpc_call_write_data(call, 1, piov, RXRPC_LAST_PACKET, GFP_NOFS, 3461da177e4SLinus Torvalds 0, &sent); 3471da177e4SLinus Torvalds if (ret < 0) 3481da177e4SLinus Torvalds goto abort; 3491da177e4SLinus Torvalds 3501da177e4SLinus Torvalds /* wait for the reply to completely arrive */ 3511da177e4SLinus Torvalds bp = rxrpc_call_alloc_scratch(call, 120); 3521da177e4SLinus Torvalds 3531da177e4SLinus Torvalds ret = rxrpc_call_read_data(call, bp, 120, 3541da177e4SLinus Torvalds RXRPC_CALL_READ_BLOCK | 3551da177e4SLinus Torvalds RXRPC_CALL_READ_ALL); 3561da177e4SLinus Torvalds if (ret < 0) { 3571da177e4SLinus Torvalds if (ret == -ECONNABORTED) { 3581da177e4SLinus Torvalds ret = call->app_errno; 3591da177e4SLinus Torvalds goto out_unwait; 3601da177e4SLinus Torvalds } 3611da177e4SLinus Torvalds goto abort; 3621da177e4SLinus Torvalds } 3631da177e4SLinus Torvalds 3641da177e4SLinus Torvalds /* unmarshall the reply */ 3651da177e4SLinus Torvalds vnode->status.if_version = ntohl(*bp++); 3661da177e4SLinus Torvalds vnode->status.type = ntohl(*bp++); 3671da177e4SLinus Torvalds vnode->status.nlink = ntohl(*bp++); 3681da177e4SLinus Torvalds vnode->status.size = ntohl(*bp++); 3691da177e4SLinus Torvalds vnode->status.version = ntohl(*bp++); 3701da177e4SLinus Torvalds vnode->status.author = ntohl(*bp++); 3711da177e4SLinus Torvalds vnode->status.owner = ntohl(*bp++); 3721da177e4SLinus Torvalds vnode->status.caller_access = ntohl(*bp++); 3731da177e4SLinus Torvalds vnode->status.anon_access = ntohl(*bp++); 3741da177e4SLinus Torvalds vnode->status.mode = ntohl(*bp++); 3751da177e4SLinus Torvalds vnode->status.parent.vid = vnode->fid.vid; 3761da177e4SLinus Torvalds vnode->status.parent.vnode = ntohl(*bp++); 3771da177e4SLinus Torvalds vnode->status.parent.unique = ntohl(*bp++); 3781da177e4SLinus Torvalds bp++; /* seg size */ 3791da177e4SLinus Torvalds vnode->status.mtime_client = ntohl(*bp++); 3801da177e4SLinus Torvalds vnode->status.mtime_server = ntohl(*bp++); 3811da177e4SLinus Torvalds bp++; /* group */ 3821da177e4SLinus Torvalds bp++; /* sync counter */ 3831da177e4SLinus Torvalds vnode->status.version |= ((unsigned long long) ntohl(*bp++)) << 32; 3841da177e4SLinus Torvalds bp++; /* spare2 */ 3851da177e4SLinus Torvalds bp++; /* spare3 */ 3861da177e4SLinus Torvalds bp++; /* spare4 */ 3871da177e4SLinus Torvalds 3881da177e4SLinus Torvalds vnode->cb_version = ntohl(*bp++); 3891da177e4SLinus Torvalds vnode->cb_expiry = ntohl(*bp++); 3901da177e4SLinus Torvalds vnode->cb_type = ntohl(*bp++); 3911da177e4SLinus Torvalds 3921da177e4SLinus Torvalds if (volsync) { 3931da177e4SLinus Torvalds volsync->creation = ntohl(*bp++); 3941da177e4SLinus Torvalds bp++; /* spare2 */ 3951da177e4SLinus Torvalds bp++; /* spare3 */ 3961da177e4SLinus Torvalds bp++; /* spare4 */ 3971da177e4SLinus Torvalds bp++; /* spare5 */ 3981da177e4SLinus Torvalds bp++; /* spare6 */ 3991da177e4SLinus Torvalds } 4001da177e4SLinus Torvalds 4011da177e4SLinus Torvalds /* success */ 4021da177e4SLinus Torvalds ret = 0; 4031da177e4SLinus Torvalds 4041da177e4SLinus Torvalds out_unwait: 4051da177e4SLinus Torvalds set_current_state(TASK_RUNNING); 4061da177e4SLinus Torvalds remove_wait_queue(&call->waitq, &myself); 4071da177e4SLinus Torvalds rxrpc_put_call(call); 4081da177e4SLinus Torvalds out_put_conn: 4091da177e4SLinus Torvalds afs_server_release_callslot(server, &callslot); 4101da177e4SLinus Torvalds out: 4111da177e4SLinus Torvalds _leave(""); 4121da177e4SLinus Torvalds return ret; 4131da177e4SLinus Torvalds 4141da177e4SLinus Torvalds abort: 4151da177e4SLinus Torvalds set_current_state(TASK_UNINTERRUPTIBLE); 4161da177e4SLinus Torvalds rxrpc_call_abort(call, ret); 4171da177e4SLinus Torvalds schedule(); 4181da177e4SLinus Torvalds goto out_unwait; 4191da177e4SLinus Torvalds } /* end afs_rxfs_fetch_file_status() */ 4201da177e4SLinus Torvalds 4211da177e4SLinus Torvalds /*****************************************************************************/ 4221da177e4SLinus Torvalds /* 4231da177e4SLinus Torvalds * fetch the contents of a file or directory 4241da177e4SLinus Torvalds */ 4251da177e4SLinus Torvalds int afs_rxfs_fetch_file_data(struct afs_server *server, 4261da177e4SLinus Torvalds struct afs_vnode *vnode, 4271da177e4SLinus Torvalds struct afs_rxfs_fetch_descriptor *desc, 4281da177e4SLinus Torvalds struct afs_volsync *volsync) 4291da177e4SLinus Torvalds { 4301da177e4SLinus Torvalds struct afs_server_callslot callslot; 4311da177e4SLinus Torvalds struct rxrpc_call *call; 4321da177e4SLinus Torvalds struct kvec piov[1]; 4331da177e4SLinus Torvalds size_t sent; 4341da177e4SLinus Torvalds int ret; 4351da177e4SLinus Torvalds __be32 *bp; 4361da177e4SLinus Torvalds 4371da177e4SLinus Torvalds DECLARE_WAITQUEUE(myself, current); 4381da177e4SLinus Torvalds 4391da177e4SLinus Torvalds _enter("%p,{fid={%u,%u,%u},sz=%Zu,of=%lu}", 4401da177e4SLinus Torvalds server, 4411da177e4SLinus Torvalds desc->fid.vid, 4421da177e4SLinus Torvalds desc->fid.vnode, 4431da177e4SLinus Torvalds desc->fid.unique, 4441da177e4SLinus Torvalds desc->size, 4451da177e4SLinus Torvalds desc->offset); 4461da177e4SLinus Torvalds 4471da177e4SLinus Torvalds /* get hold of the fileserver connection */ 4481da177e4SLinus Torvalds ret = afs_server_request_callslot(server, &callslot); 4491da177e4SLinus Torvalds if (ret < 0) 4501da177e4SLinus Torvalds goto out; 4511da177e4SLinus Torvalds 4521da177e4SLinus Torvalds /* create a call through that connection */ 4531da177e4SLinus Torvalds ret = rxrpc_create_call(callslot.conn, NULL, NULL, afs_rxfs_aemap, &call); 4541da177e4SLinus Torvalds if (ret < 0) { 4551da177e4SLinus Torvalds printk("kAFS: Unable to create call: %d\n", ret); 4561da177e4SLinus Torvalds goto out_put_conn; 4571da177e4SLinus Torvalds } 4581da177e4SLinus Torvalds call->app_opcode = FSFETCHDATA; 4591da177e4SLinus Torvalds 4601da177e4SLinus Torvalds /* we want to get event notifications from the call */ 4611da177e4SLinus Torvalds add_wait_queue(&call->waitq, &myself); 4621da177e4SLinus Torvalds 4631da177e4SLinus Torvalds /* marshall the parameters */ 4641da177e4SLinus Torvalds bp = rxrpc_call_alloc_scratch(call, 24); 4651da177e4SLinus Torvalds bp[0] = htonl(FSFETCHDATA); 4661da177e4SLinus Torvalds bp[1] = htonl(desc->fid.vid); 4671da177e4SLinus Torvalds bp[2] = htonl(desc->fid.vnode); 4681da177e4SLinus Torvalds bp[3] = htonl(desc->fid.unique); 4691da177e4SLinus Torvalds bp[4] = htonl(desc->offset); 4701da177e4SLinus Torvalds bp[5] = htonl(desc->size); 4711da177e4SLinus Torvalds 4721da177e4SLinus Torvalds piov[0].iov_len = 24; 4731da177e4SLinus Torvalds piov[0].iov_base = bp; 4741da177e4SLinus Torvalds 4751da177e4SLinus Torvalds /* send the parameters to the server */ 4761da177e4SLinus Torvalds ret = rxrpc_call_write_data(call, 1, piov, RXRPC_LAST_PACKET, GFP_NOFS, 4771da177e4SLinus Torvalds 0, &sent); 4781da177e4SLinus Torvalds if (ret < 0) 4791da177e4SLinus Torvalds goto abort; 4801da177e4SLinus Torvalds 4811da177e4SLinus Torvalds /* wait for the data count to arrive */ 4821da177e4SLinus Torvalds ret = rxrpc_call_read_data(call, bp, 4, RXRPC_CALL_READ_BLOCK); 4831da177e4SLinus Torvalds if (ret < 0) 4841da177e4SLinus Torvalds goto read_failed; 4851da177e4SLinus Torvalds 4861da177e4SLinus Torvalds desc->actual = ntohl(bp[0]); 4871da177e4SLinus Torvalds if (desc->actual != desc->size) { 4881da177e4SLinus Torvalds ret = -EBADMSG; 4891da177e4SLinus Torvalds goto abort; 4901da177e4SLinus Torvalds } 4911da177e4SLinus Torvalds 4921da177e4SLinus Torvalds /* call the app to read the actual data */ 4931da177e4SLinus Torvalds rxrpc_call_reset_scratch(call); 4941da177e4SLinus Torvalds 4951da177e4SLinus Torvalds ret = rxrpc_call_read_data(call, desc->buffer, desc->actual, 4961da177e4SLinus Torvalds RXRPC_CALL_READ_BLOCK); 4971da177e4SLinus Torvalds if (ret < 0) 4981da177e4SLinus Torvalds goto read_failed; 4991da177e4SLinus Torvalds 5001da177e4SLinus Torvalds /* wait for the rest of the reply to completely arrive */ 5011da177e4SLinus Torvalds rxrpc_call_reset_scratch(call); 5021da177e4SLinus Torvalds bp = rxrpc_call_alloc_scratch(call, 120); 5031da177e4SLinus Torvalds 5041da177e4SLinus Torvalds ret = rxrpc_call_read_data(call, bp, 120, 5051da177e4SLinus Torvalds RXRPC_CALL_READ_BLOCK | 5061da177e4SLinus Torvalds RXRPC_CALL_READ_ALL); 5071da177e4SLinus Torvalds if (ret < 0) 5081da177e4SLinus Torvalds goto read_failed; 5091da177e4SLinus Torvalds 5101da177e4SLinus Torvalds /* unmarshall the reply */ 5111da177e4SLinus Torvalds vnode->status.if_version = ntohl(*bp++); 5121da177e4SLinus Torvalds vnode->status.type = ntohl(*bp++); 5131da177e4SLinus Torvalds vnode->status.nlink = ntohl(*bp++); 5141da177e4SLinus Torvalds vnode->status.size = ntohl(*bp++); 5151da177e4SLinus Torvalds vnode->status.version = ntohl(*bp++); 5161da177e4SLinus Torvalds vnode->status.author = ntohl(*bp++); 5171da177e4SLinus Torvalds vnode->status.owner = ntohl(*bp++); 5181da177e4SLinus Torvalds vnode->status.caller_access = ntohl(*bp++); 5191da177e4SLinus Torvalds vnode->status.anon_access = ntohl(*bp++); 5201da177e4SLinus Torvalds vnode->status.mode = ntohl(*bp++); 5211da177e4SLinus Torvalds vnode->status.parent.vid = desc->fid.vid; 5221da177e4SLinus Torvalds vnode->status.parent.vnode = ntohl(*bp++); 5231da177e4SLinus Torvalds vnode->status.parent.unique = ntohl(*bp++); 5241da177e4SLinus Torvalds bp++; /* seg size */ 5251da177e4SLinus Torvalds vnode->status.mtime_client = ntohl(*bp++); 5261da177e4SLinus Torvalds vnode->status.mtime_server = ntohl(*bp++); 5271da177e4SLinus Torvalds bp++; /* group */ 5281da177e4SLinus Torvalds bp++; /* sync counter */ 5291da177e4SLinus Torvalds vnode->status.version |= ((unsigned long long) ntohl(*bp++)) << 32; 5301da177e4SLinus Torvalds bp++; /* spare2 */ 5311da177e4SLinus Torvalds bp++; /* spare3 */ 5321da177e4SLinus Torvalds bp++; /* spare4 */ 5331da177e4SLinus Torvalds 5341da177e4SLinus Torvalds vnode->cb_version = ntohl(*bp++); 5351da177e4SLinus Torvalds vnode->cb_expiry = ntohl(*bp++); 5361da177e4SLinus Torvalds vnode->cb_type = ntohl(*bp++); 5371da177e4SLinus Torvalds 5381da177e4SLinus Torvalds if (volsync) { 5391da177e4SLinus Torvalds volsync->creation = ntohl(*bp++); 5401da177e4SLinus Torvalds bp++; /* spare2 */ 5411da177e4SLinus Torvalds bp++; /* spare3 */ 5421da177e4SLinus Torvalds bp++; /* spare4 */ 5431da177e4SLinus Torvalds bp++; /* spare5 */ 5441da177e4SLinus Torvalds bp++; /* spare6 */ 5451da177e4SLinus Torvalds } 5461da177e4SLinus Torvalds 5471da177e4SLinus Torvalds /* success */ 5481da177e4SLinus Torvalds ret = 0; 5491da177e4SLinus Torvalds 5501da177e4SLinus Torvalds out_unwait: 5511da177e4SLinus Torvalds set_current_state(TASK_RUNNING); 5521da177e4SLinus Torvalds remove_wait_queue(&call->waitq,&myself); 5531da177e4SLinus Torvalds rxrpc_put_call(call); 5541da177e4SLinus Torvalds out_put_conn: 5551da177e4SLinus Torvalds afs_server_release_callslot(server, &callslot); 5561da177e4SLinus Torvalds out: 5571da177e4SLinus Torvalds _leave(" = %d", ret); 5581da177e4SLinus Torvalds return ret; 5591da177e4SLinus Torvalds 5601da177e4SLinus Torvalds read_failed: 5611da177e4SLinus Torvalds if (ret == -ECONNABORTED) { 5621da177e4SLinus Torvalds ret = call->app_errno; 5631da177e4SLinus Torvalds goto out_unwait; 5641da177e4SLinus Torvalds } 5651da177e4SLinus Torvalds 5661da177e4SLinus Torvalds abort: 5671da177e4SLinus Torvalds set_current_state(TASK_UNINTERRUPTIBLE); 5681da177e4SLinus Torvalds rxrpc_call_abort(call, ret); 5691da177e4SLinus Torvalds schedule(); 5701da177e4SLinus Torvalds goto out_unwait; 5711da177e4SLinus Torvalds 5721da177e4SLinus Torvalds } /* end afs_rxfs_fetch_file_data() */ 5731da177e4SLinus Torvalds 5741da177e4SLinus Torvalds /*****************************************************************************/ 5751da177e4SLinus Torvalds /* 5761da177e4SLinus Torvalds * ask the AFS fileserver to discard a callback request on a file 5771da177e4SLinus Torvalds */ 5781da177e4SLinus Torvalds int afs_rxfs_give_up_callback(struct afs_server *server, 5791da177e4SLinus Torvalds struct afs_vnode *vnode) 5801da177e4SLinus Torvalds { 5811da177e4SLinus Torvalds struct afs_server_callslot callslot; 5821da177e4SLinus Torvalds struct rxrpc_call *call; 5831da177e4SLinus Torvalds struct kvec piov[1]; 5841da177e4SLinus Torvalds size_t sent; 5851da177e4SLinus Torvalds int ret; 5861da177e4SLinus Torvalds __be32 *bp; 5871da177e4SLinus Torvalds 5881da177e4SLinus Torvalds DECLARE_WAITQUEUE(myself, current); 5891da177e4SLinus Torvalds 5901da177e4SLinus Torvalds _enter("%p,{%u,%u,%u}", 5911da177e4SLinus Torvalds server, vnode->fid.vid, vnode->fid.vnode, vnode->fid.unique); 5921da177e4SLinus Torvalds 5931da177e4SLinus Torvalds /* get hold of the fileserver connection */ 5941da177e4SLinus Torvalds ret = afs_server_request_callslot(server, &callslot); 5951da177e4SLinus Torvalds if (ret < 0) 5961da177e4SLinus Torvalds goto out; 5971da177e4SLinus Torvalds 5981da177e4SLinus Torvalds /* create a call through that connection */ 5991da177e4SLinus Torvalds ret = rxrpc_create_call(callslot.conn, NULL, NULL, afs_rxfs_aemap, &call); 6001da177e4SLinus Torvalds if (ret < 0) { 6011da177e4SLinus Torvalds printk("kAFS: Unable to create call: %d\n", ret); 6021da177e4SLinus Torvalds goto out_put_conn; 6031da177e4SLinus Torvalds } 6041da177e4SLinus Torvalds call->app_opcode = FSGIVEUPCALLBACKS; 6051da177e4SLinus Torvalds 6061da177e4SLinus Torvalds /* we want to get event notifications from the call */ 6071da177e4SLinus Torvalds add_wait_queue(&call->waitq, &myself); 6081da177e4SLinus Torvalds 6091da177e4SLinus Torvalds /* marshall the parameters */ 6101da177e4SLinus Torvalds bp = rxrpc_call_alloc_scratch(call, (1 + 4 + 4) * 4); 6111da177e4SLinus Torvalds 6121da177e4SLinus Torvalds piov[0].iov_len = (1 + 4 + 4) * 4; 6131da177e4SLinus Torvalds piov[0].iov_base = bp; 6141da177e4SLinus Torvalds 6151da177e4SLinus Torvalds *bp++ = htonl(FSGIVEUPCALLBACKS); 6161da177e4SLinus Torvalds *bp++ = htonl(1); 6171da177e4SLinus Torvalds *bp++ = htonl(vnode->fid.vid); 6181da177e4SLinus Torvalds *bp++ = htonl(vnode->fid.vnode); 6191da177e4SLinus Torvalds *bp++ = htonl(vnode->fid.unique); 6201da177e4SLinus Torvalds *bp++ = htonl(1); 6211da177e4SLinus Torvalds *bp++ = htonl(vnode->cb_version); 6221da177e4SLinus Torvalds *bp++ = htonl(vnode->cb_expiry); 6231da177e4SLinus Torvalds *bp++ = htonl(vnode->cb_type); 6241da177e4SLinus Torvalds 6251da177e4SLinus Torvalds /* send the parameters to the server */ 6261da177e4SLinus Torvalds ret = rxrpc_call_write_data(call, 1, piov, RXRPC_LAST_PACKET, GFP_NOFS, 6271da177e4SLinus Torvalds 0, &sent); 6281da177e4SLinus Torvalds if (ret < 0) 6291da177e4SLinus Torvalds goto abort; 6301da177e4SLinus Torvalds 6311da177e4SLinus Torvalds /* wait for the reply to completely arrive */ 6321da177e4SLinus Torvalds for (;;) { 6331da177e4SLinus Torvalds set_current_state(TASK_INTERRUPTIBLE); 6341da177e4SLinus Torvalds if (call->app_call_state != RXRPC_CSTATE_CLNT_RCV_REPLY || 6351da177e4SLinus Torvalds signal_pending(current)) 6361da177e4SLinus Torvalds break; 6371da177e4SLinus Torvalds schedule(); 6381da177e4SLinus Torvalds } 6391da177e4SLinus Torvalds set_current_state(TASK_RUNNING); 6401da177e4SLinus Torvalds 6411da177e4SLinus Torvalds ret = -EINTR; 6421da177e4SLinus Torvalds if (signal_pending(current)) 6431da177e4SLinus Torvalds goto abort; 6441da177e4SLinus Torvalds 6451da177e4SLinus Torvalds switch (call->app_call_state) { 6461da177e4SLinus Torvalds case RXRPC_CSTATE_ERROR: 6471da177e4SLinus Torvalds ret = call->app_errno; 6481da177e4SLinus Torvalds goto out_unwait; 6491da177e4SLinus Torvalds 6501da177e4SLinus Torvalds case RXRPC_CSTATE_CLNT_GOT_REPLY: 6511da177e4SLinus Torvalds ret = 0; 6521da177e4SLinus Torvalds goto out_unwait; 6531da177e4SLinus Torvalds 6541da177e4SLinus Torvalds default: 6551da177e4SLinus Torvalds BUG(); 6561da177e4SLinus Torvalds } 6571da177e4SLinus Torvalds 6581da177e4SLinus Torvalds out_unwait: 6591da177e4SLinus Torvalds set_current_state(TASK_RUNNING); 6601da177e4SLinus Torvalds remove_wait_queue(&call->waitq, &myself); 6611da177e4SLinus Torvalds rxrpc_put_call(call); 6621da177e4SLinus Torvalds out_put_conn: 6631da177e4SLinus Torvalds afs_server_release_callslot(server, &callslot); 6641da177e4SLinus Torvalds out: 6651da177e4SLinus Torvalds _leave(""); 6661da177e4SLinus Torvalds return ret; 6671da177e4SLinus Torvalds 6681da177e4SLinus Torvalds abort: 6691da177e4SLinus Torvalds set_current_state(TASK_UNINTERRUPTIBLE); 6701da177e4SLinus Torvalds rxrpc_call_abort(call, ret); 6711da177e4SLinus Torvalds schedule(); 6721da177e4SLinus Torvalds goto out_unwait; 6731da177e4SLinus Torvalds } /* end afs_rxfs_give_up_callback() */ 6741da177e4SLinus Torvalds 6751da177e4SLinus Torvalds /*****************************************************************************/ 6761da177e4SLinus Torvalds /* 6771da177e4SLinus Torvalds * look a filename up in a directory 6781da177e4SLinus Torvalds * - this operation doesn't seem to work correctly in OpenAFS server 1.2.2 6791da177e4SLinus Torvalds */ 6801da177e4SLinus Torvalds #if 0 6811da177e4SLinus Torvalds int afs_rxfs_lookup(struct afs_server *server, 6821da177e4SLinus Torvalds struct afs_vnode *dir, 6831da177e4SLinus Torvalds const char *filename, 6841da177e4SLinus Torvalds struct afs_vnode *vnode, 6851da177e4SLinus Torvalds struct afs_volsync *volsync) 6861da177e4SLinus Torvalds { 6871da177e4SLinus Torvalds struct rxrpc_connection *conn; 6881da177e4SLinus Torvalds struct rxrpc_call *call; 6891da177e4SLinus Torvalds struct kvec piov[3]; 6901da177e4SLinus Torvalds size_t sent; 6911da177e4SLinus Torvalds int ret; 6921da177e4SLinus Torvalds u32 *bp, zero; 6931da177e4SLinus Torvalds 6941da177e4SLinus Torvalds DECLARE_WAITQUEUE(myself, current); 6951da177e4SLinus Torvalds 6961da177e4SLinus Torvalds kenter("%p,{%u,%u,%u},%s", 6971da177e4SLinus Torvalds server, fid->vid, fid->vnode, fid->unique, filename); 6981da177e4SLinus Torvalds 6991da177e4SLinus Torvalds /* get hold of the fileserver connection */ 7001da177e4SLinus Torvalds ret = afs_server_get_fsconn(server, &conn); 7011da177e4SLinus Torvalds if (ret < 0) 7021da177e4SLinus Torvalds goto out; 7031da177e4SLinus Torvalds 7041da177e4SLinus Torvalds /* create a call through that connection */ 7051da177e4SLinus Torvalds ret = rxrpc_create_call(conn, NULL, NULL, afs_rxfs_aemap, &call); 7061da177e4SLinus Torvalds if (ret < 0) { 7071da177e4SLinus Torvalds printk("kAFS: Unable to create call: %d\n", ret); 7081da177e4SLinus Torvalds goto out_put_conn; 7091da177e4SLinus Torvalds } 7101da177e4SLinus Torvalds call->app_opcode = FSLOOKUP; 7111da177e4SLinus Torvalds 7121da177e4SLinus Torvalds /* we want to get event notifications from the call */ 7131da177e4SLinus Torvalds add_wait_queue(&call->waitq,&myself); 7141da177e4SLinus Torvalds 7151da177e4SLinus Torvalds /* marshall the parameters */ 7161da177e4SLinus Torvalds bp = rxrpc_call_alloc_scratch(call, 20); 7171da177e4SLinus Torvalds 7181da177e4SLinus Torvalds zero = 0; 7191da177e4SLinus Torvalds 7201da177e4SLinus Torvalds piov[0].iov_len = 20; 7211da177e4SLinus Torvalds piov[0].iov_base = bp; 7221da177e4SLinus Torvalds piov[1].iov_len = strlen(filename); 7231da177e4SLinus Torvalds piov[1].iov_base = (char *) filename; 7241da177e4SLinus Torvalds piov[2].iov_len = (4 - (piov[1].iov_len & 3)) & 3; 7251da177e4SLinus Torvalds piov[2].iov_base = &zero; 7261da177e4SLinus Torvalds 7271da177e4SLinus Torvalds *bp++ = htonl(FSLOOKUP); 7281da177e4SLinus Torvalds *bp++ = htonl(dirfid->vid); 7291da177e4SLinus Torvalds *bp++ = htonl(dirfid->vnode); 7301da177e4SLinus Torvalds *bp++ = htonl(dirfid->unique); 7311da177e4SLinus Torvalds *bp++ = htonl(piov[1].iov_len); 7321da177e4SLinus Torvalds 7331da177e4SLinus Torvalds /* send the parameters to the server */ 7341da177e4SLinus Torvalds ret = rxrpc_call_write_data(call, 3, piov, RXRPC_LAST_PACKET, GFP_NOFS, 7351da177e4SLinus Torvalds 0, &sent); 7361da177e4SLinus Torvalds if (ret < 0) 7371da177e4SLinus Torvalds goto abort; 7381da177e4SLinus Torvalds 7391da177e4SLinus Torvalds /* wait for the reply to completely arrive */ 7401da177e4SLinus Torvalds bp = rxrpc_call_alloc_scratch(call, 220); 7411da177e4SLinus Torvalds 7421da177e4SLinus Torvalds ret = rxrpc_call_read_data(call, bp, 220, 7431da177e4SLinus Torvalds RXRPC_CALL_READ_BLOCK | 7441da177e4SLinus Torvalds RXRPC_CALL_READ_ALL); 7451da177e4SLinus Torvalds if (ret < 0) { 7461da177e4SLinus Torvalds if (ret == -ECONNABORTED) { 7471da177e4SLinus Torvalds ret = call->app_errno; 7481da177e4SLinus Torvalds goto out_unwait; 7491da177e4SLinus Torvalds } 7501da177e4SLinus Torvalds goto abort; 7511da177e4SLinus Torvalds } 7521da177e4SLinus Torvalds 7531da177e4SLinus Torvalds /* unmarshall the reply */ 7541da177e4SLinus Torvalds fid->vid = ntohl(*bp++); 7551da177e4SLinus Torvalds fid->vnode = ntohl(*bp++); 7561da177e4SLinus Torvalds fid->unique = ntohl(*bp++); 7571da177e4SLinus Torvalds 7581da177e4SLinus Torvalds vnode->status.if_version = ntohl(*bp++); 7591da177e4SLinus Torvalds vnode->status.type = ntohl(*bp++); 7601da177e4SLinus Torvalds vnode->status.nlink = ntohl(*bp++); 7611da177e4SLinus Torvalds vnode->status.size = ntohl(*bp++); 7621da177e4SLinus Torvalds vnode->status.version = ntohl(*bp++); 7631da177e4SLinus Torvalds vnode->status.author = ntohl(*bp++); 7641da177e4SLinus Torvalds vnode->status.owner = ntohl(*bp++); 7651da177e4SLinus Torvalds vnode->status.caller_access = ntohl(*bp++); 7661da177e4SLinus Torvalds vnode->status.anon_access = ntohl(*bp++); 7671da177e4SLinus Torvalds vnode->status.mode = ntohl(*bp++); 7681da177e4SLinus Torvalds vnode->status.parent.vid = dirfid->vid; 7691da177e4SLinus Torvalds vnode->status.parent.vnode = ntohl(*bp++); 7701da177e4SLinus Torvalds vnode->status.parent.unique = ntohl(*bp++); 7711da177e4SLinus Torvalds bp++; /* seg size */ 7721da177e4SLinus Torvalds vnode->status.mtime_client = ntohl(*bp++); 7731da177e4SLinus Torvalds vnode->status.mtime_server = ntohl(*bp++); 7741da177e4SLinus Torvalds bp++; /* group */ 7751da177e4SLinus Torvalds bp++; /* sync counter */ 7761da177e4SLinus Torvalds vnode->status.version |= ((unsigned long long) ntohl(*bp++)) << 32; 7771da177e4SLinus Torvalds bp++; /* spare2 */ 7781da177e4SLinus Torvalds bp++; /* spare3 */ 7791da177e4SLinus Torvalds bp++; /* spare4 */ 7801da177e4SLinus Torvalds 7811da177e4SLinus Torvalds dir->status.if_version = ntohl(*bp++); 7821da177e4SLinus Torvalds dir->status.type = ntohl(*bp++); 7831da177e4SLinus Torvalds dir->status.nlink = ntohl(*bp++); 7841da177e4SLinus Torvalds dir->status.size = ntohl(*bp++); 7851da177e4SLinus Torvalds dir->status.version = ntohl(*bp++); 7861da177e4SLinus Torvalds dir->status.author = ntohl(*bp++); 7871da177e4SLinus Torvalds dir->status.owner = ntohl(*bp++); 7881da177e4SLinus Torvalds dir->status.caller_access = ntohl(*bp++); 7891da177e4SLinus Torvalds dir->status.anon_access = ntohl(*bp++); 7901da177e4SLinus Torvalds dir->status.mode = ntohl(*bp++); 7911da177e4SLinus Torvalds dir->status.parent.vid = dirfid->vid; 7921da177e4SLinus Torvalds dir->status.parent.vnode = ntohl(*bp++); 7931da177e4SLinus Torvalds dir->status.parent.unique = ntohl(*bp++); 7941da177e4SLinus Torvalds bp++; /* seg size */ 7951da177e4SLinus Torvalds dir->status.mtime_client = ntohl(*bp++); 7961da177e4SLinus Torvalds dir->status.mtime_server = ntohl(*bp++); 7971da177e4SLinus Torvalds bp++; /* group */ 7981da177e4SLinus Torvalds bp++; /* sync counter */ 7991da177e4SLinus Torvalds dir->status.version |= ((unsigned long long) ntohl(*bp++)) << 32; 8001da177e4SLinus Torvalds bp++; /* spare2 */ 8011da177e4SLinus Torvalds bp++; /* spare3 */ 8021da177e4SLinus Torvalds bp++; /* spare4 */ 8031da177e4SLinus Torvalds 8041da177e4SLinus Torvalds callback->fid = *fid; 8051da177e4SLinus Torvalds callback->version = ntohl(*bp++); 8061da177e4SLinus Torvalds callback->expiry = ntohl(*bp++); 8071da177e4SLinus Torvalds callback->type = ntohl(*bp++); 8081da177e4SLinus Torvalds 8091da177e4SLinus Torvalds if (volsync) { 8101da177e4SLinus Torvalds volsync->creation = ntohl(*bp++); 8111da177e4SLinus Torvalds bp++; /* spare2 */ 8121da177e4SLinus Torvalds bp++; /* spare3 */ 8131da177e4SLinus Torvalds bp++; /* spare4 */ 8141da177e4SLinus Torvalds bp++; /* spare5 */ 8151da177e4SLinus Torvalds bp++; /* spare6 */ 8161da177e4SLinus Torvalds } 8171da177e4SLinus Torvalds 8181da177e4SLinus Torvalds /* success */ 8191da177e4SLinus Torvalds ret = 0; 8201da177e4SLinus Torvalds 8211da177e4SLinus Torvalds out_unwait: 8221da177e4SLinus Torvalds set_current_state(TASK_RUNNING); 8231da177e4SLinus Torvalds remove_wait_queue(&call->waitq, &myself); 8241da177e4SLinus Torvalds rxrpc_put_call(call); 8251da177e4SLinus Torvalds out_put_conn: 8261da177e4SLinus Torvalds afs_server_release_fsconn(server, conn); 8271da177e4SLinus Torvalds out: 8281da177e4SLinus Torvalds kleave(""); 8291da177e4SLinus Torvalds return ret; 8301da177e4SLinus Torvalds 8311da177e4SLinus Torvalds abort: 8321da177e4SLinus Torvalds set_current_state(TASK_UNINTERRUPTIBLE); 8331da177e4SLinus Torvalds rxrpc_call_abort(call, ret); 8341da177e4SLinus Torvalds schedule(); 8351da177e4SLinus Torvalds goto out_unwait; 8361da177e4SLinus Torvalds } /* end afs_rxfs_lookup() */ 8371da177e4SLinus Torvalds #endif 838