aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorYan Zheng <zheng.yan@oracle.com>2009-01-21 10:49:16 -0500
committerChris Mason <chris.mason@oracle.com>2009-01-21 10:49:16 -0500
commit5a7be515b1f4569aac601170fc681741434cca92 (patch)
tree3c22153ede08ed26b4bf9349347d17b52c6d8d09
parent3dfdb9348ada18c74c39b9ae7b115e0594792281 (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.c4
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);