diff options
author | Chris Mason <chris.mason@oracle.com> | 2008-05-15 09:13:45 -0400 |
---|---|---|
committer | Chris Mason <chris.mason@oracle.com> | 2008-09-25 11:04:03 -0400 |
commit | 211c17f51f46dc6c308c742098273dd46b5ca59c (patch) | |
tree | d72de74136af93236f2b37088ff310f08ddeadf5 /fs/btrfs/extent_io.c | |
parent | a0af469b58944f6e8c5c8ecbebb42997baf0cb9e (diff) |
Fix corners in writepage and btrfs_truncate_page
The extent_io writepage calls needed an extra check for discarding
pages that started on th last byte in the file.
btrfs_truncate_page needed checks to make sure the page was still part
of the file after reading it, and most importantly, needed to wait for
all IO to the page to finish before freeing the corresponding extents on
disk.
Signed-off-by: Chris Mason <chris.mason@oracle.com>
Diffstat (limited to 'fs/btrfs/extent_io.c')
-rw-r--r-- | fs/btrfs/extent_io.c | 15 |
1 files changed, 9 insertions, 6 deletions
diff --git a/fs/btrfs/extent_io.c b/fs/btrfs/extent_io.c index 2a3624adc0cf..17c508a941eb 100644 --- a/fs/btrfs/extent_io.c +++ b/fs/btrfs/extent_io.c | |||
@@ -1988,9 +1988,12 @@ static int __extent_writepage(struct page *page, struct writeback_control *wbc, | |||
1988 | u64 nr_delalloc; | 1988 | u64 nr_delalloc; |
1989 | u64 delalloc_end; | 1989 | u64 delalloc_end; |
1990 | 1990 | ||
1991 | |||
1991 | WARN_ON(!PageLocked(page)); | 1992 | WARN_ON(!PageLocked(page)); |
1992 | if (page->index > end_index) { | 1993 | page_offset = i_size & (PAGE_CACHE_SIZE - 1); |
1993 | clear_extent_dirty(tree, start, page_end, GFP_NOFS); | 1994 | if (page->index > end_index || |
1995 | (page->index == end_index && !page_offset)) { | ||
1996 | page->mapping->a_ops->invalidatepage(page, 0); | ||
1994 | unlock_page(page); | 1997 | unlock_page(page); |
1995 | return 0; | 1998 | return 0; |
1996 | } | 1999 | } |
@@ -1998,13 +2001,13 @@ static int __extent_writepage(struct page *page, struct writeback_control *wbc, | |||
1998 | if (page->index == end_index) { | 2001 | if (page->index == end_index) { |
1999 | char *userpage; | 2002 | char *userpage; |
2000 | 2003 | ||
2001 | size_t offset = i_size & (PAGE_CACHE_SIZE - 1); | ||
2002 | |||
2003 | userpage = kmap_atomic(page, KM_USER0); | 2004 | userpage = kmap_atomic(page, KM_USER0); |
2004 | memset(userpage + offset, 0, PAGE_CACHE_SIZE - offset); | 2005 | memset(userpage + page_offset, 0, |
2005 | flush_dcache_page(page); | 2006 | PAGE_CACHE_SIZE - page_offset); |
2006 | kunmap_atomic(userpage, KM_USER0); | 2007 | kunmap_atomic(userpage, KM_USER0); |
2008 | flush_dcache_page(page); | ||
2007 | } | 2009 | } |
2010 | page_offset = 0; | ||
2008 | 2011 | ||
2009 | set_page_extent_mapped(page); | 2012 | set_page_extent_mapped(page); |
2010 | 2013 | ||