diff options
author | Chris Mason <chris.mason@fusionio.com> | 2013-07-05 13:44:07 -0400 |
---|---|---|
committer | Chris Mason <chris.mason@fusionio.com> | 2013-07-05 13:44:07 -0400 |
commit | 194aa4a1bd6447bb545286d0bcb0b0be8204d79f (patch) | |
tree | c512cb21116a3347a968bbb19b1c0fd76c2f5773 | |
parent | 8b5d89be6d3997f9bbaddb23a4408fcb8b50be8f (diff) | |
download | btrfs-progs-repair.tar.gz |
btrfs-restore: deal with NULL returns from read_node_slotrepair
Signed-off-by: Chris Mason <chris.mason@fusionio.com>
-rw-r--r-- | cmds-restore.c | 10 | ||||
-rw-r--r-- | ctree.c | 3 |
2 files changed, 10 insertions, 3 deletions
diff --git a/cmds-restore.c b/cmds-restore.c index 55a2fab..e48df40 100644 --- a/cmds-restore.c +++ b/cmds-restore.c @@ -152,9 +152,11 @@ int next_leaf(struct btrfs_root *root, struct btrfs_path *path) { int slot; int level = 1; + int offset = 1; struct extent_buffer *c; struct extent_buffer *next = NULL; +again: for (; level < BTRFS_MAX_LEVEL; level++) { if (path->nodes[level]) break; @@ -169,7 +171,7 @@ int next_leaf(struct btrfs_root *root, struct btrfs_path *path) if (!path->nodes[level]) return 1; - slot = path->slots[level] + 1; + slot = path->slots[level] + offset; c = path->nodes[level]; if (slot >= btrfs_header_nritems(c)) { level++; @@ -182,7 +184,9 @@ int next_leaf(struct btrfs_root *root, struct btrfs_path *path) reada_for_search(root, path, level, slot, 0); next = read_node_slot(root, c, slot); - break; + if (next) + break; + offset++; } path->slots[level] = slot; while(1) { @@ -196,6 +200,8 @@ int next_leaf(struct btrfs_root *root, struct btrfs_path *path) if (path->reada) reada_for_search(root, path, level, 0, 0); next = read_node_slot(root, next, 0); + if (!next) + goto again; } return 0; } @@ -797,7 +797,8 @@ struct extent_buffer *read_node_slot(struct btrfs_root *root, if (slot >= btrfs_header_nritems(parent)) return NULL; - BUG_ON(level == 0); + if (level == 0) + return NULL; return read_tree_block(root, btrfs_node_blockptr(parent, slot), btrfs_level_size(root, level - 1), |