diff options
Diffstat (limited to 'fs/gfs2')
-rw-r--r-- | fs/gfs2/aops.c | 17 |
1 files changed, 12 insertions, 5 deletions
diff --git a/fs/gfs2/aops.c b/fs/gfs2/aops.c index 0bad69ed6336..ee48ad37d9c0 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,27 +944,33 @@ static void gfs2_discard(struct gfs2_sbd *sdp, struct buffer_head *bh) | |||
943 | unlock_buffer(bh); | 944 | unlock_buffer(bh); |
944 | } | 945 | } |
945 | 946 | ||
946 | static void gfs2_invalidatepage(struct page *page, unsigned long offset) | 947 | static 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); |
951 | unsigned int stop = offset + length; | ||
952 | int partial_page = (offset || length < PAGE_CACHE_SIZE); | ||
949 | struct buffer_head *bh, *head; | 953 | struct buffer_head *bh, *head; |
950 | unsigned long pos = 0; | 954 | unsigned long pos = 0; |
951 | 955 | ||
952 | BUG_ON(!PageLocked(page)); | 956 | BUG_ON(!PageLocked(page)); |
953 | if (offset == 0) | 957 | if (!partial_page) |
954 | ClearPageChecked(page); | 958 | ClearPageChecked(page); |
955 | if (!page_has_buffers(page)) | 959 | if (!page_has_buffers(page)) |
956 | goto out; | 960 | goto out; |
957 | 961 | ||
958 | bh = head = page_buffers(page); | 962 | bh = head = page_buffers(page); |
959 | do { | 963 | do { |
964 | if (pos + bh->b_size > stop) | ||
965 | return; | ||
966 | |||
960 | if (offset <= pos) | 967 | if (offset <= pos) |
961 | gfs2_discard(sdp, bh); | 968 | gfs2_discard(sdp, bh); |
962 | pos += bh->b_size; | 969 | pos += bh->b_size; |
963 | bh = bh->b_this_page; | 970 | bh = bh->b_this_page; |
964 | } while (bh != head); | 971 | } while (bh != head); |
965 | out: | 972 | out: |
966 | if (offset == 0) | 973 | if (!partial_page) |
967 | try_to_release_page(page, 0); | 974 | try_to_release_page(page, 0); |
968 | } | 975 | } |
969 | 976 | ||