if (inode->i_size == 0 && !test_opt(inode->i_sb, NO_AUTO_DA_ALLOC))
ext4_set_inode_state(inode, EXT4_STATE_DA_ALLOC_CLOSE);
+ /* Wait all existing dio workers, newcomers will block on i_mutex */
+ ext4_inode_block_unlocked_dio(inode);
+ inode_dio_wait(inode);
+
if (ext4_has_inline_data(inode)) {
int has_inline = 1;
ext4_inline_data_truncate(inode, &has_inline);
if (has_inline)
- return;
+ goto out_resume;
}
if (ext4_test_inode_flag(inode, EXT4_INODE_EXTENTS))
handle = ext4_journal_start(inode, EXT4_HT_TRUNCATE, credits);
if (IS_ERR(handle)) {
ext4_std_error(inode->i_sb, PTR_ERR(handle));
- return;
+ goto out_resume;
}
if (inode->i_size & (inode->i_sb->s_blocksize - 1))
ext4_mark_inode_dirty(handle, inode);
ext4_journal_stop(handle);
+out_resume:
+ ext4_inode_resume_unlocked_dio(inode);
trace_ext4_truncate_exit(inode);
}