aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorNick Piggin <nickpiggin@yahoo.com.au>2007-10-19 03:16:53 -0400
committerDavid Woodhouse <dwmw2@infradead.org>2007-10-22 05:24:44 -0400
commit2a754b51aacb122cec25c849e3cf7f5503cc3ec6 (patch)
tree679a7b65a8a031904d2098d4133de07045ee0ca6 /fs
parentc21f900cb8817009930e672d22a5b91e5b706351 (diff)
[JFFS2] Fix return value from jffs2_write_end()
jffs2_write_end() is sometimes passing back a "written" length greater than the length we passed into it, leading to a BUG at mm/filemap.c:1749 when used with unionfs. It happens because we actually write more than was requested, to reduce log fragmentation. These "longer" writes are fine, but they shouldn't get propagated back to the vm/vfs. Signed-off-by: Nick Piggin <npiggin@suse.de> Signed-off-by: David Woodhouse <dwmw2@infradead.org>
Diffstat (limited to 'fs')
-rw-r--r--fs/jffs2/file.c11
1 files changed, 4 insertions, 7 deletions
diff --git a/fs/jffs2/file.c b/fs/jffs2/file.c
index 023a17539dd4..f9c5dd6f4b64 100644
--- a/fs/jffs2/file.c
+++ b/fs/jffs2/file.c
@@ -255,7 +255,7 @@ static int jffs2_write_end(struct file *filp, struct address_space *mapping,
255 _whole_ page. This helps to reduce the number of 255 _whole_ page. This helps to reduce the number of
256 nodes in files which have many short writes, like 256 nodes in files which have many short writes, like
257 syslog files. */ 257 syslog files. */
258 start = aligned_start = 0; 258 aligned_start = 0;
259 } 259 }
260 260
261 ri = jffs2_alloc_raw_inode(); 261 ri = jffs2_alloc_raw_inode();
@@ -291,14 +291,11 @@ static int jffs2_write_end(struct file *filp, struct address_space *mapping,
291 } 291 }
292 292
293 /* Adjust writtenlen for the padding we did, so we don't confuse our caller */ 293 /* Adjust writtenlen for the padding we did, so we don't confuse our caller */
294 if (writtenlen < (start&3)) 294 writtenlen -= min(writtenlen, (start - aligned_start));
295 writtenlen = 0;
296 else
297 writtenlen -= (start&3);
298 295
299 if (writtenlen) { 296 if (writtenlen) {
300 if (inode->i_size < (pg->index << PAGE_CACHE_SHIFT) + start + writtenlen) { 297 if (inode->i_size < pos + writtenlen) {
301 inode->i_size = (pg->index << PAGE_CACHE_SHIFT) + start + writtenlen; 298 inode->i_size = pos + writtenlen;
302 inode->i_blocks = (inode->i_size + 511) >> 9; 299 inode->i_blocks = (inode->i_size + 511) >> 9;
303 300
304 inode->i_ctime = inode->i_mtime = ITIME(je32_to_cpu(ri->ctime)); 301 inode->i_ctime = inode->i_mtime = ITIME(je32_to_cpu(ri->ctime));