Btrfs: fix possible infinite loop in slow caching
authorJosef Bacik <jbacik@fusionio.com>
Fri, 19 Apr 2013 18:37:26 +0000 (14:37 -0400)
committerJosef Bacik <jbacik@fusionio.com>
Mon, 6 May 2013 19:55:01 +0000 (15:55 -0400)
So I noticed there is an infinite loop in the slow caching code.  If we return 1
when we hit the end of the tree, so we could end up caching the last block group
the slow way and suddenly we're looping forever because we just keep
re-searching and trying again.  Fix this by only doing btrfs_next_leaf() if we
don't need_resched().  Thanks,

Signed-off-by: Josef Bacik <jbacik@fusionio.com>
fs/btrfs/extent-tree.c

index 8464d369e478ec15d43bf7c307f5af85a5f6815f..fa57965f60a33c20670e555bb1dc6b28439143a3 100644 (file)
@@ -419,8 +419,7 @@ again:
                        if (ret)
                                break;
 
-                       if (need_resched() ||
-                           btrfs_next_leaf(extent_root, path)) {
+                       if (need_resched()) {
                                caching_ctl->progress = last;
                                btrfs_release_path(path);
                                up_read(&fs_info->extent_commit_sem);
@@ -428,6 +427,12 @@ again:
                                cond_resched();
                                goto again;
                        }
+
+                       ret = btrfs_next_leaf(extent_root, path);
+                       if (ret < 0)
+                               goto err;
+                       if (ret)
+                               break;
                        leaf = path->nodes[0];
                        nritems = btrfs_header_nritems(leaf);
                        continue;