btrfs: add missing run of delayed items after unlink during log replay

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: 0d836392cadd5 ("Btrfs: fix mount failure after fsync due to hard link recreation")
Fixes: 1f250e929a9c9 ("Btrfs: fix log replay failure after unlink and link combination")
CC: stable@vger.kernel.org # 4.19+
Signed-off-by: Filipe Manana <fdmanana@suse.com>
Signed-off-by: David Sterba <dsterba@suse.com>

authored by Filipe Manana and committed by David Sterba 4751dc99 d4aef1e1

Changed files
+18
fs
btrfs
+18
fs/btrfs/tree-log.c
··· 1362 1362 inode, name, namelen); 1363 1363 kfree(name); 1364 1364 iput(dir); 1365 + /* 1366 + * Whenever we need to check if a name exists or not, we 1367 + * check the subvolume tree. So after an unlink we must 1368 + * run delayed items, so that future checks for a name 1369 + * during log replay see that the name does not exists 1370 + * anymore. 1371 + */ 1372 + if (!ret) 1373 + ret = btrfs_run_delayed_items(trans); 1365 1374 if (ret) 1366 1375 goto out; 1367 1376 goto again; ··· 1623 1614 */ 1624 1615 if (!ret && inode->i_nlink == 0) 1625 1616 inc_nlink(inode); 1617 + /* 1618 + * Whenever we need to check if a name exists or 1619 + * not, we check the subvolume tree. So after an 1620 + * unlink we must run delayed items, so that future 1621 + * checks for a name during log replay see that the 1622 + * name does not exists anymore. 1623 + */ 1624 + if (!ret) 1625 + ret = btrfs_run_delayed_items(trans); 1626 1626 } 1627 1627 if (ret < 0) 1628 1628 goto out;