[PATCH] broken fault_in_pages_readable call in generic_file_buffered_write()
authorMartin Schwidefsky <schwidefsky@de.ibm.com>
Mon, 6 Jun 2005 20:35:54 +0000 (13:35 -0700)
committerLinus Torvalds <torvalds@ppc970.osdl.org>
Mon, 6 Jun 2005 21:42:23 +0000 (14:42 -0700)
fault_in_pages_readable() is being passed an incorrect `end' address, which
can result in writes accidentally faulting in pages which will not be affected
by the write() call.

Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
mm/filemap.c

index 1d33fec..4a2fee2 100644 (file)
@@ -1968,6 +1968,7 @@ generic_file_buffered_write(struct kiocb *iocb, const struct iovec *iov,
        do {
                unsigned long index;
                unsigned long offset;
+               unsigned long maxlen;
                size_t copied;
 
                offset = (pos & (PAGE_CACHE_SIZE -1)); /* Within page */
@@ -1982,7 +1983,10 @@ generic_file_buffered_write(struct kiocb *iocb, const struct iovec *iov,
                 * same page as we're writing to, without it being marked
                 * up-to-date.
                 */
-               fault_in_pages_readable(buf, bytes);
+               maxlen = cur_iov->iov_len - iov_base;
+               if (maxlen > bytes)
+                       maxlen = bytes;
+               fault_in_pages_readable(buf, maxlen);
 
                page = __grab_cache_page(mapping,index,&cached_page,&lru_pvec);
                if (!page) {
@@ -2024,6 +2028,8 @@ generic_file_buffered_write(struct kiocb *iocb, const struct iovec *iov,
                                        filemap_set_next_iovec(&cur_iov,
                                                        &iov_base, status);
                                        buf = cur_iov->iov_base + iov_base;
+                               } else {
+                                       iov_base += status;
                                }
                        }
                }