diff options
author | Martin Schwidefsky <schwidefsky@de.ibm.com> | 2005-06-06 13:35:54 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@ppc970.osdl.org> | 2005-06-06 14:42:23 -0700 |
commit | a51171816826b074828fa96cb6ef60fc3b13631a (patch) | |
tree | e3c6f7a9852d45e9fdec75d7c71548ba404625e7 /mm/filemap.c | |
parent | 7cef5677ef3a8084f2588ce0a129dc95d65161f6 (diff) | |
download | lwn-a51171816826b074828fa96cb6ef60fc3b13631a.tar.gz lwn-a51171816826b074828fa96cb6ef60fc3b13631a.zip |
[PATCH] broken fault_in_pages_readable call in generic_file_buffered_write()
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>
Diffstat (limited to 'mm/filemap.c')
-rw-r--r-- | mm/filemap.c | 8 |
1 files changed, 7 insertions, 1 deletions
diff --git a/mm/filemap.c b/mm/filemap.c index 1d33fec7bac6..4a2fee2cb62b 100644 --- a/mm/filemap.c +++ b/mm/filemap.c @@ -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; } } } |