diff options
Diffstat (limited to 'net/rxrpc/recvmsg.c')
| -rw-r--r-- | net/rxrpc/recvmsg.c | 23 | 
1 files changed, 21 insertions, 2 deletions
diff --git a/net/rxrpc/recvmsg.c b/net/rxrpc/recvmsg.c index 86a27fb55a1c..7fa7e77f6bb9 100644 --- a/net/rxrpc/recvmsg.c +++ b/net/rxrpc/recvmsg.c @@ -29,6 +29,10 @@ void rxrpc_notify_socket(struct rxrpc_call *call)  	if (!list_empty(&call->recvmsg_link))  		return; +	if (test_bit(RXRPC_CALL_RELEASED, &call->flags)) { +		rxrpc_see_call(call, rxrpc_call_see_notify_released); +		return; +	}  	rcu_read_lock(); @@ -447,6 +451,16 @@ try_again:  		goto try_again;  	} +	rxrpc_see_call(call, rxrpc_call_see_recvmsg); +	if (test_bit(RXRPC_CALL_RELEASED, &call->flags)) { +		rxrpc_see_call(call, rxrpc_call_see_already_released); +		list_del_init(&call->recvmsg_link); +		spin_unlock_irq(&rx->recvmsg_lock); +		release_sock(&rx->sk); +		trace_rxrpc_recvmsg(call->debug_id, rxrpc_recvmsg_unqueue, 0); +		rxrpc_put_call(call, rxrpc_call_put_recvmsg); +		goto try_again; +	}  	if (!(flags & MSG_PEEK))  		list_del_init(&call->recvmsg_link);  	else @@ -470,8 +484,13 @@ try_again:  	release_sock(&rx->sk); -	if (test_bit(RXRPC_CALL_RELEASED, &call->flags)) -		BUG(); +	if (test_bit(RXRPC_CALL_RELEASED, &call->flags)) { +		rxrpc_see_call(call, rxrpc_call_see_already_released); +		mutex_unlock(&call->user_mutex); +		if (!(flags & MSG_PEEK)) +			rxrpc_put_call(call, rxrpc_call_put_recvmsg); +		goto try_again; +	}  	ret = rxrpc_recvmsg_user_id(call, msg, flags);  	if (ret < 0)  | 
