aboutsummaryrefslogtreecommitdiffstats
path: root/fs
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
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')
-rw-r--r--fs/9p/vfs_addr.c5
-rw-r--r--fs/afs/file.c10
-rw-r--r--fs/btrfs/disk-io.c3
-rw-r--r--fs/btrfs/extent_io.c2
-rw-r--r--fs/btrfs/inode.c3
-rw-r--r--fs/buffer.c21
-rw-r--r--fs/ceph/addr.c5
-rw-r--r--fs/cifs/file.c5
-rw-r--r--fs/exofs/inode.c6
-rw-r--r--fs/ext3/inode.c3
-rw-r--r--fs/ext4/inode.c18
-rw-r--r--fs/f2fs/data.c3
-rw-r--r--fs/f2fs/node.c3
-rw-r--r--fs/gfs2/aops.c8
-rw-r--r--fs/jfs/jfs_metapage.c5
-rw-r--r--fs/logfs/file.c3
-rw-r--r--fs/logfs/segment.c3
-rw-r--r--fs/nfs/file.c8
-rw-r--r--fs/ntfs/aops.c2
-rw-r--r--fs/ocfs2/aops.c3
-rw-r--r--fs/reiserfs/inode.c3
-rw-r--r--fs/ubifs/file.c5
-rw-r--r--fs/xfs/xfs_aops.c7
23 files changed, 88 insertions, 46 deletions
diff --git a/fs/9p/vfs_addr.c b/fs/9p/vfs_addr.c
index 055562c580b4..9ff073f4090a 100644
--- a/fs/9p/vfs_addr.c
+++ b/fs/9p/vfs_addr.c
@@ -148,13 +148,14 @@ static int v9fs_release_page(struct page *page, gfp_t gfp)
148 * @offset: offset in the page 148 * @offset: offset in the page
149 */ 149 */
150 150
151static void v9fs_invalidate_page(struct page *page, unsigned long offset) 151static void v9fs_invalidate_page(struct page *page, unsigned int offset,
152 unsigned int length)
152{ 153{
153 /* 154 /*
154 * If called with zero offset, we should release 155 * If called with zero offset, we should release
155 * the private state assocated with the page 156 * the private state assocated with the page
156 */ 157 */
157 if (offset == 0) 158 if (offset == 0 && length == PAGE_CACHE_SIZE)
158 v9fs_fscache_invalidate_page(page); 159 v9fs_fscache_invalidate_page(page);
159} 160}
160 161
diff --git a/fs/afs/file.c b/fs/afs/file.c
index 8f6e9234d565..66d50fe2ee45 100644
--- a/fs/afs/file.c
+++ b/fs/afs/file.c
@@ -19,7 +19,8 @@
19#include "internal.h" 19#include "internal.h"
20 20
21static int afs_readpage(struct file *file, struct page *page); 21static int afs_readpage(struct file *file, struct page *page);
22static void afs_invalidatepage(struct page *page, unsigned long offset); 22static void afs_invalidatepage(struct page *page, unsigned int offset,
23 unsigned int length);
23static int afs_releasepage(struct page *page, gfp_t gfp_flags); 24static int afs_releasepage(struct page *page, gfp_t gfp_flags);
24static int afs_launder_page(struct page *page); 25static int afs_launder_page(struct page *page);
25 26
@@ -310,16 +311,17 @@ static int afs_launder_page(struct page *page)
310 * - release a page and clean up its private data if offset is 0 (indicating 311 * - release a page and clean up its private data if offset is 0 (indicating
311 * the entire page) 312 * the entire page)
312 */ 313 */
313static void afs_invalidatepage(struct page *page, unsigned long offset) 314static void afs_invalidatepage(struct page *page, unsigned int offset,
315 unsigned int length)
314{ 316{
315 struct afs_writeback *wb = (struct afs_writeback *) page_private(page); 317 struct afs_writeback *wb = (struct afs_writeback *) page_private(page);
316 318
317 _enter("{%lu},%lu", page->index, offset); 319 _enter("{%lu},%u,%u", page->index, offset, length);
318 320
319 BUG_ON(!PageLocked(page)); 321 BUG_ON(!PageLocked(page));
320 322
321 /* we clean up only if the entire page is being invalidated */ 323 /* we clean up only if the entire page is being invalidated */
322 if (offset == 0) { 324 if (offset == 0 && length == PAGE_CACHE_SIZE) {
323#ifdef CONFIG_AFS_FSCACHE 325#ifdef CONFIG_AFS_FSCACHE
324 if (PageFsCache(page)) { 326 if (PageFsCache(page)) {
325 struct afs_vnode *vnode = AFS_FS_I(page->mapping->host); 327 struct afs_vnode *vnode = AFS_FS_I(page->mapping->host);
diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c
index e7b3cb5286a5..40c7bc300075 100644
--- a/fs/btrfs/disk-io.c
+++ b/fs/btrfs/disk-io.c
@@ -1013,7 +1013,8 @@ static int btree_releasepage(struct page *page, gfp_t gfp_flags)
1013 return try_release_extent_buffer(page); 1013 return try_release_extent_buffer(page);
1014} 1014}
1015 1015
1016static void btree_invalidatepage(struct page *page, unsigned long offset) 1016static void btree_invalidatepage(struct page *page, unsigned int offset,
1017 unsigned int length)
1017{ 1018{
1018 struct extent_io_tree *tree; 1019 struct extent_io_tree *tree;
1019 tree = &BTRFS_I(page->mapping->host)->io_tree; 1020 tree = &BTRFS_I(page->mapping->host)->io_tree;
diff --git a/fs/btrfs/extent_io.c b/fs/btrfs/extent_io.c
index e7e7afb4a872..6bca9472f313 100644
--- a/fs/btrfs/extent_io.c
+++ b/fs/btrfs/extent_io.c
@@ -2957,7 +2957,7 @@ static int __extent_writepage(struct page *page, struct writeback_control *wbc,
2957 pg_offset = i_size & (PAGE_CACHE_SIZE - 1); 2957 pg_offset = i_size & (PAGE_CACHE_SIZE - 1);
2958 if (page->index > end_index || 2958 if (page->index > end_index ||
2959 (page->index == end_index && !pg_offset)) { 2959 (page->index == end_index && !pg_offset)) {
2960 page->mapping->a_ops->invalidatepage(page, 0); 2960 page->mapping->a_ops->invalidatepage(page, 0, PAGE_CACHE_SIZE);
2961 unlock_page(page); 2961 unlock_page(page);
2962 return 0; 2962 return 0;
2963 } 2963 }
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c
index af978f7682b3..db57e6384fbb 100644
--- a/fs/btrfs/inode.c
+++ b/fs/btrfs/inode.c
@@ -7510,7 +7510,8 @@ static int btrfs_releasepage(struct page *page, gfp_t gfp_flags)
7510 return __btrfs_releasepage(page, gfp_flags & GFP_NOFS); 7510 return __btrfs_releasepage(page, gfp_flags & GFP_NOFS);
7511} 7511}
7512 7512
7513static void btrfs_invalidatepage(struct page *page, unsigned long offset) 7513static void btrfs_invalidatepage(struct page *page, unsigned int offset,
7514 unsigned int length)
7514{ 7515{
7515 struct inode *inode = page->mapping->host; 7516 struct inode *inode = page->mapping->host;
7516 struct extent_io_tree *tree; 7517 struct extent_io_tree *tree;
diff --git a/fs/buffer.c b/fs/buffer.c
index d2a4d1bb2d57..f93392e2df12 100644
--- a/fs/buffer.c
+++ b/fs/buffer.c
@@ -1454,7 +1454,8 @@ static void discard_buffer(struct buffer_head * bh)
1454 * block_invalidatepage - invalidate part or all of a buffer-backed page 1454 * block_invalidatepage - invalidate part or all of a buffer-backed page
1455 * 1455 *
1456 * @page: the page which is affected 1456 * @page: the page which is affected
1457 * @offset: the index of the truncation point 1457 * @offset: start of the range to invalidate
1458 * @length: length of the range to invalidate
1458 * 1459 *
1459 * block_invalidatepage() is called when all or part of the page has become 1460 * block_invalidatepage() is called when all or part of the page has become
1460 * invalidated by a truncate operation. 1461 * invalidated by a truncate operation.
@@ -1465,15 +1466,22 @@ static void discard_buffer(struct buffer_head * bh)
1465 * point. Because the caller is about to free (and possibly reuse) those 1466 * point. Because the caller is about to free (and possibly reuse) those
1466 * blocks on-disk. 1467 * blocks on-disk.
1467 */ 1468 */
1468void block_invalidatepage(struct page *page, unsigned long offset) 1469void block_invalidatepage(struct page *page, unsigned int offset,
1470 unsigned int length)
1469{ 1471{
1470 struct buffer_head *head, *bh, *next; 1472 struct buffer_head *head, *bh, *next;
1471 unsigned int curr_off = 0; 1473 unsigned int curr_off = 0;
1474 unsigned int stop = length + offset;
1472 1475
1473 BUG_ON(!PageLocked(page)); 1476 BUG_ON(!PageLocked(page));
1474 if (!page_has_buffers(page)) 1477 if (!page_has_buffers(page))
1475 goto out; 1478 goto out;
1476 1479
1480 /*
1481 * Check for overflow
1482 */
1483 BUG_ON(stop > PAGE_CACHE_SIZE || stop < length);
1484
1477 head = page_buffers(page); 1485 head = page_buffers(page);
1478 bh = head; 1486 bh = head;
1479 do { 1487 do {
@@ -1481,6 +1489,12 @@ void block_invalidatepage(struct page *page, unsigned long offset)
1481 next = bh->b_this_page; 1489 next = bh->b_this_page;
1482 1490
1483 /* 1491 /*
1492 * Are we still fully in range ?
1493 */
1494 if (next_off > stop)
1495 goto out;
1496
1497 /*
1484 * is this block fully invalidated? 1498 * is this block fully invalidated?
1485 */ 1499 */
1486 if (offset <= curr_off) 1500 if (offset <= curr_off)
@@ -1501,6 +1515,7 @@ out:
1501} 1515}
1502EXPORT_SYMBOL(block_invalidatepage); 1516EXPORT_SYMBOL(block_invalidatepage);
1503 1517
1518
1504/* 1519/*
1505 * We attach and possibly dirty the buffers atomically wrt 1520 * We attach and possibly dirty the buffers atomically wrt
1506 * __set_page_dirty_buffers() via private_lock. try_to_free_buffers 1521 * __set_page_dirty_buffers() via private_lock. try_to_free_buffers
@@ -2841,7 +2856,7 @@ int block_write_full_page_endio(struct page *page, get_block_t *get_block,
2841 * they may have been added in ext3_writepage(). Make them 2856 * they may have been added in ext3_writepage(). Make them
2842 * freeable here, so the page does not leak. 2857 * freeable here, so the page does not leak.
2843 */ 2858 */
2844 do_invalidatepage(page, 0); 2859 do_invalidatepage(page, 0, PAGE_CACHE_SIZE);
2845 unlock_page(page); 2860 unlock_page(page);
2846 return 0; /* don't care */ 2861 return 0; /* don't care */
2847 } 2862 }
diff --git a/fs/ceph/addr.c b/fs/ceph/addr.c
index 3e68ac101040..b1899400df1f 100644
--- a/fs/ceph/addr.c
+++ b/fs/ceph/addr.c
@@ -143,7 +143,8 @@ static int ceph_set_page_dirty(struct page *page)
143 * dirty page counters appropriately. Only called if there is private 143 * dirty page counters appropriately. Only called if there is private
144 * data on the page. 144 * data on the page.
145 */ 145 */
146static void ceph_invalidatepage(struct page *page, unsigned long offset) 146static void ceph_invalidatepage(struct page *page, unsigned int offset,
147 unsigned int length)
147{ 148{
148 struct inode *inode; 149 struct inode *inode;
149 struct ceph_inode_info *ci; 150 struct ceph_inode_info *ci;
@@ -168,7 +169,7 @@ static void ceph_invalidatepage(struct page *page, unsigned long offset)
168 169
169 ci = ceph_inode(inode); 170 ci = ceph_inode(inode);
170 if (offset == 0) { 171 if (offset == 0) {
171 dout("%p invalidatepage %p idx %lu full dirty page %lu\n", 172 dout("%p invalidatepage %p idx %lu full dirty page %u\n",
172 inode, page, page->index, offset); 173 inode, page, page->index, offset);
173 ceph_put_wrbuffer_cap_refs(ci, 1, snapc); 174 ceph_put_wrbuffer_cap_refs(ci, 1, snapc);
174 ceph_put_snap_context(snapc); 175 ceph_put_snap_context(snapc);
diff --git a/fs/cifs/file.c b/fs/cifs/file.c
index 48b29d24c9f4..4d8ba8d491e5 100644
--- a/fs/cifs/file.c
+++ b/fs/cifs/file.c
@@ -3546,11 +3546,12 @@ static int cifs_release_page(struct page *page, gfp_t gfp)
3546 return cifs_fscache_release_page(page, gfp); 3546 return cifs_fscache_release_page(page, gfp);
3547} 3547}
3548 3548
3549static void cifs_invalidate_page(struct page *page, unsigned long offset) 3549static void cifs_invalidate_page(struct page *page, unsigned int offset,
3550 unsigned int length)
3550{ 3551{
3551 struct cifsInodeInfo *cifsi = CIFS_I(page->mapping->host); 3552 struct cifsInodeInfo *cifsi = CIFS_I(page->mapping->host);
3552 3553
3553 if (offset == 0) 3554 if (offset == 0 && length == PAGE_CACHE_SIZE)
3554 cifs_fscache_invalidate_page(page, &cifsi->vfs_inode); 3555 cifs_fscache_invalidate_page(page, &cifsi->vfs_inode);
3555} 3556}
3556 3557
diff --git a/fs/exofs/inode.c b/fs/exofs/inode.c
index d1f80abd8828..2ec8eb1ab269 100644
--- a/fs/exofs/inode.c
+++ b/fs/exofs/inode.c
@@ -953,9 +953,11 @@ static int exofs_releasepage(struct page *page, gfp_t gfp)
953 return 0; 953 return 0;
954} 954}
955 955
956static void exofs_invalidatepage(struct page *page, unsigned long offset) 956static void exofs_invalidatepage(struct page *page, unsigned int offset,
957 unsigned int length)
957{ 958{
958 EXOFS_DBGMSG("page 0x%lx offset 0x%lx\n", page->index, offset); 959 EXOFS_DBGMSG("page 0x%lx offset 0x%x length 0x%x\n",
960 page->index, offset, length);
959 WARN_ON(1); 961 WARN_ON(1);
960} 962}
961 963
diff --git a/fs/ext3/inode.c b/fs/ext3/inode.c
index 23c712825640..b6e5934f5dd6 100644
--- a/fs/ext3/inode.c
+++ b/fs/ext3/inode.c
@@ -1825,7 +1825,8 @@ ext3_readpages(struct file *file, struct address_space *mapping,
1825 return mpage_readpages(mapping, pages, nr_pages, ext3_get_block); 1825 return mpage_readpages(mapping, pages, nr_pages, ext3_get_block);
1826} 1826}
1827 1827
1828static void ext3_invalidatepage(struct page *page, unsigned long offset) 1828static void ext3_invalidatepage(struct page *page, unsigned int offset,
1829 unsigned int length)
1829{ 1830{
1830 journal_t *journal = EXT3_JOURNAL(page->mapping->host); 1831 journal_t *journal = EXT3_JOURNAL(page->mapping->host);
1831 1832
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}
diff --git a/fs/f2fs/data.c b/fs/f2fs/data.c
index 91ff93b0b0f4..ce11d9a92aed 100644
--- a/fs/f2fs/data.c
+++ b/fs/f2fs/data.c
@@ -698,7 +698,8 @@ static ssize_t f2fs_direct_IO(int rw, struct kiocb *iocb,
698 get_data_block_ro); 698 get_data_block_ro);
699} 699}
700 700
701static void f2fs_invalidate_data_page(struct page *page, unsigned long offset) 701static void f2fs_invalidate_data_page(struct page *page, unsigned int offset,
702 unsigned int length)
702{ 703{
703 struct inode *inode = page->mapping->host; 704 struct inode *inode = page->mapping->host;
704 struct f2fs_sb_info *sbi = F2FS_SB(inode->i_sb); 705 struct f2fs_sb_info *sbi = F2FS_SB(inode->i_sb);
diff --git a/fs/f2fs/node.c b/fs/f2fs/node.c
index 3df43b4efd89..74f3c7b03eb2 100644
--- a/fs/f2fs/node.c
+++ b/fs/f2fs/node.c
@@ -1205,7 +1205,8 @@ static int f2fs_set_node_page_dirty(struct page *page)
1205 return 0; 1205 return 0;
1206} 1206}
1207 1207
1208static void f2fs_invalidate_node_page(struct page *page, unsigned long offset) 1208static void f2fs_invalidate_node_page(struct page *page, unsigned int offset,
1209 unsigned int length)
1209{ 1210{
1210 struct inode *inode = page->mapping->host; 1211 struct inode *inode = page->mapping->host;
1211 struct f2fs_sb_info *sbi = F2FS_SB(inode->i_sb); 1212 struct f2fs_sb_info *sbi = F2FS_SB(inode->i_sb);
diff --git a/fs/gfs2/aops.c b/fs/gfs2/aops.c
index 0bad69ed6336..db0d39f9fba4 100644
--- a/fs/gfs2/aops.c
+++ b/fs/gfs2/aops.c
@@ -110,7 +110,7 @@ static int gfs2_writepage_common(struct page *page,
110 /* Is the page fully outside i_size? (truncate in progress) */ 110 /* Is the page fully outside i_size? (truncate in progress) */
111 offset = i_size & (PAGE_CACHE_SIZE-1); 111 offset = i_size & (PAGE_CACHE_SIZE-1);
112 if (page->index > end_index || (page->index == end_index && !offset)) { 112 if (page->index > end_index || (page->index == end_index && !offset)) {
113 page->mapping->a_ops->invalidatepage(page, 0); 113 page->mapping->a_ops->invalidatepage(page, 0, PAGE_CACHE_SIZE);
114 goto out; 114 goto out;
115 } 115 }
116 return 1; 116 return 1;
@@ -299,7 +299,8 @@ static int gfs2_write_jdata_pagevec(struct address_space *mapping,
299 299
300 /* Is the page fully outside i_size? (truncate in progress) */ 300 /* Is the page fully outside i_size? (truncate in progress) */
301 if (page->index > end_index || (page->index == end_index && !offset)) { 301 if (page->index > end_index || (page->index == end_index && !offset)) {
302 page->mapping->a_ops->invalidatepage(page, 0); 302 page->mapping->a_ops->invalidatepage(page, 0,
303 PAGE_CACHE_SIZE);
303 unlock_page(page); 304 unlock_page(page);
304 continue; 305 continue;
305 } 306 }
@@ -943,7 +944,8 @@ static void gfs2_discard(struct gfs2_sbd *sdp, struct buffer_head *bh)
943 unlock_buffer(bh); 944 unlock_buffer(bh);
944} 945}
945 946
946static void gfs2_invalidatepage(struct page *page, unsigned long offset) 947static void gfs2_invalidatepage(struct page *page, unsigned int offset,
948 unsigned int length)
947{ 949{
948 struct gfs2_sbd *sdp = GFS2_SB(page->mapping->host); 950 struct gfs2_sbd *sdp = GFS2_SB(page->mapping->host);
949 struct buffer_head *bh, *head; 951 struct buffer_head *bh, *head;
diff --git a/fs/jfs/jfs_metapage.c b/fs/jfs/jfs_metapage.c
index 6740d34cd82b..9e3aaff11f89 100644
--- a/fs/jfs/jfs_metapage.c
+++ b/fs/jfs/jfs_metapage.c
@@ -571,9 +571,10 @@ static int metapage_releasepage(struct page *page, gfp_t gfp_mask)
571 return ret; 571 return ret;
572} 572}
573 573
574static void metapage_invalidatepage(struct page *page, unsigned long offset) 574static void metapage_invalidatepage(struct page *page, unsigned int offset,
575 unsigned int length)
575{ 576{
576 BUG_ON(offset); 577 BUG_ON(offset || length < PAGE_CACHE_SIZE);
577 578
578 BUG_ON(PageWriteback(page)); 579 BUG_ON(PageWriteback(page));
579 580
diff --git a/fs/logfs/file.c b/fs/logfs/file.c
index c2219a6dd3c8..57914fc32b62 100644
--- a/fs/logfs/file.c
+++ b/fs/logfs/file.c
@@ -159,7 +159,8 @@ static int logfs_writepage(struct page *page, struct writeback_control *wbc)
159 return __logfs_writepage(page); 159 return __logfs_writepage(page);
160} 160}
161 161
162static void logfs_invalidatepage(struct page *page, unsigned long offset) 162static void logfs_invalidatepage(struct page *page, unsigned int offset,
163 unsigned int length)
163{ 164{
164 struct logfs_block *block = logfs_block(page); 165 struct logfs_block *block = logfs_block(page);
165 166
diff --git a/fs/logfs/segment.c b/fs/logfs/segment.c
index 038da0991794..d448a777166b 100644
--- a/fs/logfs/segment.c
+++ b/fs/logfs/segment.c
@@ -884,7 +884,8 @@ static struct logfs_area *alloc_area(struct super_block *sb)
884 return area; 884 return area;
885} 885}
886 886
887static void map_invalidatepage(struct page *page, unsigned long l) 887static void map_invalidatepage(struct page *page, unsigned int o,
888 unsigned int l)
888{ 889{
889 return; 890 return;
890} 891}
diff --git a/fs/nfs/file.c b/fs/nfs/file.c
index a87a44f84113..6b4a79f4ad1d 100644
--- a/fs/nfs/file.c
+++ b/fs/nfs/file.c
@@ -451,11 +451,13 @@ static int nfs_write_end(struct file *file, struct address_space *mapping,
451 * - Called if either PG_private or PG_fscache is set on the page 451 * - Called if either PG_private or PG_fscache is set on the page
452 * - Caller holds page lock 452 * - Caller holds page lock
453 */ 453 */
454static void nfs_invalidate_page(struct page *page, unsigned long offset) 454static void nfs_invalidate_page(struct page *page, unsigned int offset,
455 unsigned int length)
455{ 456{
456 dfprintk(PAGECACHE, "NFS: invalidate_page(%p, %lu)\n", page, offset); 457 dfprintk(PAGECACHE, "NFS: invalidate_page(%p, %u, %u)\n",
458 page, offset, length);
457 459
458 if (offset != 0) 460 if (offset != 0 || length < PAGE_CACHE_SIZE)
459 return; 461 return;
460 /* Cancel any unstarted writes on this page */ 462 /* Cancel any unstarted writes on this page */
461 nfs_wb_page_cancel(page_file_mapping(page)->host, page); 463 nfs_wb_page_cancel(page_file_mapping(page)->host, page);
diff --git a/fs/ntfs/aops.c b/fs/ntfs/aops.c
index fa9c05f97af4..d267ea6aa1a0 100644
--- a/fs/ntfs/aops.c
+++ b/fs/ntfs/aops.c
@@ -1372,7 +1372,7 @@ retry_writepage:
1372 * The page may have dirty, unmapped buffers. Make them 1372 * The page may have dirty, unmapped buffers. Make them
1373 * freeable here, so the page does not leak. 1373 * freeable here, so the page does not leak.
1374 */ 1374 */
1375 block_invalidatepage(page, 0); 1375 block_invalidatepage(page, 0, PAGE_CACHE_SIZE);
1376 unlock_page(page); 1376 unlock_page(page);
1377 ntfs_debug("Write outside i_size - truncated?"); 1377 ntfs_debug("Write outside i_size - truncated?");
1378 return 0; 1378 return 0;
diff --git a/fs/ocfs2/aops.c b/fs/ocfs2/aops.c
index 20dfec72e903..ecb86ca8b1f1 100644
--- a/fs/ocfs2/aops.c
+++ b/fs/ocfs2/aops.c
@@ -603,7 +603,8 @@ static void ocfs2_dio_end_io(struct kiocb *iocb,
603 * from ext3. PageChecked() bits have been removed as OCFS2 does not 603 * from ext3. PageChecked() bits have been removed as OCFS2 does not
604 * do journalled data. 604 * do journalled data.
605 */ 605 */
606static void ocfs2_invalidatepage(struct page *page, unsigned long offset) 606static void ocfs2_invalidatepage(struct page *page, unsigned int offset,
607 unsigned int length)
607{ 608{
608 journal_t *journal = OCFS2_SB(page->mapping->host->i_sb)->journal->j_journal; 609 journal_t *journal = OCFS2_SB(page->mapping->host->i_sb)->journal->j_journal;
609 610
diff --git a/fs/reiserfs/inode.c b/fs/reiserfs/inode.c
index 77d6d47abc83..278c86e3e6c4 100644
--- a/fs/reiserfs/inode.c
+++ b/fs/reiserfs/inode.c
@@ -2970,7 +2970,8 @@ static int invalidatepage_can_drop(struct inode *inode, struct buffer_head *bh)
2970} 2970}
2971 2971
2972/* clm -- taken from fs/buffer.c:block_invalidate_page */ 2972/* clm -- taken from fs/buffer.c:block_invalidate_page */
2973static void reiserfs_invalidatepage(struct page *page, unsigned long offset) 2973static void reiserfs_invalidatepage(struct page *page, unsigned int offset,
2974 unsigned int length)
2974{ 2975{
2975 struct buffer_head *head, *bh, *next; 2976 struct buffer_head *head, *bh, *next;
2976 struct inode *inode = page->mapping->host; 2977 struct inode *inode = page->mapping->host;
diff --git a/fs/ubifs/file.c b/fs/ubifs/file.c
index 14374530784c..123c79b7261e 100644
--- a/fs/ubifs/file.c
+++ b/fs/ubifs/file.c
@@ -1277,13 +1277,14 @@ int ubifs_setattr(struct dentry *dentry, struct iattr *attr)
1277 return err; 1277 return err;
1278} 1278}
1279 1279
1280static void ubifs_invalidatepage(struct page *page, unsigned long offset) 1280static void ubifs_invalidatepage(struct page *page, unsigned int offset,
1281 unsigned int length)
1281{ 1282{
1282 struct inode *inode = page->mapping->host; 1283 struct inode *inode = page->mapping->host;
1283 struct ubifs_info *c = inode->i_sb->s_fs_info; 1284 struct ubifs_info *c = inode->i_sb->s_fs_info;
1284 1285
1285 ubifs_assert(PagePrivate(page)); 1286 ubifs_assert(PagePrivate(page));
1286 if (offset) 1287 if (offset || length < PAGE_CACHE_SIZE)
1287 /* Partial page remains dirty */ 1288 /* Partial page remains dirty */
1288 return; 1289 return;
1289 1290
diff --git a/fs/xfs/xfs_aops.c b/fs/xfs/xfs_aops.c
index 2b2691b73428..a8f63f38b8f7 100644
--- a/fs/xfs/xfs_aops.c
+++ b/fs/xfs/xfs_aops.c
@@ -824,10 +824,11 @@ xfs_cluster_write(
824STATIC void 824STATIC void
825xfs_vm_invalidatepage( 825xfs_vm_invalidatepage(
826 struct page *page, 826 struct page *page,
827 unsigned long offset) 827 unsigned int offset,
828 unsigned int length)
828{ 829{
829 trace_xfs_invalidatepage(page->mapping->host, page, offset); 830 trace_xfs_invalidatepage(page->mapping->host, page, offset);
830 block_invalidatepage(page, offset); 831 block_invalidatepage(page, offset, PAGE_CACHE_SIZE - offset);
831} 832}
832 833
833/* 834/*
@@ -891,7 +892,7 @@ next_buffer:
891 892
892 xfs_iunlock(ip, XFS_ILOCK_EXCL); 893 xfs_iunlock(ip, XFS_ILOCK_EXCL);
893out_invalidate: 894out_invalidate:
894 xfs_vm_invalidatepage(page, 0); 895 xfs_vm_invalidatepage(page, 0, PAGE_CACHE_SIZE);
895 return; 896 return;
896} 897}
897 898