• Chuck Lever's avatar
    SUNRPC: Revert 241b1f41 ("SUNRPC: Remove xdr_buf_trim()") · 0a8e7b7d
    Chuck Lever authored
    I've noticed that when krb5i or krb5p security is in use,
    retransmitted requests are missing the server's duplicate reply
    cache. The computed checksum on the retransmitted request does not
    match the cached checksum, resulting in the server performing the
    retransmitted request again instead of returning the cached reply.
    
    The assumptions made when removing xdr_buf_trim() were not correct.
    In the send paths, the upper layer has already set the segment
    lengths correctly, and shorting the buffer's content is simply a
    matter of reducing buf->len.
    
    xdr_buf_trim() is the right answer in the receive/unwrap path on
    both the client and the server. The buffer segment lengths have to
    be shortened one-by-one.
    
    On the server side in particular, head.iov_len needs to be updated
    correctly to enable nfsd_cache_csum() to work correctly. The simple
    buf->len computation doesn't do that, and that results in
    checksumming stale data in the buffer.
    
    The problem isn't noticed until there's significant instability of
    the RPC transport. At that point, the reliability of retransmit
    detection on the server becomes crucial.
    
    Fixes: 241b1f41 ("SUNRPC: Remove xdr_buf_trim()")
    Signed-off-by: default avatarChuck Lever <chuck.lever@oracle.com>
    0a8e7b7d
xdr.c 41.5 KB