diff options
author | Xiaoguang Wang <wangxg.fnst@cn.fujitsu.com> | 2015-02-12 23:00:17 -0500 |
---|---|---|
committer | Theodore Ts'o <tytso@mit.edu> | 2015-02-12 23:00:17 -0500 |
commit | 0572639ff66dcffe62d37adfe4c4576f9fc398f4 (patch) | |
tree | 98f88d5b347443c41a419576bfe5d79d2a08ba1d | |
parent | 2cb5cc8b09c939c77826635956c35995b15c9331 (diff) |
ext4: fix mmap data corruption in nodelalloc mode when blocksize < pagesize
Since commit 90a8020 and d6320cb, Jan Kara has fixed this issue partially.
This mmap data corruption still exists in nodelalloc mode, fix this.
Signed-off-by: Xiaoguang Wang <wangxg.fnst@cn.fujitsu.com>
Signed-off-by: Theodore Ts'o <tytso@mit.edu>
Reviewed-by: Jan Kara <jack@suse.cz>
-rw-r--r-- | fs/ext4/inode.c | 7 |
1 files changed, 7 insertions, 0 deletions
diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c index 5653fa42930b..4df6d01b762e 100644 --- a/fs/ext4/inode.c +++ b/fs/ext4/inode.c | |||
@@ -1007,6 +1007,7 @@ static int ext4_write_end(struct file *file, | |||
1007 | { | 1007 | { |
1008 | handle_t *handle = ext4_journal_current_handle(); | 1008 | handle_t *handle = ext4_journal_current_handle(); |
1009 | struct inode *inode = mapping->host; | 1009 | struct inode *inode = mapping->host; |
1010 | loff_t old_size = inode->i_size; | ||
1010 | int ret = 0, ret2; | 1011 | int ret = 0, ret2; |
1011 | int i_size_changed = 0; | 1012 | int i_size_changed = 0; |
1012 | 1013 | ||
@@ -1037,6 +1038,8 @@ static int ext4_write_end(struct file *file, | |||
1037 | unlock_page(page); | 1038 | unlock_page(page); |
1038 | page_cache_release(page); | 1039 | page_cache_release(page); |
1039 | 1040 | ||
1041 | if (old_size < pos) | ||
1042 | pagecache_isize_extended(inode, old_size, pos); | ||
1040 | /* | 1043 | /* |
1041 | * Don't mark the inode dirty under page lock. First, it unnecessarily | 1044 | * Don't mark the inode dirty under page lock. First, it unnecessarily |
1042 | * makes the holding time of page lock longer. Second, it forces lock | 1045 | * makes the holding time of page lock longer. Second, it forces lock |
@@ -1078,6 +1081,7 @@ static int ext4_journalled_write_end(struct file *file, | |||
1078 | { | 1081 | { |
1079 | handle_t *handle = ext4_journal_current_handle(); | 1082 | handle_t *handle = ext4_journal_current_handle(); |
1080 | struct inode *inode = mapping->host; | 1083 | struct inode *inode = mapping->host; |
1084 | loff_t old_size = inode->i_size; | ||
1081 | int ret = 0, ret2; | 1085 | int ret = 0, ret2; |
1082 | int partial = 0; | 1086 | int partial = 0; |
1083 | unsigned from, to; | 1087 | unsigned from, to; |
@@ -1110,6 +1114,9 @@ static int ext4_journalled_write_end(struct file *file, | |||
1110 | unlock_page(page); | 1114 | unlock_page(page); |
1111 | page_cache_release(page); | 1115 | page_cache_release(page); |
1112 | 1116 | ||
1117 | if (old_size < pos) | ||
1118 | pagecache_isize_extended(inode, old_size, pos); | ||
1119 | |||
1113 | if (size_changed) { | 1120 | if (size_changed) { |
1114 | ret2 = ext4_mark_inode_dirty(handle, inode); | 1121 | ret2 = ext4_mark_inode_dirty(handle, inode); |
1115 | if (!ret) | 1122 | if (!ret) |