mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-03 17:51:57 +09:00
SUNRPC: Fix races in xs_nospace()
commit06ea0bfe6eupstream. When a send failure occurs due to the socket being out of buffer space, we call xs_nospace() in order to have the RPC task wait until the socket has drained enough to make it worth while trying again. The current patch fixes a race in which the socket is drained before we get round to setting up the machinery in xs_nospace(), and which is reported to cause hangs. Link: http://lkml.kernel.org/r/20140210170315.33dfc621@notabene.brown Fixes:a9a6b52ee1(SUNRPC: Don't start the retransmission timer...) Reported-by: Neil Brown <neilb@suse.com> Signed-off-by: Trond Myklebust <trond.myklebust@primarydata.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
committed by
Greg Kroah-Hartman
parent
6319b13bb7
commit
830d5bd83a
@@ -502,6 +502,7 @@ static int xs_nospace(struct rpc_task *task)
|
||||
struct rpc_rqst *req = task->tk_rqstp;
|
||||
struct rpc_xprt *xprt = req->rq_xprt;
|
||||
struct sock_xprt *transport = container_of(xprt, struct sock_xprt, xprt);
|
||||
struct sock *sk = transport->inet;
|
||||
int ret = -EAGAIN;
|
||||
|
||||
dprintk("RPC: %5u xmit incomplete (%u left of %u)\n",
|
||||
@@ -519,7 +520,7 @@ static int xs_nospace(struct rpc_task *task)
|
||||
* window size
|
||||
*/
|
||||
set_bit(SOCK_NOSPACE, &transport->sock->flags);
|
||||
transport->inet->sk_write_pending++;
|
||||
sk->sk_write_pending++;
|
||||
/* ...and wait for more buffer space */
|
||||
xprt_wait_for_buffer_space(task, xs_nospace_callback);
|
||||
}
|
||||
@@ -529,6 +530,9 @@ static int xs_nospace(struct rpc_task *task)
|
||||
}
|
||||
|
||||
spin_unlock_bh(&xprt->transport_lock);
|
||||
|
||||
/* Race breaker in case memory is freed before above code is called */
|
||||
sk->sk_write_space(sk);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user