1 ext4: block direct I/O writes during ext4_truncate
3 Just as in ext4_punch_hole() it is important that we block DIO writes
4 while the truncate is proceeding, since during the overwriting DIO
5 write, we drop i_mutex, which means a truncate could start while the
6 Direct I/O operation is still in progress.
8 Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
9 Cc: stable@vger.kernel.org
11 fs/ext4/inode.c | 10 ++++++++--
12 1 file changed, 8 insertions(+), 2 deletions(-)
14 diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c
15 index 98b9bff..3c5edf2 100644
18 @@ -3659,12 +3659,16 @@ void ext4_truncate(struct inode *inode)
19 if (inode->i_size == 0 && !test_opt(inode->i_sb, NO_AUTO_DA_ALLOC))
20 ext4_set_inode_state(inode, EXT4_STATE_DA_ALLOC_CLOSE);
22 + /* Wait all existing dio workers, newcomers will block on i_mutex */
23 + ext4_inode_block_unlocked_dio(inode);
24 + inode_dio_wait(inode);
26 if (ext4_has_inline_data(inode)) {
29 ext4_inline_data_truncate(inode, &has_inline);
35 if (ext4_test_inode_flag(inode, EXT4_INODE_EXTENTS))
36 @@ -3675,7 +3679,7 @@ void ext4_truncate(struct inode *inode)
37 handle = ext4_journal_start(inode, EXT4_HT_TRUNCATE, credits);
39 ext4_std_error(inode->i_sb, PTR_ERR(handle));
44 if (inode->i_size & (inode->i_sb->s_blocksize - 1))
45 @@ -3722,6 +3726,8 @@ out_stop:
46 ext4_mark_inode_dirty(handle, inode);
47 ext4_journal_stop(handle);
50 + ext4_inode_resume_unlocked_dio(inode);
51 trace_ext4_truncate_exit(inode);