[JFFS2] Fix return value from jffs2_write_end()

Linux-MTD Mailing List linux-mtd at lists.infradead.org
Mon Oct 22 05:59:02 EDT 2007


Gitweb:     http://git.infradead.org/?p=mtd-2.6.git;a=commit;h=2a754b51aacb122cec25c849e3cf7f5503cc3ec6
Commit:     2a754b51aacb122cec25c849e3cf7f5503cc3ec6
Parent:     c21f900cb8817009930e672d22a5b91e5b706351
Author:     Nick Piggin <nickpiggin at yahoo.com.au>
AuthorDate: Fri Oct 19 17:16:53 2007 +1000
Committer:  David Woodhouse <dwmw2 at infradead.org>
CommitDate: Mon Oct 22 10:24:44 2007 +0100

    [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 at suse.de>
    Signed-off-by: David Woodhouse <dwmw2 at infradead.org>
---
 fs/jffs2/file.c |   11 ++++-------
 1 files changed, 4 insertions(+), 7 deletions(-)

diff --git a/fs/jffs2/file.c b/fs/jffs2/file.c
index 023a175..f9c5dd6 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,
 		   _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();
@@ -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));



More information about the linux-mtd-cvs mailing list