summaryrefslogtreecommitdiff
path: root/qgroup-verify.c
diff options
context:
space:
mode:
authorDavid Sterba <dsterba@suse.com>2016-09-30 18:51:46 +0200
committerDavid Sterba <dsterba@suse.com>2016-10-03 15:07:24 +0200
commitd89205c4a5304572d8b6e67cee25594d4baaedee (patch)
tree6eb2c2f2062685d983d9ca7f9bbdf01da276983c /qgroup-verify.c
parent801f15bdf1598a75f20d1c07d3e0640d37499165 (diff)
btrfs-progs: check: better error handling in find_parent_roots
Fix use-before-sanity-check leading to undefined behaviour and handle errors more gracefully. Reported-by: Lukas Lueg <lukas.lueg@gmail.com> Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=156811 Signed-off-by: David Sterba <dsterba@suse.com>
Diffstat (limited to 'qgroup-verify.c')
-rw-r--r--qgroup-verify.c21
1 files changed, 18 insertions, 3 deletions
diff --git a/qgroup-verify.c b/qgroup-verify.c
index f6df12d5..df0e5474 100644
--- a/qgroup-verify.c
+++ b/qgroup-verify.c
@@ -330,9 +330,18 @@ static int find_parent_roots(struct ulist *roots, u64 parent)
* For each unresolved root, we recurse
*/
ref = find_ref_bytenr(parent);
+ if (!ref) {
+ error("bytenr ref not found for parent %llu",
+ (unsigned long long)parent);
+ return -EIO;
+ }
node = &ref->bytenr_node;
- BUG_ON(ref == NULL);
- BUG_ON(ref->bytenr != parent);
+ if (ref->bytenr != parent) {
+ error("found bytenr ref does not match parent: %llu != %llu",
+ (unsigned long long)ref->bytenr,
+ (unsigned long long)parent);
+ return -EIO;
+ }
{
/*
@@ -341,9 +350,15 @@ static int find_parent_roots(struct ulist *roots, u64 parent)
*/
struct rb_node *prev_node = rb_prev(&ref->bytenr_node);
struct ref *prev;
+
if (prev_node) {
prev = rb_entry(prev_node, struct ref, bytenr_node);
- BUG_ON(prev->bytenr == parent);
+ if (prev->bytenr == parent) {
+ error(
+ "unexpected: prev bytenr same as parent: %llu",
+ (unsigned long long)parent);
+ return -EIO;
+ }
}
}