• Jason Baron's avatar
    rpc: Add -EPERM processing for xs_udp_send_request() · 3dedbb5c
    Jason Baron authored
    If an iptables drop rule is added for an nfs server, the client can end up in
    a softlockup. Because of the way that xs_sendpages() is structured, the -EPERM
    is ignored since the prior bits of the packet may have been successfully queued
    and thus xs_sendpages() returns a non-zero value. Then, xs_udp_send_request()
    thinks that because some bits were queued it should return -EAGAIN. We then try
    the request again and again, resulting in cpu spinning. Reproducer:
    
    1) open a file on the nfs server '/nfs/foo' (mounted using udp)
    2) iptables -A OUTPUT -d <nfs server ip> -j DROP
    3) write to /nfs/foo
    4) close /nfs/foo
    5) iptables -D OUTPUT -d <nfs server ip> -j DROP
    
    The softlockup occurs in step 4 above.
    
    The previous patch, allows xs_sendpages() to return both a sent count and
    any error values that may have occurred. Thus, if we get an -EPERM, return
    that to the higher level code.
    
    With this patch in place we can successfully abort the above sequence and
    avoid the softlockup.
    
    I also tried the above test case on an nfs mount on tcp and although the system
    does not softlockup, I still ended up with the 'hung_task' firing after 120
    seconds, due to the i/o being stuck. The tcp case appears a bit harder to fix,
    since -EPERM appears to get ignored much lower down in the stack and does not
    propogate up to xs_sendpages(). This case is not quite as insidious as the
    softlockup and it is not addressed here.
    Reported-by: default avatarYigong Lou <ylou@akamai.com>
    Signed-off-by: default avatarJason Baron <jbaron@akamai.com>
    Signed-off-by: default avatarTrond Myklebust <trond.myklebust@primarydata.com>
    3dedbb5c
xprtsock.c 82 KB