summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--cmds-check.c84
1 files changed, 58 insertions, 26 deletions
diff --git a/cmds-check.c b/cmds-check.c
index 59ef6071..a7714371 100644
--- a/cmds-check.c
+++ b/cmds-check.c
@@ -891,7 +891,8 @@ static int is_child_root(struct btrfs_root *root, u64 parent_root_id,
key.offset = child_root_id;
ret = btrfs_search_slot(NULL, root->fs_info->tree_root, &key, &path,
0, 0);
- BUG_ON(ret < 0);
+ if (ret < 0)
+ return ret;
btrfs_release_path(&path);
if (!ret)
return 1;
@@ -901,15 +902,14 @@ static int is_child_root(struct btrfs_root *root, u64 parent_root_id,
key.offset = 0;
ret = btrfs_search_slot(NULL, root->fs_info->tree_root, &key, &path,
0, 0);
- BUG_ON(ret <= 0);
+ if (ret < 0)
+ goto out;
while (1) {
leaf = path.nodes[0];
if (path.slots[0] >= btrfs_header_nritems(leaf)) {
ret = btrfs_next_leaf(root->fs_info->tree_root, &path);
- BUG_ON(ret < 0);
-
- if (ret > 0)
+ if (ret)
break;
leaf = path.nodes[0];
}
@@ -928,8 +928,10 @@ static int is_child_root(struct btrfs_root *root, u64 parent_root_id,
path.slots[0]++;
}
-
+out:
btrfs_release_path(&path);
+ if (ret < 0)
+ return ret;
return has_parent? 0 : -1;
}
@@ -1082,14 +1084,15 @@ static int process_inode_extref(struct extent_buffer *eb,
}
-static u64 count_csum_range(struct btrfs_root *root, u64 start, u64 len)
+static int count_csum_range(struct btrfs_root *root, u64 start,
+ u64 len, u64 *found)
{
struct btrfs_key key;
struct btrfs_path path;
struct extent_buffer *leaf;
- int ret ;
+ int ret;
size_t size;
- u64 found = 0;
+ *found = 0;
u64 csum_end;
u16 csum_size = btrfs_super_csum_size(root->fs_info->super_copy);
@@ -1101,7 +1104,8 @@ static u64 count_csum_range(struct btrfs_root *root, u64 start, u64 len)
ret = btrfs_search_slot(NULL, root->fs_info->csum_root,
&key, &path, 0, 0);
- BUG_ON(ret < 0);
+ if (ret < 0)
+ goto out;
if (ret > 0 && path.slots[0] > 0) {
leaf = path.nodes[0];
btrfs_item_key_to_cpu(leaf, &key, path.slots[0] - 1);
@@ -1114,9 +1118,10 @@ static u64 count_csum_range(struct btrfs_root *root, u64 start, u64 len)
leaf = path.nodes[0];
if (path.slots[0] >= btrfs_header_nritems(leaf)) {
ret = btrfs_next_leaf(root->fs_info->csum_root, &path);
- BUG_ON(ret < 0);
if (ret > 0)
break;
+ else if (ret < 0)
+ goto out;
leaf = path.nodes[0];
}
@@ -1138,13 +1143,16 @@ static u64 count_csum_range(struct btrfs_root *root, u64 start, u64 len)
size = min(csum_end - start, len);
len -= size;
start += size;
- found += size;
+ *found += size;
}
path.slots[0]++;
}
+out:
+ if (ret < 0)
+ return ret;
btrfs_release_path(&path);
- return found;
+ return 0;
}
static int process_file_extent(struct btrfs_root *root,
@@ -1159,6 +1167,7 @@ static int process_file_extent(struct btrfs_root *root,
u64 extent_offset = 0;
u64 mask = root->sectorsize - 1;
int extent_type;
+ int ret;
rec = active_node->current;
BUG_ON(rec->ino != key->objectid || rec->refs > 1);
@@ -1213,7 +1222,9 @@ static int process_file_extent(struct btrfs_root *root,
else
disk_bytenr += extent_offset;
- found = count_csum_range(root, disk_bytenr, num_bytes);
+ ret = count_csum_range(root, disk_bytenr, num_bytes, &found);
+ if (ret < 0)
+ return ret;
if (extent_type == BTRFS_FILE_EXTENT_REG) {
if (found > 0)
rec->found_csum_item = 1;
@@ -1234,7 +1245,6 @@ static int process_one_leaf(struct btrfs_root *root, struct extent_buffer *eb,
u32 nritems;
int i;
int ret = 0;
- int error = 0;
struct cache_tree *inode_cache;
struct shared_node *active_node;
@@ -1284,10 +1294,8 @@ static int process_one_leaf(struct btrfs_root *root, struct extent_buffer *eb,
default:
break;
};
- if (ret != 0)
- error = 1;
}
- return error;
+ return ret;
}
static void reada_walk_down(struct btrfs_root *root,
@@ -1355,6 +1363,8 @@ static int walk_down_tree(struct btrfs_root *root, struct btrfs_path *path,
break;
if (*level == 0) {
ret = process_one_leaf(root, cur, wc);
+ if (ret < 0)
+ err = ret;
break;
}
bytenr = btrfs_node_blockptr(cur, path->slots[*level]);
@@ -1751,6 +1761,7 @@ static int merge_root_recs(struct btrfs_root *root,
struct ptr_node *node;
struct inode_record *rec;
struct inode_backref *backref;
+ int ret = 0;
if (root->root_key.objectid == BTRFS_TREE_RELOC_OBJECTID) {
free_inode_recs_tree(src_cache);
@@ -1766,7 +1777,10 @@ static int merge_root_recs(struct btrfs_root *root,
remove_cache_extent(src_cache, &node->cache);
free(node);
- if (!is_child_root(root, root->objectid, rec->ino))
+ ret = is_child_root(root, root->objectid, rec->ino);
+ if (ret < 0)
+ break;
+ else if (ret == 0)
goto skip;
list_for_each_entry(backref, &rec->backrefs, list) {
@@ -1787,6 +1801,8 @@ static int merge_root_recs(struct btrfs_root *root,
skip:
free_inode_rec(rec);
}
+ if (ret < 0)
+ return ret;
return 0;
}
@@ -1945,6 +1961,7 @@ static int check_fs_root(struct btrfs_root *root,
struct walk_control *wc)
{
int ret = 0;
+ int err = 0;
int wret;
int level;
struct btrfs_path path;
@@ -1982,7 +1999,8 @@ static int check_fs_root(struct btrfs_root *root,
level = root_item->drop_level;
path.lowest_level = level;
wret = btrfs_search_slot(NULL, root, &key, &path, 0, 0);
- BUG_ON(wret < 0);
+ if (wret < 0)
+ goto skip_walking;
btrfs_node_key(path.nodes[level], &found_key,
path.slots[level]);
WARN_ON(memcmp(&found_key, &root_item->drop_progress,
@@ -2002,9 +2020,12 @@ static int check_fs_root(struct btrfs_root *root,
if (wret != 0)
break;
}
+skip_walking:
btrfs_release_path(&path);
- merge_root_recs(root, &root_node.root_cache, root_cache);
+ err = merge_root_recs(root, &root_node.root_cache, root_cache);
+ if (err < 0)
+ ret = err;
if (root_node.current) {
root_node.current->checked = 1;
@@ -2012,7 +2033,9 @@ static int check_fs_root(struct btrfs_root *root,
root_node.current);
}
- ret = check_inode_recs(root, &root_node.inode_cache);
+ err = check_inode_recs(root, &root_node.inode_cache);
+ if (!ret)
+ ret = err;
return ret;
}
@@ -2050,13 +2073,19 @@ static int check_fs_roots(struct btrfs_root *root,
key.objectid = 0;
key.type = BTRFS_ROOT_ITEM_KEY;
ret = btrfs_search_slot(NULL, tree_root, &key, &path, 0, 0);
- BUG_ON(ret < 0);
+ if (ret < 0) {
+ err = 1;
+ goto out;
+ }
while (1) {
leaf = path.nodes[0];
if (path.slots[0] >= btrfs_header_nritems(leaf)) {
ret = btrfs_next_leaf(tree_root, &path);
- if (ret != 0)
+ if (ret) {
+ if (ret < 0)
+ err = 1;
break;
+ }
leaf = path.nodes[0];
}
btrfs_item_key_to_cpu(leaf, &key, path.slots[0]);
@@ -2079,8 +2108,10 @@ static int check_fs_roots(struct btrfs_root *root,
next:
path.slots[0]++;
}
+out:
btrfs_release_path(&path);
-
+ if (err)
+ free_extent_cache_tree(&wc.shared);
if (!cache_tree_empty(&wc.shared))
fprintf(stderr, "warning line %d\n", __LINE__);
@@ -5892,7 +5923,8 @@ again:
btrfs_set_key_type(&key, BTRFS_ROOT_ITEM_KEY);
ret = btrfs_search_slot(NULL, root->fs_info->tree_root,
&key, &path, 0, 0);
- BUG_ON(ret < 0);
+ if (ret < 0)
+ goto out;
while(1) {
leaf = path.nodes[0];
slot = path.slots[0];