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 | |
| parent | d1310b2e0cd98eb1348553e69b73827b436dca7b (diff) | |
Btrfs: Tune readahead during defrag to avoid reading too much at once
Signed-off-by: Chris Mason <chris.mason@oracle.com>
| -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); |
