From: WU Fengguang - In sys_fadvise64_64(): if the start and/or end offsets do not fall on page boundaries, preserve the partial pages. The thinking here is that it is better to preserve needed memory than to not shoot down unneeded memory. - In invalidate_mapping_pages(): we were invalidating an entire pagevec's worth of pages each time around, even if that went beyond the part of the file which the caller asked to be invalidated. Fix that up. --- 25-akpm/mm/fadvise.c | 5 ++--- 25-akpm/mm/truncate.c | 2 ++ 2 files changed, 4 insertions(+), 3 deletions(-) diff -puN mm/fadvise.c~fadvise-fixups mm/fadvise.c --- 25/mm/fadvise.c~fadvise-fixups Mon Mar 8 13:46:43 2004 +++ 25-akpm/mm/fadvise.c Mon Mar 8 13:47:26 2004 @@ -65,9 +65,8 @@ asmlinkage long sys_fadvise64_64(int fd, case POSIX_FADV_DONTNEED: if (!bdi_write_congested(mapping->backing_dev_info)) filemap_flush(mapping); - start_index = offset >> PAGE_CACHE_SHIFT; - end_index = (offset + len + PAGE_CACHE_SIZE - 1) >> - PAGE_CACHE_SHIFT; + start_index = (offset + PAGE_CACHE_SIZE-1) >> PAGE_CACHE_SHIFT; + end_index = ((offset + len) >> PAGE_CACHE_SHIFT) - 1; invalidate_mapping_pages(mapping, start_index, end_index); break; default: diff -puN mm/truncate.c~fadvise-fixups mm/truncate.c --- 25/mm/truncate.c~fadvise-fixups Mon Mar 8 13:46:43 2004 +++ 25-akpm/mm/truncate.c Mon Mar 8 13:46:43 2004 @@ -227,6 +227,8 @@ unsigned long invalidate_mapping_pages(s ret += invalidate_complete_page(mapping, page); unlock: unlock_page(page); + if (next > end) + break; } pagevec_release(&pvec); cond_resched(); _