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 (call->state < RXRPC_CALL_COMPLETE) { 19 call->abort_code = abort_code; 20 call->error = error; 21 call->completion = compl; 22 call->state = RXRPC_CALL_COMPLETE; 23 trace_rxrpc_call_complete(call); 24 wake_up(&call->waitq); 25 rxrpc_notify_socket(call); 26 return true; 27 } 28 return false; 29 } 30 31 bool rxrpc_set_call_completion(struct rxrpc_call *call, 32 enum rxrpc_call_completion compl, 33 u32 abort_code, 34 int error) 35 { 36 bool ret = false; 37 38 if (call->state < RXRPC_CALL_COMPLETE) { 39 write_lock(&call->state_lock); 40 ret = __rxrpc_set_call_completion(call, compl, abort_code, error); 41 write_unlock(&call->state_lock); 42 } 43 return ret; 44 } 45 46 /* 47 * Record that a call successfully completed. 48 */ 49 bool __rxrpc_call_completed(struct rxrpc_call *call) 50 { 51 return __rxrpc_set_call_completion(call, RXRPC_CALL_SUCCEEDED, 0, 0); 52 } 53 54 bool rxrpc_call_completed(struct rxrpc_call *call) 55 { 56 bool ret = false; 57 58 if (call->state < RXRPC_CALL_COMPLETE) { 59 write_lock(&call->state_lock); 60 ret = __rxrpc_call_completed(call); 61 write_unlock(&call->state_lock); 62 } 63 return ret; 64 } 65 66 /* 67 * Record that a call is locally aborted. 68 */ 69 bool __rxrpc_abort_call(struct rxrpc_call *call, rxrpc_seq_t seq, 70 u32 abort_code, int error, enum rxrpc_abort_reason why) 71 { 72 trace_rxrpc_abort(call->debug_id, why, call->cid, call->call_id, seq, 73 abort_code, error); 74 return __rxrpc_set_call_completion(call, RXRPC_CALL_LOCALLY_ABORTED, 75 abort_code, error); 76 } 77 78 bool rxrpc_abort_call(struct rxrpc_call *call, rxrpc_seq_t seq, 79 u32 abort_code, int error, enum rxrpc_abort_reason why) 80 { 81 bool ret; 82 83 write_lock(&call->state_lock); 84 ret = __rxrpc_abort_call(call, seq, abort_code, error, why); 85 write_unlock(&call->state_lock); 86 if (ret && test_bit(RXRPC_CALL_EXPOSED, &call->flags)) 87 rxrpc_send_abort_packet(call); 88 return ret; 89 } 90