diff options
author | Chris Mason <chris.mason@oracle.com> | 2008-04-28 09:02:36 -0400 |
---|---|---|
committer | Chris Mason <chris.mason@oracle.com> | 2008-09-25 11:04:02 -0400 |
commit | 8e7bf94fd5f44fa585e29fbe6a1bfabc04aea7cf (patch) | |
tree | cf7ff2d942c5af49c43a8a7701b32267815c839f /fs | |
parent | 3bf3d9e9c256e1a249a47bb8ceff682e6430aeff (diff) |
Btrfs: Do more optimal file RA during shrinking and defrag
Signed-off-by: Chris Mason <chris.mason@oracle.com>
Diffstat (limited to 'fs')
-rw-r--r-- | fs/btrfs/extent-tree.c | 16 | ||||
-rw-r--r-- | fs/btrfs/inode.c | 15 |
2 files changed, 22 insertions, 9 deletions
diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c index a589912fdd51..fe4fe709c312 100644 --- a/fs/btrfs/extent-tree.c +++ b/fs/btrfs/extent-tree.c | |||
@@ -2263,6 +2263,12 @@ int btrfs_free_block_groups(struct btrfs_fs_info *info) | |||
2263 | return 0; | 2263 | return 0; |
2264 | } | 2264 | } |
2265 | 2265 | ||
2266 | static unsigned long calc_ra(unsigned long start, unsigned long last, | ||
2267 | unsigned long nr) | ||
2268 | { | ||
2269 | return min(last, start + nr - 1); | ||
2270 | } | ||
2271 | |||
2266 | static int noinline relocate_inode_pages(struct inode *inode, u64 start, | 2272 | static int noinline relocate_inode_pages(struct inode *inode, u64 start, |
2267 | u64 len) | 2273 | u64 len) |
2268 | { | 2274 | { |
@@ -2275,6 +2281,8 @@ static int noinline relocate_inode_pages(struct inode *inode, u64 start, | |||
2275 | struct page *page; | 2281 | struct page *page; |
2276 | struct extent_io_tree *io_tree = &BTRFS_I(inode)->io_tree; | 2282 | struct extent_io_tree *io_tree = &BTRFS_I(inode)->io_tree; |
2277 | struct file_ra_state *ra; | 2283 | struct file_ra_state *ra; |
2284 | unsigned long total_read = 0; | ||
2285 | unsigned long ra_pages; | ||
2278 | 2286 | ||
2279 | ra = kzalloc(sizeof(*ra), GFP_NOFS); | 2287 | ra = kzalloc(sizeof(*ra), GFP_NOFS); |
2280 | 2288 | ||
@@ -2282,11 +2290,17 @@ static int noinline relocate_inode_pages(struct inode *inode, u64 start, | |||
2282 | i = start >> PAGE_CACHE_SHIFT; | 2290 | i = start >> PAGE_CACHE_SHIFT; |
2283 | last_index = (start + len - 1) >> PAGE_CACHE_SHIFT; | 2291 | last_index = (start + len - 1) >> PAGE_CACHE_SHIFT; |
2284 | 2292 | ||
2293 | ra_pages = BTRFS_I(inode)->root->fs_info->bdi.ra_pages; | ||
2294 | |||
2285 | file_ra_state_init(ra, inode->i_mapping); | 2295 | file_ra_state_init(ra, inode->i_mapping); |
2286 | btrfs_force_ra(inode->i_mapping, ra, NULL, i, last_index); | ||
2287 | kfree(ra); | 2296 | kfree(ra); |
2288 | 2297 | ||
2289 | for (; i <= last_index; i++) { | 2298 | for (; i <= last_index; i++) { |
2299 | if (total_read % ra_pages == 0) { | ||
2300 | btrfs_force_ra(inode->i_mapping, ra, NULL, i, | ||
2301 | calc_ra(i, last_index, ra_pages)); | ||
2302 | } | ||
2303 | total_read++; | ||
2290 | page = grab_cache_page(inode->i_mapping, i); | 2304 | page = grab_cache_page(inode->i_mapping, i); |
2291 | if (!page) | 2305 | if (!page) |
2292 | goto out_unlock; | 2306 | goto out_unlock; |
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c index 4d12aa532c5b..ab707c0930df 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c | |||
@@ -2814,14 +2814,12 @@ unsigned long btrfs_force_ra(struct address_space *mapping, | |||
2814 | struct file_ra_state *ra, struct file *file, | 2814 | struct file_ra_state *ra, struct file *file, |
2815 | pgoff_t offset, pgoff_t last_index) | 2815 | pgoff_t offset, pgoff_t last_index) |
2816 | { | 2816 | { |
2817 | pgoff_t req_size; | 2817 | pgoff_t req_size = last_index - offset + 1; |
2818 | 2818 | ||
2819 | #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,23) | 2819 | #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,23) |
2820 | req_size = last_index - offset + 1; | ||
2821 | offset = page_cache_readahead(mapping, ra, file, offset, req_size); | 2820 | offset = page_cache_readahead(mapping, ra, file, offset, req_size); |
2822 | return offset; | 2821 | return offset; |
2823 | #else | 2822 | #else |
2824 | req_size = min(last_index - offset + 1, (pgoff_t)128); | ||
2825 | page_cache_sync_readahead(mapping, ra, file, offset, req_size); | 2823 | page_cache_sync_readahead(mapping, ra, file, offset, req_size); |
2826 | return offset + req_size; | 2824 | return offset + req_size; |
2827 | #endif | 2825 | #endif |
@@ -2833,7 +2831,8 @@ int btrfs_defrag_file(struct file *file) { | |||
2833 | struct extent_io_tree *io_tree = &BTRFS_I(inode)->io_tree; | 2831 | struct extent_io_tree *io_tree = &BTRFS_I(inode)->io_tree; |
2834 | struct page *page; | 2832 | struct page *page; |
2835 | unsigned long last_index; | 2833 | unsigned long last_index; |
2836 | unsigned long ra_index = 0; | 2834 | unsigned long ra_pages = root->fs_info->bdi.ra_pages; |
2835 | unsigned long total_read = 0; | ||
2837 | u64 page_start; | 2836 | u64 page_start; |
2838 | u64 page_end; | 2837 | u64 page_end; |
2839 | unsigned long i; | 2838 | unsigned long i; |
@@ -2848,11 +2847,11 @@ int btrfs_defrag_file(struct file *file) { | |||
2848 | mutex_lock(&inode->i_mutex); | 2847 | mutex_lock(&inode->i_mutex); |
2849 | last_index = inode->i_size >> PAGE_CACHE_SHIFT; | 2848 | last_index = inode->i_size >> PAGE_CACHE_SHIFT; |
2850 | for (i = 0; i <= last_index; i++) { | 2849 | for (i = 0; i <= last_index; i++) { |
2851 | if (i == ra_index) { | 2850 | if (total_read % ra_pages == 0) { |
2852 | ra_index = btrfs_force_ra(inode->i_mapping, | 2851 | btrfs_force_ra(inode->i_mapping, &file->f_ra, file, i, |
2853 | &file->f_ra, | 2852 | min(last_index, i + ra_pages - 1)); |
2854 | file, ra_index, last_index); | ||
2855 | } | 2853 | } |
2854 | total_read++; | ||
2856 | page = grab_cache_page(inode->i_mapping, i); | 2855 | page = grab_cache_page(inode->i_mapping, i); |
2857 | if (!page) | 2856 | if (!page) |
2858 | goto out_unlock; | 2857 | goto out_unlock; |