[PATCH] fadvise invalidating range fix

From: WU Fengguang
Date: Mon Mar 08 2004 - 08:15:51 EST


Hi Andrew

I noticed fadvise(POSIX_FADV_DONTNEED) was invalidating more parts of the file
than I expected. Here is the patch.

Notes for change in fadvise.c/sys_fadvise64_64():

- It should be noticed that the 'end' param of invalidate_mapping_pages()
is inclusive;

- When 'offset' and/or 'offset+len' do no align to page boundary, we must
decide whether to abandon the partial page at the beginning/end of the range.
My patch assumes that the application is scanning forward,
which is the most common case.
So 'end_index' is set to the page just before the ending partial page.

- Manual pages for posix_fadvise() mentioned the case of 'len=0', which
is not handled by the code. Perhaps the handling of 'len=0' is useless,
so I leaved that alone.

Notes for change in truncate.c/invalidate_mapping_pages():

- Is there any reason that I din't know to free any page outside of [begin,end]?
The origin code will abandon useful trailing pages when there's hole
in the range, which may cause series of unecessary disk I/O in
streaming applications.

best regards, Wu Fengguang


diff -Naur linux-2.6.4-rc2/mm/fadvise.c linux-2.6.4-rc2_fadvise_fix/mm/fadvise.c
--- linux-2.6.4-rc2/mm/fadvise.c 2004-02-18 03:57:30.000000000 +0000
+++ linux-2.6.4-rc2_fadvise_fix/mm/fadvise.c 2004-03-08 12:20:06.000000000 +0000
@@ -66,8 +66,7 @@
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;
+ end_index = ((offset + len) >> PAGE_CACHE_SHIFT) - 1;
invalidate_mapping_pages(mapping, start_index, end_index);
break;
default:
diff -Naur linux-2.6.4-rc2/mm/truncate.c linux-2.6.4-rc2_fadvise_fix/mm/truncate.c
--- linux-2.6.4-rc2/mm/truncate.c 2004-02-18 03:59:34.000000000 +0000
+++ linux-2.6.4-rc2_fadvise_fix/mm/truncate.c 2004-03-08 12:20:06.000000000 +0000
@@ -219,6 +219,8 @@
ret += invalidate_complete_page(mapping, page);
unlock:
unlock_page(page);
+ if (next > end)
+ break;
}
pagevec_release(&pvec);
cond_resched();
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/