• NeilBrown's avatar
    NFSD: Don't hand out delegations for 30 seconds after recalling them. · 6282cd56
    NeilBrown authored
    If nfsd needs to recall a delegation for some reason it implies that there is
    contention on the file, so further delegations should not be handed out.
    
    The current code fails to do so, and the result is effectively a
    live-lock under some workloads: a client attempting a conflicting
    operation on a read-delegated file receives NFS4ERR_DELAY and retries
    the operation, but by the time it retries the server may already have
    given out another delegation.
    
    We could simply avoid delegations for (say) 30 seconds after any recall, but
    this is probably too heavy handed.
    
    We could keep a list of inodes (or inode numbers or filehandles) for recalled
    delegations, but that requires memory allocation and searching.
    
    The approach taken here is to use a bloom filter to record the filehandles
    which are currently blocked from delegation, and to accept the cost of a few
    false positives.
    
    We have 2 bloom filters, each of which is valid for 30 seconds.   When a
    delegation is recalled the filehandle is added to one filter and will remain
    disabled for between 30 and 60 seconds.
    
    We keep a count of the number of filehandles that have been added, so when
    that count is zero we can bypass all other tests.
    
    The bloom filters have 256 bits and 3 hash functions.  This should allow a
    couple of dozen blocked  filehandles with minimal false positives.  If many
    more filehandles are all blocked at once, behaviour will degrade towards
    rejecting all delegations for between 30 and 60 seconds, then resetting and
    allowing new delegations.
    Signed-off-by: default avatarNeilBrown <neilb@suse.de>
    Signed-off-by: default avatarJ. Bruce Fields <bfields@redhat.com>
    6282cd56
nfs4state.c 140 KB