]>
Commit | Line | Data |
---|---|---|
ae9cf8e9 GKH |
1 | From b6c60c8018c4e9beb2f83fc82c09f9d033766571 Mon Sep 17 00:00:00 2001 |
2 | From: Josef Bacik <jbacik@fusionio.com> | |
3 | Date: Tue, 30 Jul 2013 16:30:30 -0400 | |
4 | Subject: Btrfs: change how we queue blocks for backref checking | |
5 | ||
6 | From: Josef Bacik <jbacik@fusionio.com> | |
7 | ||
8 | commit b6c60c8018c4e9beb2f83fc82c09f9d033766571 upstream. | |
9 | ||
10 | Previously we only added blocks to the list to have their backrefs checked if | |
11 | the level of the block is right above the one we are searching for. This is | |
12 | because we want to make sure we don't add the entire path up to the root to the | |
13 | lists to make sure we process things one at a time. This assumes that if any | |
14 | blocks in the path to the root are going to be not checked (shared in other | |
15 | words) then they will be in the level right above the current block on up. This | |
16 | isn't quite right though since we can have blocks higher up the list that are | |
17 | shared because they are attached to a reloc root. But we won't add this block | |
18 | to be checked and then later on we will BUG_ON(!upper->checked). So instead | |
19 | keep track of wether or not we've queued a block to be checked in this current | |
20 | search, and if we haven't go ahead and queue it to be checked. This patch fixed | |
21 | the panic I was seeing where we BUG_ON(!upper->checked). Thanks, | |
22 | ||
23 | Signed-off-by: Josef Bacik <jbacik@fusionio.com> | |
24 | Signed-off-by: Chris Mason <chris.mason@fusionio.com> | |
25 | Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> | |
26 | ||
27 | --- | |
28 | fs/btrfs/relocation.c | 14 +++++++------- | |
29 | 1 file changed, 7 insertions(+), 7 deletions(-) | |
30 | ||
31 | --- a/fs/btrfs/relocation.c | |
32 | +++ b/fs/btrfs/relocation.c | |
33 | @@ -691,6 +691,7 @@ struct backref_node *build_backref_tree( | |
34 | int cowonly; | |
35 | int ret; | |
36 | int err = 0; | |
37 | + bool need_check = true; | |
38 | ||
39 | path1 = btrfs_alloc_path(); | |
40 | path2 = btrfs_alloc_path(); | |
41 | @@ -914,6 +915,7 @@ again: | |
42 | cur->bytenr); | |
43 | ||
44 | lower = cur; | |
45 | + need_check = true; | |
46 | for (; level < BTRFS_MAX_LEVEL; level++) { | |
47 | if (!path2->nodes[level]) { | |
48 | BUG_ON(btrfs_root_bytenr(&root->root_item) != | |
49 | @@ -957,14 +959,12 @@ again: | |
50 | ||
51 | /* | |
52 | * add the block to pending list if we | |
53 | - * need check its backrefs. only block | |
54 | - * at 'cur->level + 1' is added to the | |
55 | - * tail of pending list. this guarantees | |
56 | - * we check backrefs from lower level | |
57 | - * blocks to upper level blocks. | |
58 | + * need check its backrefs, we only do this once | |
59 | + * while walking up a tree as we will catch | |
60 | + * anything else later on. | |
61 | */ | |
62 | - if (!upper->checked && | |
63 | - level == cur->level + 1) { | |
64 | + if (!upper->checked && need_check) { | |
65 | + need_check = false; | |
66 | list_add_tail(&edge->list[UPPER], | |
67 | &list); | |
68 | } else |