• Amir Goldstein's avatar
    ovl: lookup in inode cache first when decoding lower file handle · 8b58924a
    Amir Goldstein authored
    When decoding a lower file handle, we need to check if lower file was
    copied up and indexed and if it has a whiteout index, we need to check
    if this is an unlinked but open non-dir before returning -ESTALE.
    
    To find out if this is an unlinked but open non-dir we need to lookup
    an overlay inode in inode cache by lower inode and that requires decoding
    the lower file handle before looking in inode cache.
    
    Before this change, if the lower inode turned out to be a directory, we
    may have paid an expensive cost to reconnect that lower directory for
    nothing.
    
    After this change, we start by decoding a disconnected lower dentry and
    using the lower inode for looking up an overlay inode in inode cache.
    If we find overlay inode and dentry in cache, we avoid the index lookup
    overhead. If we don't find an overlay inode and dentry in cache, then we
    only need to decode a connected lower dentry in case the lower dentry is
    a non-indexed directory.
    
    The xfstests group overlay/exportfs tests decoding overlayfs file
    handles after drop_caches with different states of the file at encode
    and decode time. Overall the tests in the group call ovl_lower_fh_to_d()
    89 times to decode a lower file handle.
    
    Before this change, the tests called ovl_get_index_fh() 75 times and
    reconnect_one() 61 times.
    After this change, the tests call ovl_get_index_fh() 70 times and
    reconnect_one() 59 times. The 2 cases where reconnect_one() was avoided
    are cases where a non-upper directory file handle was encoded, then the
    directory removed and then file handle was decoded.
    
    To demonstrate the affect on decoding file handles with hot inode/dentry
    cache, the drop_caches call in the tests was disabled. Without
    drop_caches, there are no reconnect_one() calls at all before or after
    the change. Before the change, there are 75 calls to ovl_get_index_fh(),
    exactly as the case with drop_caches. After the change, there are only
    10 calls to ovl_get_index_fh().
    Signed-off-by: default avatarAmir Goldstein <amir73il@gmail.com>
    Signed-off-by: default avatarMiklos Szeredi <mszeredi@redhat.com>
    8b58924a
export.c 21.9 KB