Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 361952
b: refs/heads/master
c: 4adaa61
h: refs/heads/master
v: v3
  • Loading branch information
Chris Mason committed Mar 26, 2013
1 parent 2abce6c commit 26b41a3
Show file tree
Hide file tree
Showing 4 changed files with 50 additions and 1 deletion.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 1dd05682b3ef6e70409e130bfd83e91770801589
refs/heads/master: 4adaa611020fa6ac65b0ac8db78276af4ec04e63
33 changes: 33 additions & 0 deletions trunk/fs/btrfs/extent_io.c
Original file line number Diff line number Diff line change
Expand Up @@ -1257,6 +1257,39 @@ int unlock_extent(struct extent_io_tree *tree, u64 start, u64 end)
GFP_NOFS);
}

int extent_range_clear_dirty_for_io(struct inode *inode, u64 start, u64 end)
{
unsigned long index = start >> PAGE_CACHE_SHIFT;
unsigned long end_index = end >> PAGE_CACHE_SHIFT;
struct page *page;

while (index <= end_index) {
page = find_get_page(inode->i_mapping, index);
BUG_ON(!page); /* Pages should be in the extent_io_tree */
clear_page_dirty_for_io(page);
page_cache_release(page);
index++;
}
return 0;
}

int extent_range_redirty_for_io(struct inode *inode, u64 start, u64 end)
{
unsigned long index = start >> PAGE_CACHE_SHIFT;
unsigned long end_index = end >> PAGE_CACHE_SHIFT;
struct page *page;

while (index <= end_index) {
page = find_get_page(inode->i_mapping, index);
BUG_ON(!page); /* Pages should be in the extent_io_tree */
account_page_redirty(page);
__set_page_dirty_nobuffers(page);
page_cache_release(page);
index++;
}
return 0;
}

/*
* helper function to set both pages and extents in the tree writeback
*/
Expand Down
2 changes: 2 additions & 0 deletions trunk/fs/btrfs/extent_io.h
Original file line number Diff line number Diff line change
Expand Up @@ -325,6 +325,8 @@ int map_private_extent_buffer(struct extent_buffer *eb, unsigned long offset,
unsigned long *map_len);
int extent_range_uptodate(struct extent_io_tree *tree,
u64 start, u64 end);
int extent_range_clear_dirty_for_io(struct inode *inode, u64 start, u64 end);
int extent_range_redirty_for_io(struct inode *inode, u64 start, u64 end);
int extent_clear_unlock_delalloc(struct inode *inode,
struct extent_io_tree *tree,
u64 start, u64 end, struct page *locked_page,
Expand Down
14 changes: 14 additions & 0 deletions trunk/fs/btrfs/inode.c
Original file line number Diff line number Diff line change
Expand Up @@ -353,6 +353,7 @@ static noinline int compress_file_range(struct inode *inode,
int i;
int will_compress;
int compress_type = root->fs_info->compress_type;
int redirty = 0;

/* if this is a small write inside eof, kick off a defrag */
if ((end - start + 1) < 16 * 1024 &&
Expand Down Expand Up @@ -415,6 +416,17 @@ static noinline int compress_file_range(struct inode *inode,
if (BTRFS_I(inode)->force_compress)
compress_type = BTRFS_I(inode)->force_compress;

/*
* we need to call clear_page_dirty_for_io on each
* page in the range. Otherwise applications with the file
* mmap'd can wander in and change the page contents while
* we are compressing them.
*
* If the compression fails for any reason, we set the pages
* dirty again later on.
*/
extent_range_clear_dirty_for_io(inode, start, end);
redirty = 1;
ret = btrfs_compress_pages(compress_type,
inode->i_mapping, start,
total_compressed, pages,
Expand Down Expand Up @@ -554,6 +566,8 @@ static noinline int compress_file_range(struct inode *inode,
__set_page_dirty_nobuffers(locked_page);
/* unlocked later on in the async handlers */
}
if (redirty)
extent_range_redirty_for_io(inode, start, end);
add_async_extent(async_cow, start, end - start + 1,
0, NULL, 0, BTRFS_COMPRESS_NONE);
*num_added += 1;
Expand Down

0 comments on commit 26b41a3

Please sign in to comment.