summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJan Kara <jack@suse.cz>2019-05-23 23:07:08 -0400
committerTheodore Ts'o <tytso@mit.edu>2019-05-23 23:07:08 -0400
commit82a25b027ca48d7ef197295846b352345853dfa8 (patch)
tree3966300c54590f2562ce3c9453ad22bf75db62e7
parent0a944e8a6c66ca04c7afbaa17e22bf208a8b37f0 (diff)
downloadlinux-82a25b027ca48d7ef197295846b352345853dfa8.tar.gz
linux-82a25b027ca48d7ef197295846b352345853dfa8.tar.bz2
linux-82a25b027ca48d7ef197295846b352345853dfa8.zip
ext4: wait for outstanding dio during truncate in nojournal mode
We didn't wait for outstanding direct IO during truncate in nojournal mode (as we skip orphan handling in that case). This can lead to fs corruption or stale data exposure if truncate ends up freeing blocks and these get reallocated before direct IO finishes. Fix the condition determining whether the wait is necessary. CC: stable@vger.kernel.org Fixes: 1c9114f9c0f1 ("ext4: serialize unlocked dio reads with truncate") Reviewed-by: Ira Weiny <ira.weiny@intel.com> Signed-off-by: Jan Kara <jack@suse.cz> Signed-off-by: Theodore Ts'o <tytso@mit.edu>
-rw-r--r--fs/ext4/inode.c21
1 files changed, 9 insertions, 12 deletions
diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c
index 82298c63ea6d..9bcb7f2b86dd 100644
--- a/fs/ext4/inode.c
+++ b/fs/ext4/inode.c
@@ -5630,20 +5630,17 @@ int ext4_setattr(struct dentry *dentry, struct iattr *attr)
goto err_out;
}
}
- if (!shrink)
+ if (!shrink) {
pagecache_isize_extended(inode, oldsize, inode->i_size);
-
- /*
- * Blocks are going to be removed from the inode. Wait
- * for dio in flight. Temporarily disable
- * dioread_nolock to prevent livelock.
- */
- if (orphan) {
- if (!ext4_should_journal_data(inode)) {
- inode_dio_wait(inode);
- } else
- ext4_wait_for_tail_page_commit(inode);
+ } else {
+ /*
+ * Blocks are going to be removed from the inode. Wait
+ * for dio in flight.
+ */
+ inode_dio_wait(inode);
}
+ if (orphan && ext4_should_journal_data(inode))
+ ext4_wait_for_tail_page_commit(inode);
down_write(&EXT4_I(inode)->i_mmap_sem);
rc = ext4_break_layouts(inode);