diff options
author | Chris Mason <chris.mason@oracle.com> | 2008-01-24 16:13:14 -0500 |
---|---|---|
committer | Chris Mason <chris.mason@oracle.com> | 2008-09-25 11:03:59 -0400 |
commit | bea495e5b4d9746f26cf5b4100d24c77c3dcbd84 (patch) | |
tree | 1293831c063b7c261dcfb2d2611421400eb2bff3 /fs/btrfs/extent-tree.c | |
parent | d1310b2e0cd98eb1348553e69b73827b436dca7b (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.c | 41 |
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 | ||
1858 | static void noinline reada_walk_down(struct btrfs_root *root, | 1858 | static 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); |