diff options
author | Ingo Molnar <mingo@kernel.org> | 2018-12-03 11:44:00 +0100 |
---|---|---|
committer | Ingo Molnar <mingo@kernel.org> | 2018-12-03 11:44:00 +0100 |
commit | 989a4222c13a3e148772730d362fceb0727852f5 (patch) | |
tree | c66538440a53713e8d3fc52db62e174c6966f831 /fs/btrfs/file.c | |
parent | e8da8794a7fd9eef1ec9a07f0d4897c68581c72b (diff) | |
parent | 2595646791c319cadfdbf271563aac97d0843dc7 (diff) |
Merge tag 'v4.20-rc5' into irq/core, to pick up fixes
Signed-off-by: Ingo Molnar <mingo@kernel.org>
Diffstat (limited to 'fs/btrfs/file.c')
-rw-r--r-- | fs/btrfs/file.c | 24 |
1 files changed, 24 insertions, 0 deletions
diff --git a/fs/btrfs/file.c b/fs/btrfs/file.c index a3c22e16509b..58e93bce3036 100644 --- a/fs/btrfs/file.c +++ b/fs/btrfs/file.c @@ -2089,6 +2089,30 @@ int btrfs_sync_file(struct file *file, loff_t start, loff_t end, int datasync) atomic_inc(&root->log_batch); /* + * Before we acquired the inode's lock, someone may have dirtied more + * pages in the target range. We need to make sure that writeback for + * any such pages does not start while we are logging the inode, because + * if it does, any of the following might happen when we are not doing a + * full inode sync: + * + * 1) We log an extent after its writeback finishes but before its + * checksums are added to the csum tree, leading to -EIO errors + * when attempting to read the extent after a log replay. + * + * 2) We can end up logging an extent before its writeback finishes. + * Therefore after the log replay we will have a file extent item + * pointing to an unwritten extent (and no data checksums as well). + * + * So trigger writeback for any eventual new dirty pages and then we + * wait for all ordered extents to complete below. + */ + ret = start_ordered_ops(inode, start, end); + if (ret) { + inode_unlock(inode); + goto out; + } + + /* * We have to do this here to avoid the priority inversion of waiting on * IO of a lower priority task while holding a transaciton open. */ |