aboutsummaryrefslogtreecommitdiffstats
path: root/mm/filemap.c
diff options
context:
space:
mode:
Diffstat (limited to 'mm/filemap.c')
-rw-r--r--mm/filemap.c31
1 files changed, 21 insertions, 10 deletions
diff --git a/mm/filemap.c b/mm/filemap.c
index 9c7334bafda8..648f2c0c8e18 100644
--- a/mm/filemap.c
+++ b/mm/filemap.c
@@ -2069,7 +2069,7 @@ generic_file_buffered_write(struct kiocb *iocb, const struct iovec *iov,
2069{ 2069{
2070 struct file *file = iocb->ki_filp; 2070 struct file *file = iocb->ki_filp;
2071 struct address_space * mapping = file->f_mapping; 2071 struct address_space * mapping = file->f_mapping;
2072 struct address_space_operations *a_ops = mapping->a_ops; 2072 const struct address_space_operations *a_ops = mapping->a_ops;
2073 struct inode *inode = mapping->host; 2073 struct inode *inode = mapping->host;
2074 long status = 0; 2074 long status = 0;
2075 struct page *page; 2075 struct page *page;
@@ -2095,14 +2095,21 @@ generic_file_buffered_write(struct kiocb *iocb, const struct iovec *iov,
2095 do { 2095 do {
2096 unsigned long index; 2096 unsigned long index;
2097 unsigned long offset; 2097 unsigned long offset;
2098 unsigned long maxlen;
2099 size_t copied; 2098 size_t copied;
2100 2099
2101 offset = (pos & (PAGE_CACHE_SIZE -1)); /* Within page */ 2100 offset = (pos & (PAGE_CACHE_SIZE -1)); /* Within page */
2102 index = pos >> PAGE_CACHE_SHIFT; 2101 index = pos >> PAGE_CACHE_SHIFT;
2103 bytes = PAGE_CACHE_SIZE - offset; 2102 bytes = PAGE_CACHE_SIZE - offset;
2104 if (bytes > count) 2103
2105 bytes = count; 2104 /* Limit the size of the copy to the caller's write size */
2105 bytes = min(bytes, count);
2106
2107 /*
2108 * Limit the size of the copy to that of the current segment,
2109 * because fault_in_pages_readable() doesn't know how to walk
2110 * segments.
2111 */
2112 bytes = min(bytes, cur_iov->iov_len - iov_base);
2106 2113
2107 /* 2114 /*
2108 * Bring in the user page that we will copy from _first_. 2115 * Bring in the user page that we will copy from _first_.
@@ -2110,10 +2117,7 @@ generic_file_buffered_write(struct kiocb *iocb, const struct iovec *iov,
2110 * same page as we're writing to, without it being marked 2117 * same page as we're writing to, without it being marked
2111 * up-to-date. 2118 * up-to-date.
2112 */ 2119 */
2113 maxlen = cur_iov->iov_len - iov_base; 2120 fault_in_pages_readable(buf, bytes);
2114 if (maxlen > bytes)
2115 maxlen = bytes;
2116 fault_in_pages_readable(buf, maxlen);
2117 2121
2118 page = __grab_cache_page(mapping,index,&cached_page,&lru_pvec); 2122 page = __grab_cache_page(mapping,index,&cached_page,&lru_pvec);
2119 if (!page) { 2123 if (!page) {
@@ -2121,6 +2125,12 @@ generic_file_buffered_write(struct kiocb *iocb, const struct iovec *iov,
2121 break; 2125 break;
2122 } 2126 }
2123 2127
2128 if (unlikely(bytes == 0)) {
2129 status = 0;
2130 copied = 0;
2131 goto zero_length_segment;
2132 }
2133
2124 status = a_ops->prepare_write(file, page, offset, offset+bytes); 2134 status = a_ops->prepare_write(file, page, offset, offset+bytes);
2125 if (unlikely(status)) { 2135 if (unlikely(status)) {
2126 loff_t isize = i_size_read(inode); 2136 loff_t isize = i_size_read(inode);
@@ -2150,7 +2160,8 @@ generic_file_buffered_write(struct kiocb *iocb, const struct iovec *iov,
2150 page_cache_release(page); 2160 page_cache_release(page);
2151 continue; 2161 continue;
2152 } 2162 }
2153 if (likely(copied > 0)) { 2163zero_length_segment:
2164 if (likely(copied >= 0)) {
2154 if (!status) 2165 if (!status)
2155 status = copied; 2166 status = copied;
2156 2167
@@ -2215,7 +2226,7 @@ __generic_file_aio_write_nolock(struct kiocb *iocb, const struct iovec *iov,
2215 unsigned long nr_segs, loff_t *ppos) 2226 unsigned long nr_segs, loff_t *ppos)
2216{ 2227{
2217 struct file *file = iocb->ki_filp; 2228 struct file *file = iocb->ki_filp;
2218 struct address_space * mapping = file->f_mapping; 2229 const struct address_space * mapping = file->f_mapping;
2219 size_t ocount; /* original count */ 2230 size_t ocount; /* original count */
2220 size_t count; /* after file limit checks */ 2231 size_t count; /* after file limit checks */
2221 struct inode *inode = mapping->host; 2232 struct inode *inode = mapping->host;