[PATCH] generic_file_buffered_write fixes
akpm@osdl.org [Sun, 1 May 2005 15:58:35 +0000 (08:58 -0700)]
Anton Altaparmakov <aia21@cam.ac.uk> points out:

- It calls fault_in_pages_readable() which is completely bogus if @nr_segs >
  1.  It needs to be replaced by a to be written
  "fault_in_pages_readable_iovec()".

- It increments @buf even in the iovec case thus @buf can point to random
  memory really quickly (in the iovec case) and then it calls
  fault_in_pages_readable() on this random memory.

Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>

mm/filemap.c

index 93595c3..9b74674 100644 (file)
@@ -1949,7 +1949,7 @@ generic_file_buffered_write(struct kiocb *iocb, const struct iovec *iov,
                buf = iov->iov_base + written;
        else {
                filemap_set_next_iovec(&cur_iov, &iov_base, written);
-               buf = iov->iov_base + iov_base;
+               buf = cur_iov->iov_base + iov_base;
        }
 
        do {
@@ -2007,9 +2007,11 @@ generic_file_buffered_write(struct kiocb *iocb, const struct iovec *iov,
                                count -= status;
                                pos += status;
                                buf += status;
-                               if (unlikely(nr_segs > 1))
+                               if (unlikely(nr_segs > 1)) {
                                        filemap_set_next_iovec(&cur_iov,
                                                        &iov_base, status);
+                                       buf = cur_iov->iov_base + iov_base;
+                               }
                        }
                }
                if (unlikely(copied != bytes))