aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs/ioctl.c
diff options
context:
space:
mode:
authorChris Mason <chris.mason@oracle.com>2008-07-24 11:57:52 -0400
committerChris Mason <chris.mason@oracle.com>2008-09-25 11:04:05 -0400
commit3eaa2885276fd6dac7b076a793932428b7168e74 (patch)
treeb06382bec68bf1755597a74ac8225f3bcddda5e5 /fs/btrfs/ioctl.c
parent64f26f745084872b916cd1bef6054e21b15c5784 (diff)
Btrfs: Fix the defragmention code and the block relocation code for data=ordered
Before setting an extent to delalloc, the code needs to wait for pending ordered extents. Also, the relocation code needs to wait for ordered IO before scanning the block group again. This is because the extents are not removed until the IO for the new extents is finished Signed-off-by: Chris Mason <chris.mason@oracle.com>
Diffstat (limited to 'fs/btrfs/ioctl.c')
-rw-r--r--fs/btrfs/ioctl.c21
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++;
238again:
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