From 0b9bf3812ad1f0d937584e300826285694f53e2b Mon Sep 17 00:00:00 2001 From: David Howells Date: Thu, 25 Apr 2019 14:26:50 +0100 Subject: afs: Split wait from afs_make_call() Split the call to afs_wait_for_call_to_complete() from afs_make_call() to make it easier to handle asynchronous calls and to make it easier to convert a synchronous call to an asynchronous one in future, for instance when someone tries to interrupt an operation by pressing Ctrl-C. Signed-off-by: David Howells --- fs/afs/rxrpc.c | 33 ++++++++++++++++----------------- 1 file changed, 16 insertions(+), 17 deletions(-) (limited to 'fs/afs/rxrpc.c') diff --git a/fs/afs/rxrpc.c b/fs/afs/rxrpc.c index 15c7e82d80cb..bc5aa590f348 100644 --- a/fs/afs/rxrpc.c +++ b/fs/afs/rxrpc.c @@ -21,7 +21,6 @@ struct workqueue_struct *afs_async_calls; static void afs_wake_up_call_waiter(struct sock *, struct rxrpc_call *, unsigned long); -static long afs_wait_for_call_to_complete(struct afs_call *, struct afs_addr_cursor *); static void afs_wake_up_async_call(struct sock *, struct rxrpc_call *, unsigned long); static void afs_delete_async_call(struct work_struct *); static void afs_process_async_call(struct work_struct *); @@ -361,10 +360,10 @@ static int afs_send_pages(struct afs_call *call, struct msghdr *msg) } /* - * initiate a call + * Initiate a call and synchronously queue up the parameters for dispatch. Any + * error is stored into the call struct, which the caller must check for. */ -long afs_make_call(struct afs_addr_cursor *ac, struct afs_call *call, - gfp_t gfp, bool async) +void afs_make_call(struct afs_addr_cursor *ac, struct afs_call *call, gfp_t gfp) { struct sockaddr_rxrpc *srx = &ac->alist->addrs[ac->index]; struct rxrpc_call *rxcall; @@ -382,7 +381,6 @@ long afs_make_call(struct afs_addr_cursor *ac, struct afs_call *call, call, call->type->name, key_serial(call->key), atomic_read(&call->net->nr_outstanding_calls)); - call->async = async; call->addr_ix = ac->index; call->alist = afs_get_addrlist(ac->alist); @@ -415,7 +413,7 @@ long afs_make_call(struct afs_addr_cursor *ac, struct afs_call *call, rxcall = rxrpc_kernel_begin_call(call->net->socket, srx, call->key, (unsigned long)call, tx_total_len, gfp, - (async ? + (call->async ? afs_wake_up_async_call : afs_wake_up_call_waiter), call->upgrade, @@ -453,13 +451,11 @@ long afs_make_call(struct afs_addr_cursor *ac, struct afs_call *call, /* Note that at this point, we may have received the reply or an abort * - and an asynchronous call may already have completed. + * + * afs_wait_for_call_to_complete(call, ac) + * must be called to synchronously clean up. */ - if (call->async) { - afs_put_call(call); - return -EINPROGRESS; - } - - return afs_wait_for_call_to_complete(call, ac); + return; error_do_abort: if (ret != -ECONNABORTED) { @@ -495,9 +491,7 @@ error_kill_call: ac->error = ret; call->state = AFS_CALL_COMPLETE; - afs_put_call(call); _leave(" = %d", ret); - return ret; } /* @@ -604,10 +598,10 @@ call_complete: } /* - * wait synchronously for a call to complete + * Wait synchronously for a call to complete and clean up the call struct. */ -static long afs_wait_for_call_to_complete(struct afs_call *call, - struct afs_addr_cursor *ac) +long afs_wait_for_call_to_complete(struct afs_call *call, + struct afs_addr_cursor *ac) { signed long rtt2, timeout; long ret; @@ -620,6 +614,10 @@ static long afs_wait_for_call_to_complete(struct afs_call *call, _enter(""); + ret = call->error; + if (ret < 0) + goto out; + rtt = rxrpc_kernel_get_rtt(call->net->socket, call->rxcall); rtt2 = nsecs_to_jiffies64(rtt) * 2; if (rtt2 < 2) @@ -703,6 +701,7 @@ static long afs_wait_for_call_to_complete(struct afs_call *call, break; } +out: _debug("call complete"); afs_put_call(call); _leave(" = %p", (void *)ret); -- cgit v1.2.3