Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 287893
b: refs/heads/master
c: 600a45e
h: refs/heads/master
i:
  287891: c519998
v: v3
  • Loading branch information
Miao Xie authored and David Sterba committed Feb 16, 2012
1 parent 4bcd857 commit af3ab3e
Show file tree
Hide file tree
Showing 2 changed files with 30 additions and 25 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 013bd4c336ad0d30e9e41f9cff0dbc1858934e75
refs/heads/master: 600a45e1d5e376f679ff9ecc4ce9452710a6d27c
53 changes: 29 additions & 24 deletions trunk/fs/btrfs/ioctl.c
Original file line number Diff line number Diff line change
Expand Up @@ -862,6 +862,7 @@ static int cluster_pages_for_defrag(struct inode *inode,
int i_done;
struct btrfs_ordered_extent *ordered;
struct extent_state *cached_state = NULL;
struct extent_io_tree *tree;
gfp_t mask = btrfs_alloc_write_mask(inode->i_mapping);

if (isize == 0)
Expand All @@ -872,18 +873,34 @@ static int cluster_pages_for_defrag(struct inode *inode,
num_pages << PAGE_CACHE_SHIFT);
if (ret)
return ret;
again:
ret = 0;
i_done = 0;
tree = &BTRFS_I(inode)->io_tree;

/* step one, lock all the pages */
for (i = 0; i < num_pages; i++) {
struct page *page;
again:
page = find_or_create_page(inode->i_mapping,
start_index + i, mask);
start_index + i, mask);
if (!page)
break;

page_start = page_offset(page);
page_end = page_start + PAGE_CACHE_SIZE - 1;
while (1) {
lock_extent(tree, page_start, page_end, GFP_NOFS);
ordered = btrfs_lookup_ordered_extent(inode,
page_start);
unlock_extent(tree, page_start, page_end, GFP_NOFS);
if (!ordered)
break;

unlock_page(page);
btrfs_start_ordered_extent(inode, ordered, 1);
btrfs_put_ordered_extent(ordered);
lock_page(page);
}

if (!PageUptodate(page)) {
btrfs_readpage(NULL, page);
lock_page(page);
Expand All @@ -894,15 +911,22 @@ static int cluster_pages_for_defrag(struct inode *inode,
break;
}
}

isize = i_size_read(inode);
file_end = (isize - 1) >> PAGE_CACHE_SHIFT;
if (!isize || page->index > file_end ||
page->mapping != inode->i_mapping) {
if (!isize || page->index > file_end) {
/* whoops, we blew past eof, skip this page */
unlock_page(page);
page_cache_release(page);
break;
}

if (page->mapping != inode->i_mapping) {
unlock_page(page);
page_cache_release(page);
goto again;
}

pages[i] = page;
i_done++;
}
Expand All @@ -925,25 +949,6 @@ static int cluster_pages_for_defrag(struct inode *inode,
lock_extent_bits(&BTRFS_I(inode)->io_tree,
page_start, page_end - 1, 0, &cached_state,
GFP_NOFS);
ordered = btrfs_lookup_first_ordered_extent(inode, page_end - 1);
if (ordered &&
ordered->file_offset + ordered->len > page_start &&
ordered->file_offset < page_end) {
btrfs_put_ordered_extent(ordered);
unlock_extent_cached(&BTRFS_I(inode)->io_tree,
page_start, page_end - 1,
&cached_state, GFP_NOFS);
for (i = 0; i < i_done; i++) {
unlock_page(pages[i]);
page_cache_release(pages[i]);
}
btrfs_wait_ordered_range(inode, page_start,
page_end - page_start);
goto again;
}
if (ordered)
btrfs_put_ordered_extent(ordered);

clear_extent_bit(&BTRFS_I(inode)->io_tree, page_start,
page_end - 1, EXTENT_DIRTY | EXTENT_DELALLOC |
EXTENT_DO_ACCOUNTING, 0, 0, &cached_state,
Expand Down

0 comments on commit af3ab3e

Please sign in to comment.