diff options
author | Trond Myklebust <Trond.Myklebust@netapp.com> | 2006-07-27 17:22:50 -0400 |
---|---|---|
committer | Trond Myklebust <Trond.Myklebust@netapp.com> | 2006-08-03 16:56:55 -0400 |
commit | e0ab53deaa91293a7958d63d5a2cf4c5645ad6f0 (patch) | |
tree | 1117ac18e263222ad91f3af90ddcaf65f37b79f6 /net/sunrpc/xprtsock.c | |
parent | f3d43c769d14b7065da7f62ec468b1fcb8cd6e06 (diff) |
RPC: Ensure that we disconnect TCP socket when client requests error out
If we're part way through transmitting a TCP request, and the client
errors, then we need to disconnect and reconnect the TCP socket in order to
avoid confusing the server.
Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
(cherry picked from 031a50c8b9ea82616abd4a4e18021a25848941ce commit)
Diffstat (limited to 'net/sunrpc/xprtsock.c')
-rw-r--r-- | net/sunrpc/xprtsock.c | 29 |
1 files changed, 28 insertions, 1 deletions
diff --git a/net/sunrpc/xprtsock.c b/net/sunrpc/xprtsock.c index ee678ed13b6f..441bd53f5eca 100644 --- a/net/sunrpc/xprtsock.c +++ b/net/sunrpc/xprtsock.c | |||
@@ -414,6 +414,33 @@ static int xs_tcp_send_request(struct rpc_task *task) | |||
414 | } | 414 | } |
415 | 415 | ||
416 | /** | 416 | /** |
417 | * xs_tcp_release_xprt - clean up after a tcp transmission | ||
418 | * @xprt: transport | ||
419 | * @task: rpc task | ||
420 | * | ||
421 | * This cleans up if an error causes us to abort the transmission of a request. | ||
422 | * In this case, the socket may need to be reset in order to avoid confusing | ||
423 | * the server. | ||
424 | */ | ||
425 | static void xs_tcp_release_xprt(struct rpc_xprt *xprt, struct rpc_task *task) | ||
426 | { | ||
427 | struct rpc_rqst *req; | ||
428 | |||
429 | if (task != xprt->snd_task) | ||
430 | return; | ||
431 | if (task == NULL) | ||
432 | goto out_release; | ||
433 | req = task->tk_rqstp; | ||
434 | if (req->rq_bytes_sent == 0) | ||
435 | goto out_release; | ||
436 | if (req->rq_bytes_sent == req->rq_snd_buf.len) | ||
437 | goto out_release; | ||
438 | set_bit(XPRT_CLOSE_WAIT, &task->tk_xprt->state); | ||
439 | out_release: | ||
440 | xprt_release_xprt(xprt, task); | ||
441 | } | ||
442 | |||
443 | /** | ||
417 | * xs_close - close a socket | 444 | * xs_close - close a socket |
418 | * @xprt: transport | 445 | * @xprt: transport |
419 | * | 446 | * |
@@ -1250,7 +1277,7 @@ static struct rpc_xprt_ops xs_udp_ops = { | |||
1250 | 1277 | ||
1251 | static struct rpc_xprt_ops xs_tcp_ops = { | 1278 | static struct rpc_xprt_ops xs_tcp_ops = { |
1252 | .reserve_xprt = xprt_reserve_xprt, | 1279 | .reserve_xprt = xprt_reserve_xprt, |
1253 | .release_xprt = xprt_release_xprt, | 1280 | .release_xprt = xs_tcp_release_xprt, |
1254 | .set_port = xs_set_port, | 1281 | .set_port = xs_set_port, |
1255 | .connect = xs_connect, | 1282 | .connect = xs_connect, |
1256 | .buf_alloc = rpc_malloc, | 1283 | .buf_alloc = rpc_malloc, |