aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRoss Zwisler <ross.zwisler@linux.intel.com>2016-02-27 14:01:13 -0500
committerTheodore Ts'o <tytso@mit.edu>2016-02-27 14:01:16 -0500
commit1e9d180ba39f42e8ca4a808baef3a3ef034b1c2c (patch)
tree130440fffa2025bff83c906f797afbb395529e00
parent74dae4278546b897eb81784fdfcce872ddd8b2b8 (diff)
ext2, ext4: fix issue with missing journal entry in ext4_dax_mkwrite()
As it is currently written ext4_dax_mkwrite() assumes that the call into __dax_mkwrite() will not have to do a block allocation so it doesn't create a journal entry. For a read that creates a zero page to cover a hole followed by a write that actually allocates storage this is incorrect. The ext4_dax_mkwrite() -> __dax_mkwrite() -> __dax_fault() path calls get_blocks() to allocate storage. Fix this by having the ->page_mkwrite fault handler call ext4_dax_fault() as this function already has all the logic needed to allocate a journal entry and call __dax_fault(). Also update the ext2 fault handlers in this same way to remove duplicate code and keep the logic between ext2 and ext4 the same. Reviewed-by: Jan Kara <jack@suse.cz> Signed-off-by: Ross Zwisler <ross.zwisler@linux.intel.com> Signed-off-by: Theodore Ts'o <tytso@mit.edu>
-rw-r--r--fs/ext2/file.c19
-rw-r--r--fs/ext4/file.c19
2 files changed, 3 insertions, 35 deletions
diff --git a/fs/ext2/file.c b/fs/ext2/file.c
index 2c88d683cd91..c1400b109805 100644
--- a/fs/ext2/file.c
+++ b/fs/ext2/file.c
@@ -80,23 +80,6 @@ static int ext2_dax_pmd_fault(struct vm_area_struct *vma, unsigned long addr,
80 return ret; 80 return ret;
81} 81}
82 82
83static int ext2_dax_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf)
84{
85 struct inode *inode = file_inode(vma->vm_file);
86 struct ext2_inode_info *ei = EXT2_I(inode);
87 int ret;
88
89 sb_start_pagefault(inode->i_sb);
90 file_update_time(vma->vm_file);
91 down_read(&ei->dax_sem);
92
93 ret = __dax_mkwrite(vma, vmf, ext2_get_block, NULL);
94
95 up_read(&ei->dax_sem);
96 sb_end_pagefault(inode->i_sb);
97 return ret;
98}
99
100static int ext2_dax_pfn_mkwrite(struct vm_area_struct *vma, 83static int ext2_dax_pfn_mkwrite(struct vm_area_struct *vma,
101 struct vm_fault *vmf) 84 struct vm_fault *vmf)
102{ 85{
@@ -124,7 +107,7 @@ static int ext2_dax_pfn_mkwrite(struct vm_area_struct *vma,
124static const struct vm_operations_struct ext2_dax_vm_ops = { 107static const struct vm_operations_struct ext2_dax_vm_ops = {
125 .fault = ext2_dax_fault, 108 .fault = ext2_dax_fault,
126 .pmd_fault = ext2_dax_pmd_fault, 109 .pmd_fault = ext2_dax_pmd_fault,
127 .page_mkwrite = ext2_dax_mkwrite, 110 .page_mkwrite = ext2_dax_fault,
128 .pfn_mkwrite = ext2_dax_pfn_mkwrite, 111 .pfn_mkwrite = ext2_dax_pfn_mkwrite,
129}; 112};
130 113
diff --git a/fs/ext4/file.c b/fs/ext4/file.c
index 474f1a4d2ca8..4cd318f31cbe 100644
--- a/fs/ext4/file.c
+++ b/fs/ext4/file.c
@@ -262,23 +262,8 @@ static int ext4_dax_pmd_fault(struct vm_area_struct *vma, unsigned long addr,
262 return result; 262 return result;
263} 263}
264 264
265static int ext4_dax_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf)
266{
267 int err;
268 struct inode *inode = file_inode(vma->vm_file);
269
270 sb_start_pagefault(inode->i_sb);
271 file_update_time(vma->vm_file);
272 down_read(&EXT4_I(inode)->i_mmap_sem);
273 err = __dax_mkwrite(vma, vmf, ext4_dax_mmap_get_block, NULL);
274 up_read(&EXT4_I(inode)->i_mmap_sem);
275 sb_end_pagefault(inode->i_sb);
276
277 return err;
278}
279
280/* 265/*
281 * Handle write fault for VM_MIXEDMAP mappings. Similarly to ext4_dax_mkwrite() 266 * Handle write fault for VM_MIXEDMAP mappings. Similarly to ext4_dax_fault()
282 * handler we check for races agaist truncate. Note that since we cycle through 267 * handler we check for races agaist truncate. Note that since we cycle through
283 * i_mmap_sem, we are sure that also any hole punching that began before we 268 * i_mmap_sem, we are sure that also any hole punching that began before we
284 * were called is finished by now and so if it included part of the file we 269 * were called is finished by now and so if it included part of the file we
@@ -311,7 +296,7 @@ static int ext4_dax_pfn_mkwrite(struct vm_area_struct *vma,
311static const struct vm_operations_struct ext4_dax_vm_ops = { 296static const struct vm_operations_struct ext4_dax_vm_ops = {
312 .fault = ext4_dax_fault, 297 .fault = ext4_dax_fault,
313 .pmd_fault = ext4_dax_pmd_fault, 298 .pmd_fault = ext4_dax_pmd_fault,
314 .page_mkwrite = ext4_dax_mkwrite, 299 .page_mkwrite = ext4_dax_fault,
315 .pfn_mkwrite = ext4_dax_pfn_mkwrite, 300 .pfn_mkwrite = ext4_dax_pfn_mkwrite,
316}; 301};
317#else 302#else