summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSu Yue <suy.fnst@cn.fujitsu.com>2017-09-01 10:56:16 +0800
committerDavid Sterba <dsterba@suse.com>2017-10-16 20:33:00 +0200
commit63edc9144113a17ebcf4576cdc73348868d7740b (patch)
tree47c7dd548ba538ea405fdcabd769633381ae00da
parenta47604de3ee0ecbf79ce9d3fd271562177777ec8 (diff)
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>
-rw-r--r--cmds-check.c11
1 files changed, 11 insertions, 0 deletions
diff --git a/cmds-check.c b/cmds-check.c
index edc2726c..1d399d7e 100644
--- a/cmds-check.c
+++ b/cmds-check.c
@@ -5748,6 +5748,7 @@ static int check_inode_item(struct btrfs_root *root, struct btrfs_path *path,
struct extent_buffer *node;
struct btrfs_inode_item *ii;
struct btrfs_key key;
+ struct btrfs_key last_key;
u64 inode_id;
u32 mode;
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;
while (1) {
+ btrfs_item_key_to_cpu(path->nodes[0], &last_key, path->slots[0]);
ret = btrfs_next_item(root, path);
if (ret < 0) {
/* 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:
+ 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 */
if (dir) {
if (repair && (err & DIR_COUNT_AGAIN)) {
@@ -5937,6 +5946,8 @@ out:
}
}
+ if (err & LAST_ITEM)
+ btrfs_next_item(root, path);
return err;
}