diff options
author | Jeff Mahoney <jeffm@suse.com> | 2011-10-03 23:22:33 -0400 |
---|---|---|
committer | David Sterba <dsterba@suse.cz> | 2012-03-21 20:45:30 -0400 |
commit | 43c04fb1b8c9f45d971bb53d7cbbcda8ee85716b (patch) | |
tree | 18a5a3d5958348f7dbc6c5ca267aab982f02f13d /fs/btrfs/relocation.c | |
parent | c2d904e086b6f707b73bf065e4d18ded4b86ae9e (diff) |
btrfs: Panic on bad rbtree operations
The ordered data and relocation trees have BUG_ONs to protect against
bad tree operations.
This patch replaces them with a panic that will report the problem.
Signed-off-by: Jeff Mahoney <jeffm@suse.com>
Diffstat (limited to 'fs/btrfs/relocation.c')
-rw-r--r-- | fs/btrfs/relocation.c | 36 |
1 files changed, 29 insertions, 7 deletions
diff --git a/fs/btrfs/relocation.c b/fs/btrfs/relocation.c index 8c1aae2c845d..e5996ff8aaa4 100644 --- a/fs/btrfs/relocation.c +++ b/fs/btrfs/relocation.c | |||
@@ -326,6 +326,19 @@ static struct rb_node *tree_search(struct rb_root *root, u64 bytenr) | |||
326 | return NULL; | 326 | return NULL; |
327 | } | 327 | } |
328 | 328 | ||
329 | void backref_tree_panic(struct rb_node *rb_node, int errno, | ||
330 | u64 bytenr) | ||
331 | { | ||
332 | |||
333 | struct btrfs_fs_info *fs_info = NULL; | ||
334 | struct backref_node *bnode = rb_entry(rb_node, struct backref_node, | ||
335 | rb_node); | ||
336 | if (bnode->root) | ||
337 | fs_info = bnode->root->fs_info; | ||
338 | btrfs_panic(fs_info, errno, "Inconsistency in backref cache " | ||
339 | "found at offset %llu\n", (unsigned long long)bytenr); | ||
340 | } | ||
341 | |||
329 | /* | 342 | /* |
330 | * walk up backref nodes until reach node presents tree root | 343 | * walk up backref nodes until reach node presents tree root |
331 | */ | 344 | */ |
@@ -452,7 +465,8 @@ static void update_backref_node(struct backref_cache *cache, | |||
452 | rb_erase(&node->rb_node, &cache->rb_root); | 465 | rb_erase(&node->rb_node, &cache->rb_root); |
453 | node->bytenr = bytenr; | 466 | node->bytenr = bytenr; |
454 | rb_node = tree_insert(&cache->rb_root, node->bytenr, &node->rb_node); | 467 | rb_node = tree_insert(&cache->rb_root, node->bytenr, &node->rb_node); |
455 | BUG_ON(rb_node); | 468 | if (rb_node) |
469 | backref_tree_panic(rb_node, -EEXIST, bytenr); | ||
456 | } | 470 | } |
457 | 471 | ||
458 | /* | 472 | /* |
@@ -999,7 +1013,8 @@ next: | |||
999 | if (!cowonly) { | 1013 | if (!cowonly) { |
1000 | rb_node = tree_insert(&cache->rb_root, node->bytenr, | 1014 | rb_node = tree_insert(&cache->rb_root, node->bytenr, |
1001 | &node->rb_node); | 1015 | &node->rb_node); |
1002 | BUG_ON(rb_node); | 1016 | if (rb_node) |
1017 | backref_tree_panic(rb_node, -EEXIST, node->bytenr); | ||
1003 | list_add_tail(&node->lower, &cache->leaves); | 1018 | list_add_tail(&node->lower, &cache->leaves); |
1004 | } | 1019 | } |
1005 | 1020 | ||
@@ -1034,7 +1049,9 @@ next: | |||
1034 | if (!cowonly) { | 1049 | if (!cowonly) { |
1035 | rb_node = tree_insert(&cache->rb_root, upper->bytenr, | 1050 | rb_node = tree_insert(&cache->rb_root, upper->bytenr, |
1036 | &upper->rb_node); | 1051 | &upper->rb_node); |
1037 | BUG_ON(rb_node); | 1052 | if (rb_node) |
1053 | backref_tree_panic(rb_node, -EEXIST, | ||
1054 | upper->bytenr); | ||
1038 | } | 1055 | } |
1039 | 1056 | ||
1040 | list_add_tail(&edge->list[UPPER], &upper->lower); | 1057 | list_add_tail(&edge->list[UPPER], &upper->lower); |
@@ -1180,7 +1197,8 @@ static int clone_backref_node(struct btrfs_trans_handle *trans, | |||
1180 | 1197 | ||
1181 | rb_node = tree_insert(&cache->rb_root, new_node->bytenr, | 1198 | rb_node = tree_insert(&cache->rb_root, new_node->bytenr, |
1182 | &new_node->rb_node); | 1199 | &new_node->rb_node); |
1183 | BUG_ON(rb_node); | 1200 | if (rb_node) |
1201 | backref_tree_panic(rb_node, -EEXIST, new_node->bytenr); | ||
1184 | 1202 | ||
1185 | if (!new_node->lowest) { | 1203 | if (!new_node->lowest) { |
1186 | list_for_each_entry(new_edge, &new_node->lower, list[UPPER]) { | 1204 | list_for_each_entry(new_edge, &new_node->lower, list[UPPER]) { |
@@ -1252,7 +1270,8 @@ static int __update_reloc_root(struct btrfs_root *root, int del) | |||
1252 | rb_node = tree_insert(&rc->reloc_root_tree.rb_root, | 1270 | rb_node = tree_insert(&rc->reloc_root_tree.rb_root, |
1253 | node->bytenr, &node->rb_node); | 1271 | node->bytenr, &node->rb_node); |
1254 | spin_unlock(&rc->reloc_root_tree.lock); | 1272 | spin_unlock(&rc->reloc_root_tree.lock); |
1255 | BUG_ON(rb_node); | 1273 | if (rb_node) |
1274 | backref_tree_panic(rb_node, -EEXIST, node->bytenr); | ||
1256 | } else { | 1275 | } else { |
1257 | list_del_init(&root->root_list); | 1276 | list_del_init(&root->root_list); |
1258 | kfree(node); | 1277 | kfree(node); |
@@ -3154,7 +3173,8 @@ static int add_tree_block(struct reloc_control *rc, | |||
3154 | block->key_ready = 0; | 3173 | block->key_ready = 0; |
3155 | 3174 | ||
3156 | rb_node = tree_insert(blocks, block->bytenr, &block->rb_node); | 3175 | rb_node = tree_insert(blocks, block->bytenr, &block->rb_node); |
3157 | BUG_ON(rb_node); | 3176 | if (rb_node) |
3177 | backref_tree_panic(rb_node, -EEXIST, block->bytenr); | ||
3158 | 3178 | ||
3159 | return 0; | 3179 | return 0; |
3160 | } | 3180 | } |
@@ -3426,7 +3446,9 @@ static int find_data_references(struct reloc_control *rc, | |||
3426 | block->key_ready = 1; | 3446 | block->key_ready = 1; |
3427 | rb_node = tree_insert(blocks, block->bytenr, | 3447 | rb_node = tree_insert(blocks, block->bytenr, |
3428 | &block->rb_node); | 3448 | &block->rb_node); |
3429 | BUG_ON(rb_node); | 3449 | if (rb_node) |
3450 | backref_tree_panic(rb_node, -EEXIST, | ||
3451 | block->bytenr); | ||
3430 | } | 3452 | } |
3431 | if (counted) | 3453 | if (counted) |
3432 | added = 1; | 3454 | added = 1; |