aboutsummaryrefslogtreecommitdiffstats
path: root/fs/ext4
diff options
context:
space:
mode:
authorLukas Czerner <lczerner@redhat.com>2013-05-21 23:17:23 -0400
committerTheodore Ts'o <tytso@mit.edu>2013-05-21 23:17:23 -0400
commitd47992f86b307985b3215bcf141d56d1849d71df (patch)
treee1ae47bd19185371462c5a273c15276534447349 /fs/ext4
parentc7788792a5e7b0d5d7f96d0766b4cb6112d47d75 (diff)
mm: change invalidatepage prototype to accept length
Currently there is no way to truncate partial page where the end truncate point is not at the end of the page. This is because it was not needed and the functionality was enough for file system truncate operation to work properly. However more file systems now support punch hole feature and it can benefit from mm supporting truncating page just up to the certain point. Specifically, with this functionality truncate_inode_pages_range() can be changed so it supports truncating partial page at the end of the range (currently it will BUG_ON() if 'end' is not at the end of the page). This commit changes the invalidatepage() address space operation prototype to accept range to be invalidated and update all the instances for it. We also change the block_invalidatepage() in the same way and actually make a use of the new length argument implementing range invalidation. Actual file system implementations will follow except the file systems where the changes are really simple and should not change the behaviour in any way .Implementation for truncate_page_range() which will be able to accept page unaligned ranges will follow as well. Signed-off-by: Lukas Czerner <lczerner@redhat.com> Cc: Andrew Morton <akpm@linux-foundation.org> Cc: Hugh Dickins <hughd@google.com>
Diffstat (limited to 'fs/ext4')
-rw-r--r--fs/ext4/inode.c18
1 files changed, 11 insertions, 7 deletions
diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c
index d6382b89ecbd..19d6ca27c879 100644
--- a/fs/ext4/inode.c
+++ b/fs/ext4/inode.c
@@ -132,7 +132,8 @@ static inline int ext4_begin_ordered_truncate(struct inode *inode,
132 new_size); 132 new_size);
133} 133}
134 134
135static void ext4_invalidatepage(struct page *page, unsigned long offset); 135static void ext4_invalidatepage(struct page *page, unsigned int offset,
136 unsigned int length);
136static int __ext4_journalled_writepage(struct page *page, unsigned int len); 137static int __ext4_journalled_writepage(struct page *page, unsigned int len);
137static int ext4_bh_delay_or_unwritten(handle_t *handle, struct buffer_head *bh); 138static int ext4_bh_delay_or_unwritten(handle_t *handle, struct buffer_head *bh);
138static int ext4_discard_partial_page_buffers_no_lock(handle_t *handle, 139static int ext4_discard_partial_page_buffers_no_lock(handle_t *handle,
@@ -1606,7 +1607,7 @@ static void ext4_da_block_invalidatepages(struct mpage_da_data *mpd)
1606 break; 1607 break;
1607 BUG_ON(!PageLocked(page)); 1608 BUG_ON(!PageLocked(page));
1608 BUG_ON(PageWriteback(page)); 1609 BUG_ON(PageWriteback(page));
1609 block_invalidatepage(page, 0); 1610 block_invalidatepage(page, 0, PAGE_CACHE_SIZE);
1610 ClearPageUptodate(page); 1611 ClearPageUptodate(page);
1611 unlock_page(page); 1612 unlock_page(page);
1612 } 1613 }
@@ -2829,7 +2830,8 @@ static int ext4_da_write_end(struct file *file,
2829 return ret ? ret : copied; 2830 return ret ? ret : copied;
2830} 2831}
2831 2832
2832static void ext4_da_invalidatepage(struct page *page, unsigned long offset) 2833static void ext4_da_invalidatepage(struct page *page, unsigned int offset,
2834 unsigned int length)
2833{ 2835{
2834 /* 2836 /*
2835 * Drop reserved blocks 2837 * Drop reserved blocks
@@ -2841,7 +2843,7 @@ static void ext4_da_invalidatepage(struct page *page, unsigned long offset)
2841 ext4_da_page_release_reservation(page, offset); 2843 ext4_da_page_release_reservation(page, offset);
2842 2844
2843out: 2845out:
2844 ext4_invalidatepage(page, offset); 2846 ext4_invalidatepage(page, offset, length);
2845 2847
2846 return; 2848 return;
2847} 2849}
@@ -2989,14 +2991,15 @@ ext4_readpages(struct file *file, struct address_space *mapping,
2989 return mpage_readpages(mapping, pages, nr_pages, ext4_get_block); 2991 return mpage_readpages(mapping, pages, nr_pages, ext4_get_block);
2990} 2992}
2991 2993
2992static void ext4_invalidatepage(struct page *page, unsigned long offset) 2994static void ext4_invalidatepage(struct page *page, unsigned int offset,
2995 unsigned int length)
2993{ 2996{
2994 trace_ext4_invalidatepage(page, offset); 2997 trace_ext4_invalidatepage(page, offset);
2995 2998
2996 /* No journalling happens on data buffers when this function is used */ 2999 /* No journalling happens on data buffers when this function is used */
2997 WARN_ON(page_has_buffers(page) && buffer_jbd(page_buffers(page))); 3000 WARN_ON(page_has_buffers(page) && buffer_jbd(page_buffers(page)));
2998 3001
2999 block_invalidatepage(page, offset); 3002 block_invalidatepage(page, offset, PAGE_CACHE_SIZE - offset);
3000} 3003}
3001 3004
3002static int __ext4_journalled_invalidatepage(struct page *page, 3005static int __ext4_journalled_invalidatepage(struct page *page,
@@ -3017,7 +3020,8 @@ static int __ext4_journalled_invalidatepage(struct page *page,
3017 3020
3018/* Wrapper for aops... */ 3021/* Wrapper for aops... */
3019static void ext4_journalled_invalidatepage(struct page *page, 3022static void ext4_journalled_invalidatepage(struct page *page,
3020 unsigned long offset) 3023 unsigned int offset,
3024 unsigned int length)
3021{ 3025{
3022 WARN_ON(__ext4_journalled_invalidatepage(page, offset) < 0); 3026 WARN_ON(__ext4_journalled_invalidatepage(page, offset) < 0);
3023} 3027}