• Chuck Lever's avatar
    NFS: Fix possible endless state recovery wait · 0625c2dd
    Chuck Lever authored
    In nfs4_wait_clnt_recover(), hold a reference to the clp being
    waited on.  The state manager can reduce clp->cl_count to 1, in
    which case the nfs_put_client() in nfs4_run_state_manager() can
    free *clp before wait_on_bit() returns and allows
    nfs4_wait_clnt_recover() to run again.
    
    The behavior at that point is non-deterministic.  If the waited-on
    bit still happens to be zero, wait_on_bit() will wake the waiter as
    expected.  If the bit is set again (say, if the memory was poisoned
    when freed) wait_on_bit() can leave the waiter asleep.
    
    This is a narrow fix which ensures the safety of accessing *clp in
    nfs4_wait_clnt_recover(), but does not address the continued use
    of a possibly freed *clp after nfs4_wait_clnt_recover() returns
    (see nfs_end_delegation_return(), for example).
    Signed-off-by: default avatarChuck Lever <chuck.lever@oracle.com>
    Signed-off-by: default avatarTrond Myklebust <Trond.Myklebust@netapp.com>
    0625c2dd
nfs4state.c 63.9 KB