Skip to content

Commit

Permalink
mm/fadvise.c: do not discard partial pages with POSIX_FADV_DONTNEED
Browse files Browse the repository at this point in the history
I noticed that the logic in the fadvise64_64 syscall is incorrect for
partial pages.  While first page of the region is correctly skipped if
it is partial, the last page of the region is mistakenly discarded.
This leads to problems for applications that read data in
non-page-aligned chunks discarding already processed data between the
reads.

A somewhat misguided application that does something like write(XX bytes
(non-page-alligned)); drop the data it just wrote; repeat gets a
significant penalty in performance as a result.

Link: http://lkml.kernel.org/r/[email protected]
Signed-off-by: Oleg Drokin <[email protected]>
Signed-off-by: Andrew Morton <[email protected]>
Signed-off-by: Linus Torvalds <[email protected]>
  • Loading branch information
verygreen authored and torvalds committed Jun 9, 2016
1 parent f3a932b commit 18aba41
Showing 1 changed file with 11 additions and 0 deletions.
11 changes: 11 additions & 0 deletions mm/fadvise.c
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,17 @@ SYSCALL_DEFINE4(fadvise64_64, int, fd, loff_t, offset, loff_t, len, int, advice)
*/
start_index = (offset+(PAGE_SIZE-1)) >> PAGE_SHIFT;
end_index = (endbyte >> PAGE_SHIFT);
if ((endbyte & ~PAGE_MASK) != ~PAGE_MASK) {
/* First page is tricky as 0 - 1 = -1, but pgoff_t
* is unsigned, so the end_index >= start_index
* check below would be true and we'll discard the whole
* file cache which is not what was asked.
*/
if (end_index == 0)
break;

end_index--;
}

if (end_index >= start_index) {
unsigned long count = invalidate_mapping_pages(mapping,
Expand Down

0 comments on commit 18aba41

Please sign in to comment.