diff options
Diffstat (limited to 'net/sunrpc/svcsock.c')
| -rw-r--r-- | net/sunrpc/svcsock.c | 24 | 
1 files changed, 13 insertions, 11 deletions
diff --git a/net/sunrpc/svcsock.c b/net/sunrpc/svcsock.c index 2e2f007dfc9f..9eb5b6b89077 100644 --- a/net/sunrpc/svcsock.c +++ b/net/sunrpc/svcsock.c @@ -519,6 +519,7 @@ static int svc_udp_recvfrom(struct svc_rqst *rqstp)  	if (serv->sv_stats)  		serv->sv_stats->netudpcnt++; +	svc_xprt_received(rqstp->rq_xprt);  	return len;  out_recv_err: @@ -527,7 +528,7 @@ out_recv_err:  		set_bit(XPT_DATA, &svsk->sk_xprt.xpt_flags);  	}  	trace_svcsock_udp_recv_err(&svsk->sk_xprt, err); -	return 0; +	goto out_clear_busy;  out_cmsg_err:  	net_warn_ratelimited("svc: received unknown control message %d/%d; dropping RPC reply datagram\n",  			     cmh->cmsg_level, cmh->cmsg_type); @@ -536,6 +537,8 @@ out_bh_enable:  	local_bh_enable();  out_free:  	kfree_skb(skb); +out_clear_busy: +	svc_xprt_received(rqstp->rq_xprt);  	return 0;  } @@ -728,10 +731,8 @@ static void svc_tcp_state_change(struct sock *sk)  		rmb();  		svsk->sk_ostate(sk);  		trace_svcsock_tcp_state(&svsk->sk_xprt, svsk->sk_sock); -		if (sk->sk_state != TCP_ESTABLISHED) { -			set_bit(XPT_CLOSE, &svsk->sk_xprt.xpt_flags); -			svc_xprt_enqueue(&svsk->sk_xprt); -		} +		if (sk->sk_state != TCP_ESTABLISHED) +			svc_xprt_deferred_close(&svsk->sk_xprt);  	}  } @@ -901,7 +902,7 @@ err_too_large:  	net_notice_ratelimited("svc: %s %s RPC fragment too large: %d\n",  			       __func__, svsk->sk_xprt.xpt_server->sv_name,  			       svc_sock_reclen(svsk)); -	set_bit(XPT_CLOSE, &svsk->sk_xprt.xpt_flags); +	svc_xprt_deferred_close(&svsk->sk_xprt);  err_short:  	return -EAGAIN;  } @@ -1035,6 +1036,7 @@ static int svc_tcp_recvfrom(struct svc_rqst *rqstp)  	if (serv->sv_stats)  		serv->sv_stats->nettcpcnt++; +	svc_xprt_received(rqstp->rq_xprt);  	return rqstp->rq_arg.len;  err_incomplete: @@ -1052,13 +1054,14 @@ error:  	if (len != -EAGAIN)  		goto err_delete;  	trace_svcsock_tcp_recv_eagain(&svsk->sk_xprt, 0); -	return 0; +	goto err_noclose;  err_nuts:  	svsk->sk_datalen = 0;  err_delete:  	trace_svcsock_tcp_recv_err(&svsk->sk_xprt, len); -	set_bit(XPT_CLOSE, &svsk->sk_xprt.xpt_flags); +	svc_xprt_deferred_close(&svsk->sk_xprt);  err_noclose: +	svc_xprt_received(rqstp->rq_xprt);  	return 0;	/* record not complete */  } @@ -1188,8 +1191,7 @@ out_close:  		  xprt->xpt_server->sv_name,  		  (err < 0) ? "got error" : "sent",  		  (err < 0) ? err : sent, xdr->len); -	set_bit(XPT_CLOSE, &xprt->xpt_flags); -	svc_xprt_enqueue(xprt); +	svc_xprt_deferred_close(xprt);  	atomic_dec(&svsk->sk_sendqlen);  	mutex_unlock(&xprt->xpt_mutex);  	return -EAGAIN; @@ -1268,7 +1270,7 @@ static void svc_tcp_init(struct svc_sock *svsk, struct svc_serv *serv)  		case TCP_ESTABLISHED:  			break;  		default: -			set_bit(XPT_CLOSE, &svsk->sk_xprt.xpt_flags); +			svc_xprt_deferred_close(&svsk->sk_xprt);  		}  	}  }  |