Commit 3db29f35 authored by Zach Brown's avatar Zach Brown Committed by Linus Torvalds

[PATCH] only unmap what intersects a direct_IO op

Now that we're only invalidating the pages that intersected a direct IO
write we might as well only unmap the intersecting bytes as well.  This
passed a light fsx load with page cache, direct, and mmap IO.
Signed-off-by: default avatarZach Brown <zach.brown@oracle.com>
Signed-off-by: default avatarAndrew Morton <akpm@osdl.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@osdl.org>
parent daf70db8
...@@ -2285,22 +2285,26 @@ generic_file_direct_IO(int rw, struct kiocb *iocb, const struct iovec *iov, ...@@ -2285,22 +2285,26 @@ generic_file_direct_IO(int rw, struct kiocb *iocb, const struct iovec *iov,
struct file *file = iocb->ki_filp; struct file *file = iocb->ki_filp;
struct address_space *mapping = file->f_mapping; struct address_space *mapping = file->f_mapping;
ssize_t retval; ssize_t retval;
size_t write_len = 0;
/* /*
* If it's a write, unmap all mmappings of the file up-front. This * If it's a write, unmap all mmappings of the file up-front. This
* will cause any pte dirty bits to be propagated into the pageframes * will cause any pte dirty bits to be propagated into the pageframes
* for the subsequent filemap_write_and_wait(). * for the subsequent filemap_write_and_wait().
*/ */
if (rw == WRITE && mapping_mapped(mapping)) if (rw == WRITE) {
unmap_mapping_range(mapping, 0, -1, 0); write_len = iov_length(iov, nr_segs);
if (mapping_mapped(mapping))
unmap_mapping_range(mapping, offset, write_len, 0);
}
retval = filemap_write_and_wait(mapping); retval = filemap_write_and_wait(mapping);
if (retval == 0) { if (retval == 0) {
retval = mapping->a_ops->direct_IO(rw, iocb, iov, retval = mapping->a_ops->direct_IO(rw, iocb, iov,
offset, nr_segs); offset, nr_segs);
if (rw == WRITE && mapping->nrpages) { if (rw == WRITE && mapping->nrpages) {
pgoff_t end = (offset + iov_length(iov, nr_segs) - 1) pgoff_t end = (offset + write_len - 1)
>> PAGE_CACHE_SHIFT; >> PAGE_CACHE_SHIFT;
int err = invalidate_inode_pages2_range(mapping, int err = invalidate_inode_pages2_range(mapping,
offset >> PAGE_CACHE_SHIFT, end); offset >> PAGE_CACHE_SHIFT, end);
if (err) if (err)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment