Skip to content

Commit 5f6a0ce

Browse files
fdmananakdave
authored andcommitted
btrfs: don't ignore inode missing when replaying log tree
During log replay, at add_inode_ref(), we return -ENOENT if our current inode isn't found on the subvolume tree or if a parent directory isn't found. The error comes from btrfs_iget_logging() <- btrfs_iget() <- btrfs_read_locked_inode(). The single caller of add_inode_ref(), replay_one_buffer(), ignores an -ENOENT error because it expects that error to mean only that a parent directory wasn't found and that is ok. Before commit 5f61b96 ("btrfs: fix inode lookup error handling during log replay") we were converting any error when getting a parent directory to -ENOENT and any error when getting the current inode to -EIO, so our caller would fail log replay in case we can't find the current inode. After that commit however in case the current inode is not found we return -ENOENT to the caller and therefore it ignores the critical fact that the current inode was not found in the subvolume tree. Fix this by converting -ENOENT to 0 when we don't find a parent directory, returning -ENOENT when we don't find the current inode and making the caller, replay_one_buffer(), not ignore -ENOENT anymore. Fixes: 5f61b96 ("btrfs: fix inode lookup error handling during log replay") Reviewed-by: Boris Burkov <[email protected]> Signed-off-by: Filipe Manana <[email protected]> Signed-off-by: David Sterba <[email protected]>
1 parent 2210bb4 commit 5f6a0ce

File tree

1 file changed

+12
-2
lines changed

1 file changed

+12
-2
lines changed

fs/btrfs/tree-log.c

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1416,6 +1416,8 @@ static noinline int add_inode_ref(struct btrfs_trans_handle *trans,
14161416
dir = btrfs_iget_logging(parent_objectid, root);
14171417
if (IS_ERR(dir)) {
14181418
ret = PTR_ERR(dir);
1419+
if (ret == -ENOENT)
1420+
ret = 0;
14191421
dir = NULL;
14201422
goto out;
14211423
}
@@ -1440,6 +1442,15 @@ static noinline int add_inode_ref(struct btrfs_trans_handle *trans,
14401442
if (IS_ERR(dir)) {
14411443
ret = PTR_ERR(dir);
14421444
dir = NULL;
1445+
/*
1446+
* A new parent dir may have not been
1447+
* logged and not exist in the subvolume
1448+
* tree, see the comment above before
1449+
* the loop when getting the first
1450+
* parent dir.
1451+
*/
1452+
if (ret == -ENOENT)
1453+
ret = 0;
14431454
goto out;
14441455
}
14451456
}
@@ -2551,9 +2562,8 @@ static int replay_one_buffer(struct btrfs_root *log, struct extent_buffer *eb,
25512562
key.type == BTRFS_INODE_EXTREF_KEY) {
25522563
ret = add_inode_ref(wc->trans, root, log, path,
25532564
eb, i, &key);
2554-
if (ret && ret != -ENOENT)
2565+
if (ret)
25552566
break;
2556-
ret = 0;
25572567
} else if (key.type == BTRFS_EXTENT_DATA_KEY) {
25582568
ret = replay_one_extent(wc->trans, root, path,
25592569
eb, i, &key);

0 commit comments

Comments
 (0)