diff options
author | akpm@osdl.org <akpm@osdl.org> | 2005-05-01 19:58:35 +0400 |
---|---|---|
committer | Linus Torvalds <torvalds@ppc970.osdl.org> | 2005-05-01 19:58:35 +0400 |
commit | f021e9210185b46e41ec3a0e78ec1621e168eacb (patch) | |
tree | 5661ced2f5c69f737dcf7673db2ef6e852003d6d | |
parent | 69aa3f71580990f39e387d96ed1001d2f5fb04b1 (diff) | |
download | linux-f021e9210185b46e41ec3a0e78ec1621e168eacb.tar.xz |
[PATCH] generic_file_buffered_write fixes
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>
-rw-r--r-- | mm/filemap.c | 6 |
1 files changed, 4 insertions, 2 deletions
diff --git a/mm/filemap.c b/mm/filemap.c index 93595c327bbd..9b74674e36ad 100644 --- a/mm/filemap.c +++ b/mm/filemap.c @@ -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)) |