summaryrefslogtreecommitdiff
path: root/mm/filemap.c
diff options
context:
space:
mode:
authorMartin Schwidefsky <schwidefsky@de.ibm.com>2005-06-06 13:35:54 -0700
committerLinus Torvalds <torvalds@ppc970.osdl.org>2005-06-06 14:42:23 -0700
commita51171816826b074828fa96cb6ef60fc3b13631a (patch)
treee3c6f7a9852d45e9fdec75d7c71548ba404625e7 /mm/filemap.c
parent7cef5677ef3a8084f2588ce0a129dc95d65161f6 (diff)
downloadkernel-common-a51171816826b074828fa96cb6ef60fc3b13631a.tar.gz
kernel-common-a51171816826b074828fa96cb6ef60fc3b13631a.tar.bz2
kernel-common-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.c8
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;
}
}
}