diff options
author | akpm@osdl.org <akpm@osdl.org> | 2005-05-01 11:58:35 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@ppc970.osdl.org> | 2005-05-01 11:58:35 -0400 |
commit | f021e9210185b46e41ec3a0e78ec1621e168eacb (patch) | |
tree | 5661ced2f5c69f737dcf7673db2ef6e852003d6d /mm | |
parent | 69aa3f71580990f39e387d96ed1001d2f5fb04b1 (diff) |
[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>
Diffstat (limited to 'mm')
-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, | |||
1949 | buf = iov->iov_base + written; | 1949 | buf = iov->iov_base + written; |
1950 | else { | 1950 | else { |
1951 | filemap_set_next_iovec(&cur_iov, &iov_base, written); | 1951 | filemap_set_next_iovec(&cur_iov, &iov_base, written); |
1952 | buf = iov->iov_base + iov_base; | 1952 | buf = cur_iov->iov_base + iov_base; |
1953 | } | 1953 | } |
1954 | 1954 | ||
1955 | do { | 1955 | do { |
@@ -2007,9 +2007,11 @@ generic_file_buffered_write(struct kiocb *iocb, const struct iovec *iov, | |||
2007 | count -= status; | 2007 | count -= status; |
2008 | pos += status; | 2008 | pos += status; |
2009 | buf += status; | 2009 | buf += status; |
2010 | if (unlikely(nr_segs > 1)) | 2010 | if (unlikely(nr_segs > 1)) { |
2011 | filemap_set_next_iovec(&cur_iov, | 2011 | filemap_set_next_iovec(&cur_iov, |
2012 | &iov_base, status); | 2012 | &iov_base, status); |
2013 | buf = cur_iov->iov_base + iov_base; | ||
2014 | } | ||
2013 | } | 2015 | } |
2014 | } | 2016 | } |
2015 | if (unlikely(copied != bytes)) | 2017 | if (unlikely(copied != bytes)) |