summaryrefslogtreecommitdiffstats
path: root/net/rxrpc/peer_event.c
diff options
context:
space:
mode:
authorDavid Howells <dhowells@redhat.com>2016-08-30 09:49:28 +0100
committerDavid Howells <dhowells@redhat.com>2016-08-30 15:58:31 +0100
commitf5c17aaeb2aee9b6c30d082bbe652a7e5589adff (patch)
treebc2ec0c32190f3a2de5e1d322d745232ff96771b /net/rxrpc/peer_event.c
parentccbd3dbe85e1445231a7e0da2dada130cedce9d0 (diff)
downloadlinux-f5c17aaeb2aee9b6c30d082bbe652a7e5589adff.tar.gz
linux-f5c17aaeb2aee9b6c30d082bbe652a7e5589adff.tar.bz2
linux-f5c17aaeb2aee9b6c30d082bbe652a7e5589adff.zip
rxrpc: Calls should only have one terminal state
Condense the terminal states of a call state machine to a single state, plus a separate completion type value. The value is then set, along with error and abort code values, only when the call is transitioned to the completion state. Helpers are provided to simplify this. Signed-off-by: David Howells <dhowells@redhat.com>
Diffstat (limited to 'net/rxrpc/peer_event.c')
-rw-r--r--net/rxrpc/peer_event.c24
1 files changed, 16 insertions, 8 deletions
diff --git a/net/rxrpc/peer_event.c b/net/rxrpc/peer_event.c
index 8940674b5e08..865078d76ad3 100644
--- a/net/rxrpc/peer_event.c
+++ b/net/rxrpc/peer_event.c
@@ -248,13 +248,21 @@ void rxrpc_peer_error_distributor(struct work_struct *work)
struct rxrpc_peer *peer =
container_of(work, struct rxrpc_peer, error_distributor);
struct rxrpc_call *call;
- int error_report;
+ enum rxrpc_call_completion compl;
+ bool queue;
+ int error;
_enter("");
- error_report = READ_ONCE(peer->error_report);
+ error = READ_ONCE(peer->error_report);
+ if (error < RXRPC_LOCAL_ERROR_OFFSET) {
+ compl = RXRPC_CALL_NETWORK_ERROR;
+ } else {
+ compl = RXRPC_CALL_LOCAL_ERROR;
+ error -= RXRPC_LOCAL_ERROR_OFFSET;
+ }
- _debug("ISSUE ERROR %d", error_report);
+ _debug("ISSUE ERROR %s %d", rxrpc_call_completions[compl], error);
spin_lock_bh(&peer->lock);
@@ -263,15 +271,15 @@ void rxrpc_peer_error_distributor(struct work_struct *work)
struct rxrpc_call, error_link);
hlist_del_init(&call->error_link);
+ queue = false;
write_lock(&call->state_lock);
- if (call->state != RXRPC_CALL_COMPLETE &&
- call->state < RXRPC_CALL_NETWORK_ERROR) {
- call->error_report = error_report;
- call->state = RXRPC_CALL_NETWORK_ERROR;
+ if (__rxrpc_set_call_completion(call, compl, 0, error)) {
set_bit(RXRPC_CALL_EV_RCVD_ERROR, &call->events);
- rxrpc_queue_call(call);
+ queue = true;
}
write_unlock(&call->state_lock);
+ if (queue)
+ rxrpc_queue_call(call);
}
spin_unlock_bh(&peer->lock);