• Jeff Layton's avatar
    nfsd: make deny mode enforcement more efficient and close races in it · baeb4ff0
    Jeff Layton authored
    The current enforcement of deny modes is both inefficient and scattered
    across several places, which makes it hard to guarantee atomicity. The
    inefficiency is a problem now, and the lack of atomicity will mean races
    once the client_mutex is removed.
    
    First, we address the inefficiency. We have to track deny modes on a
    per-stateid basis to ensure that open downgrades are sane, but when the
    server goes to enforce them it has to walk the entire list of stateids
    and check against each one.
    
    Instead of doing that, maintain a per-nfs4_file deny mode. When a file
    is opened, we simply set any deny bits in that mode that were specified
    in the OPEN call. We can then use that unified deny mode to do a simple
    check to see whether there are any conflicts without needing to walk the
    entire stateid list.
    
    The only time we'll need to walk the entire list of stateids is when a
    stateid that has a deny mode on it is being released, or one is having
    its deny mode downgraded. In that case, we must walk the entire list and
    recalculate the fi_share_deny field. Since deny modes are pretty rare
    today, this should be very rare under normal workloads.
    
    To address the potential for races once the client_mutex is removed,
    protect fi_share_deny with the fi_lock. In nfs4_get_vfs_file, check to
    make sure that any deny mode we want to apply won't conflict with
    existing access. If that's ok, then have nfs4_file_get_access check that
    new access to the file won't conflict with existing deny modes.
    
    If that also passes, then get file access references, set the correct
    access and deny bits in the stateid, and update the fi_share_deny field.
    If opening the file or truncating it fails, then unwind the whole mess
    and return the appropriate error.
    Signed-off-by: default avatarJeff Layton <jlayton@primarydata.com>
    Reviewed-by: default avatarChristoph Hellwig <hch@lst.de>
    Signed-off-by: default avatarJ. Bruce Fields <bfields@redhat.com>
    baeb4ff0
state.h 15.7 KB