diff options
author | Yan Zheng <zheng.yan@oracle.com> | 2009-01-21 10:49:16 -0500 |
---|---|---|
committer | Chris Mason <chris.mason@oracle.com> | 2009-01-21 10:49:16 -0500 |
commit | 5a7be515b1f4569aac601170fc681741434cca92 (patch) | |
tree | 3c22153ede08ed26b4bf9349347d17b52c6d8d09 | |
parent | 3dfdb9348ada18c74c39b9ae7b115e0594792281 (diff) |
Btrfs: Fix infinite loop in btrfs_extent_post_op
btrfs_extent_post_op calls finish_current_insert and del_pending_extents. They
both may enter infinite loops.
finish_current_insert enters infinite loop if it only finds some backrefs to
update. The fix is to check for pending backref updates before restarting the
loop.
The infinite loop in del_pending_extents is due to a the skipped variable
not being properly reset before looping around.
Signed-off-by: Yan Zheng <zheng.yan@oracle.com>
-rw-r--r-- | fs/btrfs/extent-tree.c | 4 |
1 files changed, 3 insertions, 1 deletions
diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c index 3bed6a7e4b22..aeaec84ebed8 100644 --- a/fs/btrfs/extent-tree.c +++ b/fs/btrfs/extent-tree.c | |||
@@ -2156,7 +2156,8 @@ again: | |||
2156 | ret = find_first_extent_bit(&info->extent_ins, search, &start, | 2156 | ret = find_first_extent_bit(&info->extent_ins, search, &start, |
2157 | &end, EXTENT_WRITEBACK); | 2157 | &end, EXTENT_WRITEBACK); |
2158 | if (ret) { | 2158 | if (ret) { |
2159 | if (skipped && all && !num_inserts) { | 2159 | if (skipped && all && !num_inserts && |
2160 | list_empty(&update_list)) { | ||
2160 | skipped = 0; | 2161 | skipped = 0; |
2161 | search = 0; | 2162 | search = 0; |
2162 | continue; | 2163 | continue; |
@@ -2544,6 +2545,7 @@ again: | |||
2544 | if (ret) { | 2545 | if (ret) { |
2545 | if (all && skipped && !nr) { | 2546 | if (all && skipped && !nr) { |
2546 | search = 0; | 2547 | search = 0; |
2548 | skipped = 0; | ||
2547 | continue; | 2549 | continue; |
2548 | } | 2550 | } |
2549 | mutex_unlock(&info->extent_ins_mutex); | 2551 | mutex_unlock(&info->extent_ins_mutex); |