diff options
Diffstat (limited to 'fs/btrfs/ioctl.c')
-rw-r--r-- | fs/btrfs/ioctl.c | 21 |
1 files changed, 14 insertions, 7 deletions
diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c index 83f17a5cbd6a..a61f2e7e2db5 100644 --- a/fs/btrfs/ioctl.c +++ b/fs/btrfs/ioctl.c | |||
@@ -213,6 +213,7 @@ int btrfs_defrag_file(struct file *file) | |||
213 | struct inode *inode = fdentry(file)->d_inode; | 213 | struct inode *inode = fdentry(file)->d_inode; |
214 | struct btrfs_root *root = BTRFS_I(inode)->root; | 214 | struct btrfs_root *root = BTRFS_I(inode)->root; |
215 | struct extent_io_tree *io_tree = &BTRFS_I(inode)->io_tree; | 215 | struct extent_io_tree *io_tree = &BTRFS_I(inode)->io_tree; |
216 | struct btrfs_ordered_extent *ordered; | ||
216 | struct page *page; | 217 | struct page *page; |
217 | unsigned long last_index; | 218 | unsigned long last_index; |
218 | unsigned long ra_pages = root->fs_info->bdi.ra_pages; | 219 | unsigned long ra_pages = root->fs_info->bdi.ra_pages; |
@@ -234,6 +235,7 @@ int btrfs_defrag_file(struct file *file) | |||
234 | min(last_index, i + ra_pages - 1)); | 235 | min(last_index, i + ra_pages - 1)); |
235 | } | 236 | } |
236 | total_read++; | 237 | total_read++; |
238 | again: | ||
237 | page = grab_cache_page(inode->i_mapping, i); | 239 | page = grab_cache_page(inode->i_mapping, i); |
238 | if (!page) | 240 | if (!page) |
239 | goto out_unlock; | 241 | goto out_unlock; |
@@ -247,18 +249,23 @@ int btrfs_defrag_file(struct file *file) | |||
247 | } | 249 | } |
248 | } | 250 | } |
249 | 251 | ||
250 | #if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,18) | ||
251 | ClearPageDirty(page); | ||
252 | #else | ||
253 | cancel_dirty_page(page, PAGE_CACHE_SIZE); | ||
254 | #endif | ||
255 | wait_on_page_writeback(page); | 252 | wait_on_page_writeback(page); |
256 | set_page_extent_mapped(page); | ||
257 | 253 | ||
258 | page_start = (u64)page->index << PAGE_CACHE_SHIFT; | 254 | page_start = (u64)page->index << PAGE_CACHE_SHIFT; |
259 | page_end = page_start + PAGE_CACHE_SIZE - 1; | 255 | page_end = page_start + PAGE_CACHE_SIZE - 1; |
260 | |||
261 | lock_extent(io_tree, page_start, page_end, GFP_NOFS); | 256 | lock_extent(io_tree, page_start, page_end, GFP_NOFS); |
257 | |||
258 | ordered = btrfs_lookup_ordered_extent(inode, page_start); | ||
259 | if (ordered) { | ||
260 | unlock_extent(io_tree, page_start, page_end, GFP_NOFS); | ||
261 | unlock_page(page); | ||
262 | page_cache_release(page); | ||
263 | btrfs_start_ordered_extent(inode, ordered, 1); | ||
264 | btrfs_put_ordered_extent(ordered); | ||
265 | goto again; | ||
266 | } | ||
267 | set_page_extent_mapped(page); | ||
268 | |||
262 | set_extent_delalloc(io_tree, page_start, | 269 | set_extent_delalloc(io_tree, page_start, |
263 | page_end, GFP_NOFS); | 270 | page_end, GFP_NOFS); |
264 | 271 | ||