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) |
