diff options
Diffstat (limited to 'net/sunrpc/xprtsock.c')
| -rw-r--r-- | net/sunrpc/xprtsock.c | 63 | 
1 files changed, 22 insertions, 41 deletions
diff --git a/net/sunrpc/xprtsock.c b/net/sunrpc/xprtsock.c index 1d1a70498910..fde2138b81e7 100644 --- a/net/sunrpc/xprtsock.c +++ b/net/sunrpc/xprtsock.c @@ -398,7 +398,6 @@ static int xs_sendpages(struct socket *sock, struct sockaddr *addr, int addrlen,  	if (unlikely(!sock))  		return -ENOTSOCK; -	clear_bit(SOCK_ASYNC_NOSPACE, &sock->flags);  	if (base != 0) {  		addr = NULL;  		addrlen = 0; @@ -442,7 +441,6 @@ static void xs_nospace_callback(struct rpc_task *task)  	struct sock_xprt *transport = container_of(task->tk_rqstp->rq_xprt, struct sock_xprt, xprt);  	transport->inet->sk_write_pending--; -	clear_bit(SOCK_ASYNC_NOSPACE, &transport->sock->flags);  }  /** @@ -467,20 +465,11 @@ static int xs_nospace(struct rpc_task *task)  	/* Don't race with disconnect */  	if (xprt_connected(xprt)) { -		if (test_bit(SOCK_ASYNC_NOSPACE, &transport->sock->flags)) { -			/* -			 * Notify TCP that we're limited by the application -			 * window size -			 */ -			set_bit(SOCK_NOSPACE, &transport->sock->flags); -			sk->sk_write_pending++; -			/* ...and wait for more buffer space */ -			xprt_wait_for_buffer_space(task, xs_nospace_callback); -		} -	} else { -		clear_bit(SOCK_ASYNC_NOSPACE, &transport->sock->flags); +		/* wait for more buffer space */ +		sk->sk_write_pending++; +		xprt_wait_for_buffer_space(task, xs_nospace_callback); +	} else  		ret = -ENOTCONN; -	}  	spin_unlock_bh(&xprt->transport_lock); @@ -616,9 +605,6 @@ process_status:  	case -EAGAIN:  		status = xs_nospace(task);  		break; -	default: -		dprintk("RPC:       sendmsg returned unrecognized error %d\n", -			-status);  	case -ENETUNREACH:  	case -ENOBUFS:  	case -EPIPE: @@ -626,7 +612,10 @@ process_status:  	case -EPERM:  		/* When the server has died, an ICMP port unreachable message  		 * prompts ECONNREFUSED. */ -		clear_bit(SOCK_ASYNC_NOSPACE, &transport->sock->flags); +		break; +	default: +		dprintk("RPC:       sendmsg returned unrecognized error %d\n", +			-status);  	}  	return status; @@ -706,16 +695,16 @@ static int xs_tcp_send_request(struct rpc_task *task)  	case -EAGAIN:  		status = xs_nospace(task);  		break; -	default: -		dprintk("RPC:       sendmsg returned unrecognized error %d\n", -			-status);  	case -ECONNRESET:  	case -ECONNREFUSED:  	case -ENOTCONN:  	case -EADDRINUSE:  	case -ENOBUFS:  	case -EPIPE: -		clear_bit(SOCK_ASYNC_NOSPACE, &transport->sock->flags); +		break; +	default: +		dprintk("RPC:       sendmsg returned unrecognized error %d\n", +			-status);  	}  	return status; @@ -1609,19 +1598,23 @@ static void xs_tcp_state_change(struct sock *sk)  static void xs_write_space(struct sock *sk)  { -	struct socket *sock; +	struct socket_wq *wq;  	struct rpc_xprt *xprt; -	if (unlikely(!(sock = sk->sk_socket))) +	if (!sk->sk_socket)  		return; -	clear_bit(SOCK_NOSPACE, &sock->flags); +	clear_bit(SOCK_NOSPACE, &sk->sk_socket->flags);  	if (unlikely(!(xprt = xprt_from_sock(sk))))  		return; -	if (test_and_clear_bit(SOCK_ASYNC_NOSPACE, &sock->flags) == 0) -		return; +	rcu_read_lock(); +	wq = rcu_dereference(sk->sk_wq); +	if (!wq || test_and_clear_bit(SOCKWQ_ASYNC_NOSPACE, &wq->flags) == 0) +		goto out;  	xprt_write_space(xprt); +out: +	rcu_read_unlock();  }  /** @@ -1907,18 +1900,6 @@ static inline void xs_reclassify_socket(int family, struct socket *sock)  	}  }  #else -static inline void xs_reclassify_socketu(struct socket *sock) -{ -} - -static inline void xs_reclassify_socket4(struct socket *sock) -{ -} - -static inline void xs_reclassify_socket6(struct socket *sock) -{ -} -  static inline void xs_reclassify_socket(int family, struct socket *sock)  {  } @@ -2008,7 +1989,7 @@ static int xs_local_setup_socket(struct sock_xprt *transport)  			"transport socket (%d).\n", -status);  		goto out;  	} -	xs_reclassify_socketu(sock); +	xs_reclassify_socket(AF_LOCAL, sock);  	dprintk("RPC:       worker connecting xprt %p via AF_LOCAL to %s\n",  			xprt, xprt->address_strings[RPC_DISPLAY_ADDR]);  | 
