• Chuck Lever's avatar
    xprtrdma: Do not update {head, tail}.iov_len in rpcrdma_inline_fixup() · cb0ae1fb
    Chuck Lever authored
    While trying NFSv4.0/RDMA with sec=krb5p, I noticed small NFS READ
    operations failed. After the client unwrapped the NFS READ reply
    message, the NFS READ XDR decoder was not able to decode the reply.
    The message was "Server cheating in reply", with the reported
    number of received payload bytes being zero. Applications reported
    a read(2) that returned -1/EIO.
    
    The problem is rpcrdma_inline_fixup() sets the tail.iov_len to zero
    when the incoming reply fits entirely in the head iovec. The zero
    tail.iov_len confused xdr_buf_trim(), which then mangled the actual
    reply data instead of simply removing the trailing GSS checksum.
    
    As near as I can tell, RPC transports are not supposed to update the
    head.iov_len, page_len, or tail.iov_len fields in the receive XDR
    buffer when handling an incoming RPC reply message. These fields
    contain the length of each component of the XDR buffer, and hence
    the maximum number of bytes of reply data that can be stored in each
    XDR buffer component. I've concluded this because:
    
    - This is how xdr_partial_copy_from_skb() appears to behave
    - rpcrdma_inline_fixup() already does not alter page_len
    - call_decode() compares rq_private_buf and rq_rcv_buf and WARNs
       if they are not exactly the same
    
    Unfortunately, as soon as I tried the simple fix to just remove the
    line that sets tail.iov_len to zero, I saw that the logic that
    appends the implicit Write chunk pad inline depends on inline_fixup
    setting tail.iov_len to zero.
    
    To address this, re-organize the tail iovec handling logic to use
    the same approach as with the head iovec: simply point tail.iov_base
    to the correct bytes in the receive buffer.
    
    While I remember all this, write down the conclusion in documenting
    comments.
    Signed-off-by: default avatarChuck Lever <chuck.lever@oracle.com>
    Tested-by: default avatarSteve Wise <swise@opengridcomputing.com>
    Signed-off-by: default avatarAnna Schumaker <Anna.Schumaker@Netapp.com>
    cb0ae1fb
rpc_rdma.c 32.1 KB