<html><head><meta name="color-scheme" content="light dark"></head><body><pre style="word-wrap: break-word; white-space: pre-wrap;">
From: Zach Brown &lt;zach.brown@oracle.com&gt;

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: Zach Brown &lt;zach.brown@oracle.com&gt;
Signed-off-by: Andrew Morton &lt;akpm@osdl.org&gt;
---

 25-akpm/mm/filemap.c |   12 ++++++++----
 1 files changed, 8 insertions(+), 4 deletions(-)

diff -puN mm/filemap.c~only-unmap-what-intersects-a-direct_io-op mm/filemap.c
--- 25/mm/filemap.c~only-unmap-what-intersects-a-direct_io-op	2005-02-22 18:16:10.000000000 -0800
+++ 25-akpm/mm/filemap.c	2005-02-22 18:16:10.000000000 -0800
@@ -2285,22 +2285,26 @@ generic_file_direct_IO(int rw, struct ki
 	struct file *file = iocb-&gt;ki_filp;
 	struct address_space *mapping = file-&gt;f_mapping;
 	ssize_t retval;
+	size_t write_len = 0;
 
 	/*
 	 * 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
 	 * for the subsequent filemap_write_and_wait().
 	 */
-	if (rw == WRITE &amp;&amp; mapping_mapped(mapping))
-		unmap_mapping_range(mapping, 0, -1, 0);
+	if (rw == WRITE) {
+		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);
 	if (retval == 0) {
 		retval = mapping-&gt;a_ops-&gt;direct_IO(rw, iocb, iov,
 						offset, nr_segs);
 		if (rw == WRITE &amp;&amp; mapping-&gt;nrpages) {
-			pgoff_t end = (offset + iov_length(iov, nr_segs) - 1)
-				      &gt;&gt; PAGE_CACHE_SHIFT;
+			pgoff_t end = (offset + write_len - 1)
+						&gt;&gt; PAGE_CACHE_SHIFT;
 			int err = invalidate_inode_pages2_range(mapping,
 					offset &gt;&gt; PAGE_CACHE_SHIFT, end);
 			if (err)
_
</pre></body></html>