• Filipe Manana's avatar
    btrfs: add missing run of delayed items after unlink during log replay · 4751dc99
    Filipe Manana authored
    During log replay, whenever we need to check if a name (dentry) exists in
    a directory we do searches on the subvolume tree for inode references or
    or directory entries (BTRFS_DIR_INDEX_KEY keys, and BTRFS_DIR_ITEM_KEY
    keys as well, before kernel 5.17). However when during log replay we
    unlink a name, through btrfs_unlink_inode(), we may not delete inode
    references and dir index keys from a subvolume tree and instead just add
    the deletions to the delayed inode's delayed items, which will only be
    run when we commit the transaction used for log replay. This means that
    after an unlink operation during log replay, if we attempt to search for
    the same name during log replay, we will not see that the name was already
    deleted, since the deletion is recorded only on the delayed items.
    
    We run delayed items after every unlink operation during log replay,
    except at unlink_old_inode_refs() and at add_inode_ref(). This was due
    to an overlook, as delayed items should be run after evert unlink, for
    the reasons stated above.
    
    So fix those two cases.
    
    Fixes: 0d836392 ("Btrfs: fix mount failure after fsync due to hard link recreation")
    Fixes: 1f250e92 ("Btrfs: fix log replay failure after unlink and link combination")
    CC: stable@vger.kernel.org # 4.19+
    Signed-off-by: default avatarFilipe Manana <fdmanana@suse.com>
    Signed-off-by: default avatarDavid Sterba <dsterba@suse.com>
    4751dc99
tree-log.c 186 KB