aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs/extent-tree.c
diff options
context:
space:
mode:
authorChris Mason <chris.mason@oracle.com>2008-01-24 16:13:14 -0500
committerChris Mason <chris.mason@oracle.com>2008-09-25 11:03:59 -0400
commitbea495e5b4d9746f26cf5b4100d24c77c3dcbd84 (patch)
tree1293831c063b7c261dcfb2d2611421400eb2bff3 /fs/btrfs/extent-tree.c
parentd1310b2e0cd98eb1348553e69b73827b436dca7b (diff)
Btrfs: Tune readahead during defrag to avoid reading too much at once
Signed-off-by: Chris Mason <chris.mason@oracle.com>
Diffstat (limited to 'fs/btrfs/extent-tree.c')
-rw-r--r--fs/btrfs/extent-tree.c41
1 files changed, 28 insertions, 13 deletions
diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c
index 1cf125ab7822..c4fe37791d3f 100644
--- a/fs/btrfs/extent-tree.c
+++ b/fs/btrfs/extent-tree.c
@@ -1856,27 +1856,44 @@ static int noinline drop_leaf_ref(struct btrfs_trans_handle *trans,
1856} 1856}
1857 1857
1858static void noinline reada_walk_down(struct btrfs_root *root, 1858static void noinline reada_walk_down(struct btrfs_root *root,
1859 struct extent_buffer *node) 1859 struct extent_buffer *node,
1860 int slot)
1860{ 1861{
1861 int i;
1862 u32 nritems;
1863 u64 bytenr; 1862 u64 bytenr;
1864 int ret; 1863 u64 last = 0;
1864 u32 nritems;
1865 u32 refs; 1865 u32 refs;
1866 int level;
1867 u32 blocksize; 1866 u32 blocksize;
1867 int ret;
1868 int i;
1869 int level;
1870 int skipped = 0;
1868 1871
1869 nritems = btrfs_header_nritems(node); 1872 nritems = btrfs_header_nritems(node);
1870 level = btrfs_header_level(node); 1873 level = btrfs_header_level(node);
1871 for (i = 0; i < nritems; i++) { 1874 if (level)
1875 return;
1876
1877 for (i = slot; i < nritems && skipped < 32; i++) {
1872 bytenr = btrfs_node_blockptr(node, i); 1878 bytenr = btrfs_node_blockptr(node, i);
1873 blocksize = btrfs_level_size(root, level - 1); 1879 if (last && ((bytenr > last && bytenr - last > 32 * 1024) ||
1874 ret = lookup_extent_ref(NULL, root, bytenr, blocksize, &refs); 1880 (last > bytenr && last - bytenr > 32 * 1024))) {
1875 BUG_ON(ret); 1881 skipped++;
1876 if (refs != 1)
1877 continue; 1882 continue;
1883 }
1884 blocksize = btrfs_level_size(root, level - 1);
1885 if (i != slot) {
1886 ret = lookup_extent_ref(NULL, root, bytenr,
1887 blocksize, &refs);
1888 BUG_ON(ret);
1889 if (refs != 1) {
1890 skipped++;
1891 continue;
1892 }
1893 }
1878 mutex_unlock(&root->fs_info->fs_mutex); 1894 mutex_unlock(&root->fs_info->fs_mutex);
1879 ret = readahead_tree_block(root, bytenr, blocksize); 1895 ret = readahead_tree_block(root, bytenr, blocksize);
1896 last = bytenr + blocksize;
1880 cond_resched(); 1897 cond_resched();
1881 mutex_lock(&root->fs_info->fs_mutex); 1898 mutex_lock(&root->fs_info->fs_mutex);
1882 if (ret) 1899 if (ret)
@@ -1919,9 +1936,6 @@ static int noinline walk_down_tree(struct btrfs_trans_handle *trans,
1919 WARN_ON(*level >= BTRFS_MAX_LEVEL); 1936 WARN_ON(*level >= BTRFS_MAX_LEVEL);
1920 cur = path->nodes[*level]; 1937 cur = path->nodes[*level];
1921 1938
1922 if (*level > 0 && path->slots[*level] == 0)
1923 reada_walk_down(root, cur);
1924
1925 if (btrfs_header_level(cur) != *level) 1939 if (btrfs_header_level(cur) != *level)
1926 WARN_ON(1); 1940 WARN_ON(1);
1927 1941
@@ -1951,6 +1965,7 @@ static int noinline walk_down_tree(struct btrfs_trans_handle *trans,
1951 next = btrfs_find_tree_block(root, bytenr, blocksize); 1965 next = btrfs_find_tree_block(root, bytenr, blocksize);
1952 if (!next || !btrfs_buffer_uptodate(next)) { 1966 if (!next || !btrfs_buffer_uptodate(next)) {
1953 free_extent_buffer(next); 1967 free_extent_buffer(next);
1968 reada_walk_down(root, cur, path->slots[*level]);
1954 mutex_unlock(&root->fs_info->fs_mutex); 1969 mutex_unlock(&root->fs_info->fs_mutex);
1955 next = read_tree_block(root, bytenr, blocksize); 1970 next = read_tree_block(root, bytenr, blocksize);
1956 mutex_lock(&root->fs_info->fs_mutex); 1971 mutex_lock(&root->fs_info->fs_mutex);