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/btrfs | |
| 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/btrfs')
| -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 a589912fdd5..fe4fe709c31 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 4d12aa532c5..ab707c0930d 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; |
