1 // SPDX-License-Identifier: GPL-2.0-or-later 2 /* Call state changing functions. 3 * 4 * Copyright (C) 2022 Red Hat, Inc. All Rights Reserved. 5 * Written by David Howells (dhowells@redhat.com) 6 */ 7 8 #include "ar-internal.h" 9 10 /* 11 * Transition a call to the complete state. 12 */ 13 bool rxrpc_set_call_completion(struct rxrpc_call *call, 14 enum rxrpc_call_completion compl, 15 u32 abort_code, 16 int error) 17 { 18 if (__rxrpc_call_state(call) == RXRPC_CALL_COMPLETE) 19 return false; 20 21 call->abort_code = abort_code; 22 call->error = error; 23 call->completion = compl; 24 /* Allow reader of completion state to operate locklessly */ 25 rxrpc_set_call_state(call, RXRPC_CALL_COMPLETE); 26 trace_rxrpc_call_complete(call); 27 wake_up(&call->waitq); 28 rxrpc_notify_socket(call); 29 return true; 30 } 31 32 /* 33 * Record that a call successfully completed. 34 */ 35 bool rxrpc_call_completed(struct rxrpc_call *call) 36 { 37 return rxrpc_set_call_completion(call, RXRPC_CALL_SUCCEEDED, 0, 0); 38 } 39 40 /* 41 * Record that a call is locally aborted. 42 */ 43 bool rxrpc_abort_call(struct rxrpc_call *call, rxrpc_seq_t seq, 44 u32 abort_code, int error, enum rxrpc_abort_reason why) 45 { 46 trace_rxrpc_abort(call->debug_id, why, call->cid, call->call_id, seq, 47 abort_code, error); 48 if (!rxrpc_set_call_completion(call, RXRPC_CALL_LOCALLY_ABORTED, 49 abort_code, error)) 50 return false; 51 if (test_bit(RXRPC_CALL_EXPOSED, &call->flags)) 52 rxrpc_send_abort_packet(call); 53 return true; 54 } 55 56 /* 57 * Record that a call errored out before even getting off the ground, thereby 58 * setting the state to allow it to be destroyed. 59 */ 60 void rxrpc_prefail_call(struct rxrpc_call *call, enum rxrpc_call_completion compl, 61 int error) 62 { 63 call->abort_code = RX_CALL_DEAD; 64 call->error = error; 65 call->completion = compl; 66 call->_state = RXRPC_CALL_COMPLETE; 67 trace_rxrpc_call_complete(call); 68 WARN_ON_ONCE(__test_and_set_bit(RXRPC_CALL_RELEASED, &call->flags)); 69 } 70