diff options
Diffstat (limited to 'net/rxrpc/recvmsg.c')
| -rw-r--r-- | net/rxrpc/recvmsg.c | 79 | 
1 files changed, 79 insertions, 0 deletions
diff --git a/net/rxrpc/recvmsg.c b/net/rxrpc/recvmsg.c index 8578c39ec839..2989742a4aa1 100644 --- a/net/rxrpc/recvmsg.c +++ b/net/rxrpc/recvmsg.c @@ -59,6 +59,85 @@ void rxrpc_notify_socket(struct rxrpc_call *call)  }  /* + * Transition a call to the complete state. + */ +bool __rxrpc_set_call_completion(struct rxrpc_call *call, +				 enum rxrpc_call_completion compl, +				 u32 abort_code, +				 int error) +{ +	if (call->state < RXRPC_CALL_COMPLETE) { +		call->abort_code = abort_code; +		call->error = error; +		call->completion = compl, +		call->state = RXRPC_CALL_COMPLETE; +		trace_rxrpc_call_complete(call); +		wake_up(&call->waitq); +		rxrpc_notify_socket(call); +		return true; +	} +	return false; +} + +bool rxrpc_set_call_completion(struct rxrpc_call *call, +			       enum rxrpc_call_completion compl, +			       u32 abort_code, +			       int error) +{ +	bool ret = false; + +	if (call->state < RXRPC_CALL_COMPLETE) { +		write_lock_bh(&call->state_lock); +		ret = __rxrpc_set_call_completion(call, compl, abort_code, error); +		write_unlock_bh(&call->state_lock); +	} +	return ret; +} + +/* + * Record that a call successfully completed. + */ +bool __rxrpc_call_completed(struct rxrpc_call *call) +{ +	return __rxrpc_set_call_completion(call, RXRPC_CALL_SUCCEEDED, 0, 0); +} + +bool rxrpc_call_completed(struct rxrpc_call *call) +{ +	bool ret = false; + +	if (call->state < RXRPC_CALL_COMPLETE) { +		write_lock_bh(&call->state_lock); +		ret = __rxrpc_call_completed(call); +		write_unlock_bh(&call->state_lock); +	} +	return ret; +} + +/* + * Record that a call is locally aborted. + */ +bool __rxrpc_abort_call(const char *why, struct rxrpc_call *call, +			rxrpc_seq_t seq, u32 abort_code, int error) +{ +	trace_rxrpc_abort(call->debug_id, why, call->cid, call->call_id, seq, +			  abort_code, error); +	return __rxrpc_set_call_completion(call, RXRPC_CALL_LOCALLY_ABORTED, +					   abort_code, error); +} + +bool rxrpc_abort_call(const char *why, struct rxrpc_call *call, +		      rxrpc_seq_t seq, u32 abort_code, int error) +{ +	bool ret; + +	write_lock_bh(&call->state_lock); +	ret = __rxrpc_abort_call(why, call, seq, abort_code, error); +	write_unlock_bh(&call->state_lock); +	return ret; +} + +/*   * Pass a call terminating message to userspace.   */  static int rxrpc_recvmsg_term(struct rxrpc_call *call, struct msghdr *msg)  | 
