• NeilBrown's avatar
    net/sunrpc/xprt_sock: fix regression in connection error reporting. · 3ffbc1d6
    NeilBrown authored
    Commit 3d476263 ("tcp: remove poll() flakes when receiving
    RST") in v4.12 changed the order in which ->sk_state_change()
    and ->sk_error_report() are called when a socket is shut
    down - sk_state_change() is now called first.
    
    This causes xs_tcp_state_change() -> xs_sock_mark_closed() ->
    xprt_disconnect_done() to wake all pending tasked with -EAGAIN.
    When the ->sk_error_report() callback arrives, it is too late to
    pass the error on, and it is lost.
    
    As easy way to demonstrate the problem caused is to try to start
    rpc.nfsd while rcpbind isn't running.
    nfsd will attempt a tcp connection to rpcbind.  A ECONNREFUSED
    error is returned, but sunrpc code loses the error and keeps
    retrying.  If it saw the ECONNREFUSED, it would abort.
    
    To fix this, handle the sk->sk_err in the TCP_CLOSE branch of
    xs_tcp_state_change().
    
    Fixes: 3d476263 ("tcp: remove poll() flakes when receiving RST")
    Cc: stable@vger.kernel.org (v4.12)
    Signed-off-by: default avatarNeilBrown <neilb@suse.com>
    Signed-off-by: default avatarAnna Schumaker <Anna.Schumaker@Netapp.com>
    3ffbc1d6
xprtsock.c 86.8 KB