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