add jbd2 speedup patches
[ext4-patch-queue.git] / avoid-exposure-stale-data-in-ext4_punch_hole
blob427e3468020eb0d10dc037e818798b5776cbaeb3
1 ext4: avoid exposure of stale data in ext4_punch_hole()
3 From: Maxim Patlasov <MPatlasov@parallels.com>
5 While handling punch-hole fallocate, it's useless to truncate page cache
6 before removing the range from extent tree (or block map in indirect case)
7 because page cache can be re-populated (by read-ahead or read(2) or mmap-ed
8 read) immediately after truncating page cache, but before updating extent
9 tree (or block map). In that case the user will see stale data even after
10 fallocate is completed.
12 Until the problem of data corruption resulting from pages backed by
13 already freed blocks is fully resolved, the simple thing we can do now
14 is to add another truncation of pagecache after punch hole is done.
16 Signed-off-by: Maxim Patlasov <mpatlasov@parallels.com>
17 Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
18 Reviewed-by: Jan Kara <jack@suse.cz>
19 ---
20  fs/ext4/inode.c | 6 ++++++
21  1 file changed, 6 insertions(+)
23 diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c
24 index 113458c..5324a38 100644
25 --- a/fs/ext4/inode.c
26 +++ b/fs/ext4/inode.c
27 @@ -3614,6 +3614,12 @@ int ext4_punch_hole(struct inode *inode, loff_t offset, loff_t length)
28         up_write(&EXT4_I(inode)->i_data_sem);
29         if (IS_SYNC(inode))
30                 ext4_handle_sync(handle);
32 +       /* Now release the pages again to reduce race window */
33 +       if (last_block_offset > first_block_offset)
34 +               truncate_pagecache_range(inode, first_block_offset,
35 +                                        last_block_offset);
37         inode->i_mtime = inode->i_ctime = ext4_current_time(inode);
38         ext4_mark_inode_dirty(handle, inode);
39  out_stop: