diff options
author | Martin Schwidefsky <schwidefsky@de.ibm.com> | 2005-06-06 16:35:54 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@ppc970.osdl.org> | 2005-06-06 17:42:23 -0400 |
commit | a51171816826b074828fa96cb6ef60fc3b13631a (patch) | |
tree | e3c6f7a9852d45e9fdec75d7c71548ba404625e7 | |
parent | 7cef5677ef3a8084f2588ce0a129dc95d65161f6 (diff) |
[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>
-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, | |||
1968 | do { | 1968 | do { |
1969 | unsigned long index; | 1969 | unsigned long index; |
1970 | unsigned long offset; | 1970 | unsigned long offset; |
1971 | unsigned long maxlen; | ||
1971 | size_t copied; | 1972 | size_t copied; |
1972 | 1973 | ||
1973 | offset = (pos & (PAGE_CACHE_SIZE -1)); /* Within page */ | 1974 | offset = (pos & (PAGE_CACHE_SIZE -1)); /* Within page */ |
@@ -1982,7 +1983,10 @@ generic_file_buffered_write(struct kiocb *iocb, const struct iovec *iov, | |||
1982 | * same page as we're writing to, without it being marked | 1983 | * same page as we're writing to, without it being marked |
1983 | * up-to-date. | 1984 | * up-to-date. |
1984 | */ | 1985 | */ |
1985 | fault_in_pages_readable(buf, bytes); | 1986 | maxlen = cur_iov->iov_len - iov_base; |
1987 | if (maxlen > bytes) | ||
1988 | maxlen = bytes; | ||
1989 | fault_in_pages_readable(buf, maxlen); | ||
1986 | 1990 | ||
1987 | page = __grab_cache_page(mapping,index,&cached_page,&lru_pvec); | 1991 | page = __grab_cache_page(mapping,index,&cached_page,&lru_pvec); |
1988 | if (!page) { | 1992 | if (!page) { |
@@ -2024,6 +2028,8 @@ generic_file_buffered_write(struct kiocb *iocb, const struct iovec *iov, | |||
2024 | filemap_set_next_iovec(&cur_iov, | 2028 | filemap_set_next_iovec(&cur_iov, |
2025 | &iov_base, status); | 2029 | &iov_base, status); |
2026 | buf = cur_iov->iov_base + iov_base; | 2030 | buf = cur_iov->iov_base + iov_base; |
2031 | } else { | ||
2032 | iov_base += status; | ||
2027 | } | 2033 | } |
2028 | } | 2034 | } |
2029 | } | 2035 | } |