Skip to content

Commit

Permalink
[JFFS2] Fix return value from jffs2_write_end()
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Nick Piggin authored and David Woodhouse committed Oct 22, 2007
1 parent c21f900 commit 2a754b5
Showing 1 changed file with 4 additions and 7 deletions.
11 changes: 4 additions & 7 deletions fs/jffs2/file.c
Original file line number Diff line number Diff line change
Expand Up @@ -255,7 +255,7 @@ static int jffs2_write_end(struct file *filp, struct address_space *mapping,
_whole_ page. This helps to reduce the number of
nodes in files which have many short writes, like
syslog files. */
start = aligned_start = 0;
aligned_start = 0;
}

ri = jffs2_alloc_raw_inode();
Expand Down Expand Up @@ -291,14 +291,11 @@ static int jffs2_write_end(struct file *filp, struct address_space *mapping,
}

/* Adjust writtenlen for the padding we did, so we don't confuse our caller */
if (writtenlen < (start&3))
writtenlen = 0;
else
writtenlen -= (start&3);
writtenlen -= min(writtenlen, (start - aligned_start));

if (writtenlen) {
if (inode->i_size < (pg->index << PAGE_CACHE_SHIFT) + start + writtenlen) {
inode->i_size = (pg->index << PAGE_CACHE_SHIFT) + start + writtenlen;
if (inode->i_size < pos + writtenlen) {
inode->i_size = pos + writtenlen;
inode->i_blocks = (inode->i_size + 511) >> 9;

inode->i_ctime = inode->i_mtime = ITIME(je32_to_cpu(ri->ctime));
Expand Down

0 comments on commit 2a754b5

Please sign in to comment.