lkml.org 
[lkml]   [2016]   [Apr]   [22]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 3.12 67/78] SUNRPC: Fix large reads on NFS/RDMA
    Date
    From: Chuck Lever <chuck.lever@oracle.com>

    3.12-stable review patch. If anyone has any objections, please let me know.

    ===============

    commit 2b7bbc963da8d076f263574af4138b5df2e1581f upstream.

    After commit a11a2bf4, "SUNRPC: Optimise away unnecessary data moves
    in xdr_align_pages", Thu Aug 2 13:21:43 2012, READs larger than a
    few hundred bytes via NFS/RDMA no longer work. This commit exposed
    a long-standing bug in rpcrdma_inline_fixup().

    I reproduce this with an rsize=4096 mount using the cthon04 basic
    tests. Test 5 fails with an EIO error.

    For my reproducer, kernel log shows:

    NFS: server cheating in read reply: count 4096 > recvd 0

    rpcrdma_inline_fixup() is zeroing the xdr_stream::page_len field,
    and xdr_align_pages() is now returning that value to the READ XDR
    decoder function.

    That field is set up by xdr_inline_pages() by the READ XDR encoder
    function. As far as I can tell, it is supposed to be left alone
    after that, as it describes the dimensions of the reply xdr_stream,
    not the contents of that stream.

    Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=68391
    Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
    Signed-off-by: Trond Myklebust <trond.myklebust@primarydata.com>
    Signed-off-by: Jiri Slaby <jslaby@suse.cz>
    ---
    net/sunrpc/xprtrdma/rpc_rdma.c | 4 +---
    1 file changed, 1 insertion(+), 3 deletions(-)

    diff --git a/net/sunrpc/xprtrdma/rpc_rdma.c b/net/sunrpc/xprtrdma/rpc_rdma.c
    index e03725bfe2b8..96ead526b125 100644
    --- a/net/sunrpc/xprtrdma/rpc_rdma.c
    +++ b/net/sunrpc/xprtrdma/rpc_rdma.c
    @@ -649,9 +649,7 @@ rpcrdma_inline_fixup(struct rpc_rqst *rqst, char *srcp, int copy_len, int pad)
    break;
    page_base = 0;
    }
    - rqst->rq_rcv_buf.page_len = olen - copy_len;
    - } else
    - rqst->rq_rcv_buf.page_len = 0;
    + }

    if (copy_len && rqst->rq_rcv_buf.tail[0].iov_len) {
    curlen = copy_len;
    --
    2.8.1
    \
     
     \ /
      Last update: 2016-04-22 13:21    [W:4.282 / U:0.040 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site