diff options
author | David Howells <dhowells@redhat.com> | 2007-04-26 15:55:03 -0700 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2007-04-26 15:55:03 -0700 |
commit | 08e0e7c82eeadec6f4871a386b86bf0f0fbcb4eb (patch) | |
tree | 1c4f7e91e20e56ff2ec755e988a6ee828b1a21c0 /fs/afs/vlclient.c | |
parent | 651350d10f93bed7003c9a66e24cf25e0f8eed3d (diff) | |
download | linux-stable-08e0e7c82eeadec6f4871a386b86bf0f0fbcb4eb.tar.gz linux-stable-08e0e7c82eeadec6f4871a386b86bf0f0fbcb4eb.tar.bz2 linux-stable-08e0e7c82eeadec6f4871a386b86bf0f0fbcb4eb.zip |
[AF_RXRPC]: Make the in-kernel AFS filesystem use AF_RXRPC.
Make the in-kernel AFS filesystem use AF_RXRPC instead of the old RxRPC code.
Signed-off-by: David Howells <dhowells@redhat.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'fs/afs/vlclient.c')
-rw-r--r-- | fs/afs/vlclient.c | 709 |
1 files changed, 119 insertions, 590 deletions
diff --git a/fs/afs/vlclient.c b/fs/afs/vlclient.c index dac9faa70ff4..0c7eba174836 100644 --- a/fs/afs/vlclient.c +++ b/fs/afs/vlclient.c @@ -11,243 +11,76 @@ #include <linux/init.h> #include <linux/sched.h> -#include <rxrpc/rxrpc.h> -#include <rxrpc/transport.h> -#include <rxrpc/connection.h> -#include <rxrpc/call.h> -#include "server.h" -#include "volume.h" -#include "vlclient.h" -#include "kafsasyncd.h" -#include "kafstimod.h" -#include "errors.h" #include "internal.h" -#define VLGETENTRYBYID 503 /* AFS Get Cache Entry By ID operation ID */ -#define VLGETENTRYBYNAME 504 /* AFS Get Cache Entry By Name operation ID */ -#define VLPROBE 514 /* AFS Probe Volume Location Service operation ID */ - -static void afs_rxvl_get_entry_by_id_attn(struct rxrpc_call *call); -static void afs_rxvl_get_entry_by_id_error(struct rxrpc_call *call); - /* - * map afs VL abort codes to/from Linux error codes - * - called with call->lock held + * map volume locator abort codes to error codes */ -static void afs_rxvl_aemap(struct rxrpc_call *call) +static int afs_vl_abort_to_error(u32 abort_code) { - int err; - - _enter("{%u,%u,%d}", - call->app_err_state, call->app_abort_code, call->app_errno); - - switch (call->app_err_state) { - case RXRPC_ESTATE_LOCAL_ABORT: - call->app_abort_code = -call->app_errno; - return; - - case RXRPC_ESTATE_PEER_ABORT: - switch (call->app_abort_code) { - case AFSVL_IDEXIST: err = -EEXIST; break; - case AFSVL_IO: err = -EREMOTEIO; break; - case AFSVL_NAMEEXIST: err = -EEXIST; break; - case AFSVL_CREATEFAIL: err = -EREMOTEIO; break; - case AFSVL_NOENT: err = -ENOMEDIUM; break; - case AFSVL_EMPTY: err = -ENOMEDIUM; break; - case AFSVL_ENTDELETED: err = -ENOMEDIUM; break; - case AFSVL_BADNAME: err = -EINVAL; break; - case AFSVL_BADINDEX: err = -EINVAL; break; - case AFSVL_BADVOLTYPE: err = -EINVAL; break; - case AFSVL_BADSERVER: err = -EINVAL; break; - case AFSVL_BADPARTITION: err = -EINVAL; break; - case AFSVL_REPSFULL: err = -EFBIG; break; - case AFSVL_NOREPSERVER: err = -ENOENT; break; - case AFSVL_DUPREPSERVER: err = -EEXIST; break; - case AFSVL_RWNOTFOUND: err = -ENOENT; break; - case AFSVL_BADREFCOUNT: err = -EINVAL; break; - case AFSVL_SIZEEXCEEDED: err = -EINVAL; break; - case AFSVL_BADENTRY: err = -EINVAL; break; - case AFSVL_BADVOLIDBUMP: err = -EINVAL; break; - case AFSVL_IDALREADYHASHED: err = -EINVAL; break; - case AFSVL_ENTRYLOCKED: err = -EBUSY; break; - case AFSVL_BADVOLOPER: err = -EBADRQC; break; - case AFSVL_BADRELLOCKTYPE: err = -EINVAL; break; - case AFSVL_RERELEASE: err = -EREMOTEIO; break; - case AFSVL_BADSERVERFLAG: err = -EINVAL; break; - case AFSVL_PERM: err = -EACCES; break; - case AFSVL_NOMEM: err = -EREMOTEIO; break; - default: - err = afs_abort_to_error(call->app_abort_code); - break; - } - call->app_errno = err; - return; - + _enter("%u", abort_code); + + switch (abort_code) { + case AFSVL_IDEXIST: return -EEXIST; + case AFSVL_IO: return -EREMOTEIO; + case AFSVL_NAMEEXIST: return -EEXIST; + case AFSVL_CREATEFAIL: return -EREMOTEIO; + case AFSVL_NOENT: return -ENOMEDIUM; + case AFSVL_EMPTY: return -ENOMEDIUM; + case AFSVL_ENTDELETED: return -ENOMEDIUM; + case AFSVL_BADNAME: return -EINVAL; + case AFSVL_BADINDEX: return -EINVAL; + case AFSVL_BADVOLTYPE: return -EINVAL; + case AFSVL_BADSERVER: return -EINVAL; + case AFSVL_BADPARTITION: return -EINVAL; + case AFSVL_REPSFULL: return -EFBIG; + case AFSVL_NOREPSERVER: return -ENOENT; + case AFSVL_DUPREPSERVER: return -EEXIST; + case AFSVL_RWNOTFOUND: return -ENOENT; + case AFSVL_BADREFCOUNT: return -EINVAL; + case AFSVL_SIZEEXCEEDED: return -EINVAL; + case AFSVL_BADENTRY: return -EINVAL; + case AFSVL_BADVOLIDBUMP: return -EINVAL; + case AFSVL_IDALREADYHASHED: return -EINVAL; + case AFSVL_ENTRYLOCKED: return -EBUSY; + case AFSVL_BADVOLOPER: return -EBADRQC; + case AFSVL_BADRELLOCKTYPE: return -EINVAL; + case AFSVL_RERELEASE: return -EREMOTEIO; + case AFSVL_BADSERVERFLAG: return -EINVAL; + case AFSVL_PERM: return -EACCES; + case AFSVL_NOMEM: return -EREMOTEIO; default: - return; + return afs_abort_to_error(abort_code); } } -#if 0 /* - * probe a volume location server to see if it is still alive -- unused + * deliver reply data to a VL.GetEntryByXXX call */ -static int afs_rxvl_probe(struct afs_server *server, int alloc_flags) +static int afs_deliver_vl_get_entry_by_xxx(struct afs_call *call, + struct sk_buff *skb, bool last) { - struct rxrpc_connection *conn; - struct rxrpc_call *call; - struct kvec piov[1]; - size_t sent; - int ret; - __be32 param[1]; - - DECLARE_WAITQUEUE(myself, current); - - /* get hold of the vlserver connection */ - ret = afs_server_get_vlconn(server, &conn); - if (ret < 0) - goto out; - - /* create a call through that connection */ - ret = rxrpc_create_call(conn, NULL, NULL, afs_rxvl_aemap, &call); - if (ret < 0) { - printk("kAFS: Unable to create call: %d\n", ret); - goto out_put_conn; - } - call->app_opcode = VLPROBE; - - /* we want to get event notifications from the call */ - add_wait_queue(&call->waitq, &myself); - - /* marshall the parameters */ - param[0] = htonl(VLPROBE); - piov[0].iov_len = sizeof(param); - piov[0].iov_base = param; - - /* send the parameters to the server */ - ret = rxrpc_call_write_data(call, 1, piov, RXRPC_LAST_PACKET, - alloc_flags, 0, &sent); - if (ret < 0) - goto abort; - - /* wait for the reply to completely arrive */ - for (;;) { - set_current_state(TASK_INTERRUPTIBLE); - if (call->app_call_state != RXRPC_CSTATE_CLNT_RCV_REPLY || - signal_pending(current)) - break; - schedule(); - } - set_current_state(TASK_RUNNING); - - ret = -EINTR; - if (signal_pending(current)) - goto abort; - - switch (call->app_call_state) { - case RXRPC_CSTATE_ERROR: - ret = call->app_errno; - goto out_unwait; - - case RXRPC_CSTATE_CLNT_GOT_REPLY: - ret = 0; - goto out_unwait; - - default: - BUG(); - } + struct afs_cache_vlocation *entry; + __be32 *bp; + u32 tmp; + int loop; -abort: - set_current_state(TASK_UNINTERRUPTIBLE); - rxrpc_call_abort(call, ret); - schedule(); - -out_unwait: - set_current_state(TASK_RUNNING); - remove_wait_queue(&call->waitq, &myself); - rxrpc_put_call(call); -out_put_conn: - rxrpc_put_connection(conn); -out: - return ret; -} -#endif + _enter(",,%u", last); -/* - * look up a volume location database entry by name - */ -int afs_rxvl_get_entry_by_name(struct afs_server *server, - const char *volname, - unsigned volnamesz, - struct afs_cache_vlocation *entry) -{ - DECLARE_WAITQUEUE(myself, current); - - struct rxrpc_connection *conn; - struct rxrpc_call *call; - struct kvec piov[3]; - unsigned tmp; - size_t sent; - int ret, loop; - __be32 *bp, param[2], zero; - - _enter(",%*.*s,%u,", volnamesz, volnamesz, volname, volnamesz); - - memset(entry, 0, sizeof(*entry)); - - /* get hold of the vlserver connection */ - ret = afs_server_get_vlconn(server, &conn); - if (ret < 0) - goto out; - - /* create a call through that connection */ - ret = rxrpc_create_call(conn, NULL, NULL, afs_rxvl_aemap, &call); - if (ret < 0) { - printk("kAFS: Unable to create call: %d\n", ret); - goto out_put_conn; - } - call->app_opcode = VLGETENTRYBYNAME; + afs_transfer_reply(call, skb); + if (!last) + return 0; - /* we want to get event notifications from the call */ - add_wait_queue(&call->waitq, &myself); + if (call->reply_size != call->reply_max) + return -EBADMSG; - /* marshall the parameters */ - piov[1].iov_len = volnamesz; - piov[1].iov_base = (char *) volname; - - zero = 0; - piov[2].iov_len = (4 - (piov[1].iov_len & 3)) & 3; - piov[2].iov_base = &zero; - - param[0] = htonl(VLGETENTRYBYNAME); - param[1] = htonl(piov[1].iov_len); - - piov[0].iov_len = sizeof(param); - piov[0].iov_base = param; - - /* send the parameters to the server */ - ret = rxrpc_call_write_data(call, 3, piov, RXRPC_LAST_PACKET, GFP_NOFS, - 0, &sent); - if (ret < 0) - goto abort; - - /* wait for the reply to completely arrive */ - bp = rxrpc_call_alloc_scratch(call, 384); - - ret = rxrpc_call_read_data(call, bp, 384, - RXRPC_CALL_READ_BLOCK | - RXRPC_CALL_READ_ALL); - if (ret < 0) { - if (ret == -ECONNABORTED) { - ret = call->app_errno; - goto out_unwait; - } - goto abort; - } + /* unmarshall the reply once we've received all of it */ + entry = call->reply; + bp = call->buffer; - /* unmarshall the reply */ for (loop = 0; loop < 64; loop++) entry->name[loop] = ntohl(*bp++); + entry->name[loop] = 0; bp++; /* final NUL */ bp++; /* type */ @@ -260,6 +93,7 @@ int afs_rxvl_get_entry_by_name(struct afs_server *server, for (loop = 0; loop < 8; loop++) { tmp = ntohl(*bp++); + entry->srvtmask[loop] = 0; if (tmp & AFS_VLSF_RWVOL) entry->srvtmask[loop] |= AFS_VOL_VTM_RW; if (tmp & AFS_VLSF_ROVOL) @@ -275,409 +109,104 @@ int afs_rxvl_get_entry_by_name(struct afs_server *server, bp++; /* clone ID */ tmp = ntohl(*bp++); /* flags */ + entry->vidmask = 0; if (tmp & AFS_VLF_RWEXISTS) entry->vidmask |= AFS_VOL_VTM_RW; if (tmp & AFS_VLF_ROEXISTS) entry->vidmask |= AFS_VOL_VTM_RO; if (tmp & AFS_VLF_BACKEXISTS) entry->vidmask |= AFS_VOL_VTM_BAK; - - ret = -ENOMEDIUM; if (!entry->vidmask) - goto abort; - - /* success */ - entry->rtime = get_seconds(); - ret = 0; - -out_unwait: - set_current_state(TASK_RUNNING); - remove_wait_queue(&call->waitq, &myself); - rxrpc_put_call(call); -out_put_conn: - rxrpc_put_connection(conn); -out: - _leave(" = %d", ret); - return ret; - -abort: - set_current_state(TASK_UNINTERRUPTIBLE); - rxrpc_call_abort(call, ret); - schedule(); - goto out_unwait; + return -EBADMSG; + + _leave(" = 0 [done]"); + return 0; } /* - * look up a volume location database entry by ID + * VL.GetEntryByName operation type */ -int afs_rxvl_get_entry_by_id(struct afs_server *server, - afs_volid_t volid, - afs_voltype_t voltype, - struct afs_cache_vlocation *entry) -{ - DECLARE_WAITQUEUE(myself, current); - - struct rxrpc_connection *conn; - struct rxrpc_call *call; - struct kvec piov[1]; - unsigned tmp; - size_t sent; - int ret, loop; - __be32 *bp, param[3]; - - _enter(",%x,%d,", volid, voltype); - - memset(entry, 0, sizeof(*entry)); - - /* get hold of the vlserver connection */ - ret = afs_server_get_vlconn(server, &conn); - if (ret < 0) - goto out; - - /* create a call through that connection */ - ret = rxrpc_create_call(conn, NULL, NULL, afs_rxvl_aemap, &call); - if (ret < 0) { - printk("kAFS: Unable to create call: %d\n", ret); - goto out_put_conn; - } - call->app_opcode = VLGETENTRYBYID; - - /* we want to get event notifications from the call */ - add_wait_queue(&call->waitq, &myself); - - /* marshall the parameters */ - param[0] = htonl(VLGETENTRYBYID); - param[1] = htonl(volid); - param[2] = htonl(voltype); - - piov[0].iov_len = sizeof(param); - piov[0].iov_base = param; - - /* send the parameters to the server */ - ret = rxrpc_call_write_data(call, 1, piov, RXRPC_LAST_PACKET, GFP_NOFS, - 0, &sent); - if (ret < 0) - goto abort; - - /* wait for the reply to completely arrive */ - bp = rxrpc_call_alloc_scratch(call, 384); - - ret = rxrpc_call_read_data(call, bp, 384, - RXRPC_CALL_READ_BLOCK | - RXRPC_CALL_READ_ALL); - if (ret < 0) { - if (ret == -ECONNABORTED) { - ret = call->app_errno; - goto out_unwait; - } - goto abort; - } - - /* unmarshall the reply */ - for (loop = 0; loop < 64; loop++) - entry->name[loop] = ntohl(*bp++); - bp++; /* final NUL */ - - bp++; /* type */ - entry->nservers = ntohl(*bp++); - - for (loop = 0; loop < 8; loop++) - entry->servers[loop].s_addr = *bp++; - - bp += 8; /* partition IDs */ - - for (loop = 0; loop < 8; loop++) { - tmp = ntohl(*bp++); - if (tmp & AFS_VLSF_RWVOL) - entry->srvtmask[loop] |= AFS_VOL_VTM_RW; - if (tmp & AFS_VLSF_ROVOL) - entry->srvtmask[loop] |= AFS_VOL_VTM_RO; - if (tmp & AFS_VLSF_BACKVOL) - entry->srvtmask[loop] |= AFS_VOL_VTM_BAK; - } - - entry->vid[0] = ntohl(*bp++); - entry->vid[1] = ntohl(*bp++); - entry->vid[2] = ntohl(*bp++); - - bp++; /* clone ID */ - - tmp = ntohl(*bp++); /* flags */ - if (tmp & AFS_VLF_RWEXISTS) - entry->vidmask |= AFS_VOL_VTM_RW; - if (tmp & AFS_VLF_ROEXISTS) - entry->vidmask |= AFS_VOL_VTM_RO; - if (tmp & AFS_VLF_BACKEXISTS) - entry->vidmask |= AFS_VOL_VTM_BAK; +static const struct afs_call_type afs_RXVLGetEntryByName = { + .deliver = afs_deliver_vl_get_entry_by_xxx, + .abort_to_error = afs_vl_abort_to_error, + .destructor = afs_flat_call_destructor, +}; - ret = -ENOMEDIUM; - if (!entry->vidmask) - goto abort; - -#if 0 /* TODO: remove */ - entry->nservers = 3; - entry->servers[0].s_addr = htonl(0xac101249); - entry->servers[1].s_addr = htonl(0xac101243); - entry->servers[2].s_addr = htonl(0xac10125b /*0xac10125b*/); - - entry->srvtmask[0] = AFS_VOL_VTM_RO; - entry->srvtmask[1] = AFS_VOL_VTM_RO; - entry->srvtmask[2] = AFS_VOL_VTM_RO | AFS_VOL_VTM_RW; -#endif - - /* success */ - entry->rtime = get_seconds(); - ret = 0; - -out_unwait: - set_current_state(TASK_RUNNING); - remove_wait_queue(&call->waitq, &myself); - rxrpc_put_call(call); -out_put_conn: - rxrpc_put_connection(conn); -out: - _leave(" = %d", ret); - return ret; - -abort: - set_current_state(TASK_UNINTERRUPTIBLE); - rxrpc_call_abort(call, ret); - schedule(); - goto out_unwait; -} +/* + * VL.GetEntryById operation type + */ +static const struct afs_call_type afs_RXVLGetEntryById = { + .deliver = afs_deliver_vl_get_entry_by_xxx, + .abort_to_error = afs_vl_abort_to_error, + .destructor = afs_flat_call_destructor, +}; /* - * look up a volume location database entry by ID asynchronously + * dispatch a get volume entry by name operation */ -int afs_rxvl_get_entry_by_id_async(struct afs_async_op *op, - afs_volid_t volid, - afs_voltype_t voltype) +int afs_vl_get_entry_by_name(struct in_addr *addr, + const char *volname, + struct afs_cache_vlocation *entry, + const struct afs_wait_mode *wait_mode) { - struct rxrpc_connection *conn; - struct rxrpc_call *call; - struct kvec piov[1]; - size_t sent; - int ret; - __be32 param[3]; - - _enter(",%x,%d,", volid, voltype); - - /* get hold of the vlserver connection */ - ret = afs_server_get_vlconn(op->server, &conn); - if (ret < 0) { - _leave(" = %d", ret); - return ret; - } + struct afs_call *call; + size_t volnamesz, reqsz, padsz; + __be32 *bp; - /* create a call through that connection */ - ret = rxrpc_create_call(conn, - afs_rxvl_get_entry_by_id_attn, - afs_rxvl_get_entry_by_id_error, - afs_rxvl_aemap, - &op->call); - rxrpc_put_connection(conn); - - if (ret < 0) { - printk("kAFS: Unable to create call: %d\n", ret); - _leave(" = %d", ret); - return ret; - } + _enter(""); - op->call->app_opcode = VLGETENTRYBYID; - op->call->app_user = op; + volnamesz = strlen(volname); + padsz = (4 - (volnamesz & 3)) & 3; + reqsz = 8 + volnamesz + padsz; - call = op->call; - rxrpc_get_call(call); + call = afs_alloc_flat_call(&afs_RXVLGetEntryByName, reqsz, 384); + if (!call) + return -ENOMEM; - /* send event notifications from the call to kafsasyncd */ - afs_kafsasyncd_begin_op(op); + call->reply = entry; + call->service_id = VL_SERVICE; + call->port = htons(AFS_VL_PORT); /* marshall the parameters */ - param[0] = htonl(VLGETENTRYBYID); - param[1] = htonl(volid); - param[2] = htonl(voltype); - - piov[0].iov_len = sizeof(param); - piov[0].iov_base = param; - - /* allocate result read buffer in scratch space */ - call->app_scr_ptr = rxrpc_call_alloc_scratch(op->call, 384); - - /* send the parameters to the server */ - ret = rxrpc_call_write_data(call, 1, piov, RXRPC_LAST_PACKET, GFP_NOFS, - 0, &sent); - if (ret < 0) { - rxrpc_call_abort(call, ret); /* handle from kafsasyncd */ - ret = 0; - goto out; - } - - /* wait for the reply to completely arrive */ - ret = rxrpc_call_read_data(call, call->app_scr_ptr, 384, 0); - switch (ret) { - case 0: - case -EAGAIN: - case -ECONNABORTED: - ret = 0; - break; /* all handled by kafsasyncd */ - - default: - rxrpc_call_abort(call, ret); /* make kafsasyncd handle it */ - ret = 0; - break; - } - -out: - rxrpc_put_call(call); - _leave(" = %d", ret); - return ret; + bp = call->request; + *bp++ = htonl(VLGETENTRYBYNAME); + *bp++ = htonl(volnamesz); + memcpy(bp, volname, volnamesz); + if (padsz > 0) + memset((void *) bp + volnamesz, 0, padsz); + + /* initiate the call */ + return afs_make_call(addr, call, GFP_KERNEL, wait_mode); } /* - * attend to the asynchronous get VLDB entry by ID + * dispatch a get volume entry by ID operation */ -int afs_rxvl_get_entry_by_id_async2(struct afs_async_op *op, - struct afs_cache_vlocation *entry) +int afs_vl_get_entry_by_id(struct in_addr *addr, + afs_volid_t volid, + afs_voltype_t voltype, + struct afs_cache_vlocation *entry, + const struct afs_wait_mode *wait_mode) { + struct afs_call *call; __be32 *bp; - __u32 tmp; - int loop, ret; - - _enter("{op=%p cst=%u}", op, op->call->app_call_state); - - memset(entry, 0, sizeof(*entry)); - - if (op->call->app_call_state == RXRPC_CSTATE_COMPLETE) { - /* operation finished */ - afs_kafsasyncd_terminate_op(op); - - bp = op->call->app_scr_ptr; - - /* unmarshall the reply */ - for (loop = 0; loop < 64; loop++) - entry->name[loop] = ntohl(*bp++); - bp++; /* final NUL */ - - bp++; /* type */ - entry->nservers = ntohl(*bp++); - - for (loop = 0; loop < 8; loop++) - entry->servers[loop].s_addr = *bp++; - - bp += 8; /* partition IDs */ - - for (loop = 0; loop < 8; loop++) { - tmp = ntohl(*bp++); - if (tmp & AFS_VLSF_RWVOL) - entry->srvtmask[loop] |= AFS_VOL_VTM_RW; - if (tmp & AFS_VLSF_ROVOL) - entry->srvtmask[loop] |= AFS_VOL_VTM_RO; - if (tmp & AFS_VLSF_BACKVOL) - entry->srvtmask[loop] |= AFS_VOL_VTM_BAK; - } - - entry->vid[0] = ntohl(*bp++); - entry->vid[1] = ntohl(*bp++); - entry->vid[2] = ntohl(*bp++); - - bp++; /* clone ID */ - - tmp = ntohl(*bp++); /* flags */ - if (tmp & AFS_VLF_RWEXISTS) - entry->vidmask |= AFS_VOL_VTM_RW; - if (tmp & AFS_VLF_ROEXISTS) - entry->vidmask |= AFS_VOL_VTM_RO; - if (tmp & AFS_VLF_BACKEXISTS) - entry->vidmask |= AFS_VOL_VTM_BAK; - - ret = -ENOMEDIUM; - if (!entry->vidmask) { - rxrpc_call_abort(op->call, ret); - goto done; - } - -#if 0 /* TODO: remove */ - entry->nservers = 3; - entry->servers[0].s_addr = htonl(0xac101249); - entry->servers[1].s_addr = htonl(0xac101243); - entry->servers[2].s_addr = htonl(0xac10125b /*0xac10125b*/); - - entry->srvtmask[0] = AFS_VOL_VTM_RO; - entry->srvtmask[1] = AFS_VOL_VTM_RO; - entry->srvtmask[2] = AFS_VOL_VTM_RO | AFS_VOL_VTM_RW; -#endif - - /* success */ - entry->rtime = get_seconds(); - ret = 0; - goto done; - } - - if (op->call->app_call_state == RXRPC_CSTATE_ERROR) { - /* operation error */ - ret = op->call->app_errno; - goto done; - } - - _leave(" = -EAGAIN"); - return -EAGAIN; - -done: - rxrpc_put_call(op->call); - op->call = NULL; - _leave(" = %d", ret); - return ret; -} - -/* - * handle attention events on an async get-entry-by-ID op - * - called from krxiod - */ -static void afs_rxvl_get_entry_by_id_attn(struct rxrpc_call *call) -{ - struct afs_async_op *op = call->app_user; - - _enter("{op=%p cst=%u}", op, call->app_call_state); - - switch (call->app_call_state) { - case RXRPC_CSTATE_COMPLETE: - afs_kafsasyncd_attend_op(op); - break; - case RXRPC_CSTATE_CLNT_RCV_REPLY: - if (call->app_async_read) - break; - case RXRPC_CSTATE_CLNT_GOT_REPLY: - if (call->app_read_count == 0) - break; - printk("kAFS: Reply bigger than expected" - " {cst=%u asyn=%d mark=%Zu rdy=%Zu pr=%u%s}", - call->app_call_state, - call->app_async_read, - call->app_mark, - call->app_ready_qty, - call->pkt_rcv_count, - call->app_last_rcv ? " last" : ""); - - rxrpc_call_abort(call, -EBADMSG); - break; - default: - BUG(); - } - _leave(""); -} + _enter(""); -/* - * handle error events on an async get-entry-by-ID op - * - called from krxiod - */ -static void afs_rxvl_get_entry_by_id_error(struct rxrpc_call *call) -{ - struct afs_async_op *op = call->app_user; + call = afs_alloc_flat_call(&afs_RXVLGetEntryById, 12, 384); + if (!call) + return -ENOMEM; - _enter("{op=%p cst=%u}", op, call->app_call_state); + call->reply = entry; + call->service_id = VL_SERVICE; + call->port = htons(AFS_VL_PORT); - afs_kafsasyncd_attend_op(op); + /* marshall the parameters */ + bp = call->request; + *bp++ = htonl(VLGETENTRYBYID); + *bp++ = htonl(volid); + *bp = htonl(voltype); - _leave(""); + /* initiate the call */ + return afs_make_call(addr, call, GFP_KERNEL, wait_mode); } |