btrfs-progs: check: special case for last item

Since repair functions will search path again, if the last item
was checked, the location where the path points is invalid.

Fix it by saving the last valid key if err contains LAST_ITEM,
and call btrfs_next_item() before return of check_inode_item().

Signed-off-by: Su Yue <suy.fnst@cn.fujitsu.com>
Signed-off-by: David Sterba <dsterba@suse.com>
This commit is contained in:
Su Yue 2017-09-01 10:56:16 +08:00 committed by David Sterba
parent a47604de3e
commit 63edc91441
1 changed files with 11 additions and 0 deletions

View File

@ -5748,6 +5748,7 @@ static int check_inode_item(struct btrfs_root *root, struct btrfs_path *path,
struct extent_buffer *node; struct extent_buffer *node;
struct btrfs_inode_item *ii; struct btrfs_inode_item *ii;
struct btrfs_key key; struct btrfs_key key;
struct btrfs_key last_key;
u64 inode_id; u64 inode_id;
u32 mode; u32 mode;
u64 nlink; u64 nlink;
@ -5787,6 +5788,7 @@ static int check_inode_item(struct btrfs_root *root, struct btrfs_path *path,
nodatasum = btrfs_inode_flags(node, ii) & BTRFS_INODE_NODATASUM; nodatasum = btrfs_inode_flags(node, ii) & BTRFS_INODE_NODATASUM;
while (1) { while (1) {
btrfs_item_key_to_cpu(path->nodes[0], &last_key, path->slots[0]);
ret = btrfs_next_item(root, path); ret = btrfs_next_item(root, path);
if (ret < 0) { if (ret < 0) {
/* out will fill 'err' rusing current statistics */ /* out will fill 'err' rusing current statistics */
@ -5848,6 +5850,13 @@ static int check_inode_item(struct btrfs_root *root, struct btrfs_path *path,
} }
out: out:
if (err & LAST_ITEM) {
btrfs_release_path(path);
ret = btrfs_search_slot(NULL, root, &last_key, path, 0, 0);
if (ret)
return err;
}
/* verify INODE_ITEM nlink/isize/nbytes */ /* verify INODE_ITEM nlink/isize/nbytes */
if (dir) { if (dir) {
if (repair && (err & DIR_COUNT_AGAIN)) { if (repair && (err & DIR_COUNT_AGAIN)) {
@ -5937,6 +5946,8 @@ out:
} }
} }
if (err & LAST_ITEM)
btrfs_next_item(root, path);
return err; return err;
} }