• Jeff Layton's avatar
    nfsd: bump dl_time when unhashing delegation · d55a166c
    Jeff Layton authored
    There's a potential race between a lease break and DELEGRETURN call.
    
    Suppose a lease break comes in and queues the workqueue job for a
    delegation, but it doesn't run just yet. Then, a DELEGRETURN comes in
    finds the delegation and calls destroy_delegation on it to unhash it and
    put its primary reference.
    
    Next, the workqueue job runs and queues the delegation back onto the
    del_recall_lru list, issues the CB_RECALL and puts the final reference.
    With that, the final reference to the delegation is put, but it's still
    on the LRU list.
    
    When we go to unhash a delegation, it's because we intend to get rid of
    it soon afterward, so we don't want lease breaks to mess with it once
    that occurs. Fix this by bumping the dl_time whenever we unhash a
    delegation, to ensure that lease breaks don't monkey with it.
    
    I believe this is a regression due to commit 02e1215f (nfsd: Avoid
    taking state_lock while holding inode lock in nfsd_break_one_deleg).
    Prior to that, the state_lock was held in the lm_break callback itself,
    and that would have prevented this race.
    
    Cc: Trond Myklebust <trond.myklebust@primarydata.com>
    Signed-off-by: default avatarJeff Layton <jlayton@primarydata.com>
    Signed-off-by: default avatarJ. Bruce Fields <bfields@redhat.com>
    d55a166c
nfs4state.c 147 KB