aboutsummaryrefslogtreecommitdiffstats
path: root/net/sunrpc
diff options
context:
space:
mode:
authorJ. Bruce Fields <bfields@redhat.com>2012-08-09 18:12:28 -0400
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2012-09-14 10:00:38 -0700
commite684493e06addddaf273964dff6fa0f2204953b8 (patch)
treef8e5d4ca1f23a4fa2c40236175a5eccd58deb537 /net/sunrpc
parent830cd761e4a2d5b31326e5669f59170d8b25e5ed (diff)
downloadkernel_samsung_smdk4412-e684493e06addddaf273964dff6fa0f2204953b8.zip
kernel_samsung_smdk4412-e684493e06addddaf273964dff6fa0f2204953b8.tar.gz
kernel_samsung_smdk4412-e684493e06addddaf273964dff6fa0f2204953b8.tar.bz2
svcrpc: fix BUG() in svc_tcp_clear_pages
commit be1e44441a560c43c136a562d49a1c9623c91197 upstream. Examination of svc_tcp_clear_pages shows that it assumes sk_tcplen is consistent with sk_pages[] (in particular, sk_pages[n] can't be NULL if sk_tcplen would lead us to expect n pages of data). svc_tcp_restore_pages zeroes out sk_pages[] while leaving sk_tcplen. This is OK, since both functions are serialized by XPT_BUSY. However, that means the inconsistency must be repaired before dropping XPT_BUSY. Therefore we should be ensuring that svc_tcp_save_pages repairs the problem before exiting svc_tcp_recv_record on error. Symptoms were a BUG() in svc_tcp_clear_pages. Signed-off-by: J. Bruce Fields <bfields@redhat.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'net/sunrpc')
-rw-r--r--net/sunrpc/svcsock.c2
1 files changed, 1 insertions, 1 deletions
diff --git a/net/sunrpc/svcsock.c b/net/sunrpc/svcsock.c
index af04f77..80c6c96 100644
--- a/net/sunrpc/svcsock.c
+++ b/net/sunrpc/svcsock.c
@@ -1122,9 +1122,9 @@ static int svc_tcp_recvfrom(struct svc_rqst *rqstp)
if (len >= 0)
svsk->sk_tcplen += len;
if (len != want) {
+ svc_tcp_save_pages(svsk, rqstp);
if (len < 0 && len != -EAGAIN)
goto err_other;
- svc_tcp_save_pages(svsk, rqstp);
dprintk("svc: incomplete TCP record (%d of %d)\n",
svsk->sk_tcplen, svsk->sk_reclen);
goto err_noclose;