add patch discard-dirty-data-when-forgetting-unjournaled-buffer
[ext4-patch-queue.git] / revert-use-write_inode_for-fsyncing-wo-journal
blob863660aae7a674a8f4e28110855e08ba3b785ac4
1 Revert "ext4: use ext4_write_inode() when fsyncing w/o a journal"
3 This reverts commit ad211f3e94b314a910d4af03178a0b52a7d1ee0a.
5 As Jan Kara pointed out, this change was unsafe since it means we lose
6 the call to sync_mapping_buffers() in the nojournal case.  The
7 original point of the commit was avoid taking the inode mutex (since
8 it causes a lockdep warning in generic/113); but we need the mutex in
9 order to call sync_mapping_buffers().
11 The real fix to this problem was discussed here:
13 https://lore.kernel.org/lkml/20181025150540.259281-4-bvanassche@acm.org
15 The proposed patch was to fix a syzbot complaint, but the problem can
16 also demonstrated via "kvm-xfstests -c nojournal generic/113".
17 Multiple solutions were discused in the e-mail thread, but none have
18 landed in the kernel as of this writing.  Anyway, commit
19 ad211f3e94b314 is absolutely the wrong way to suppress the lockdep, so
20 revert it.
22 Fixes: ad211f3e94b314a910d4af03178a0b52a7d1ee0a ("ext4: use ext4_write_inode() when fsyncing w/o a journal")
23 Signed-off-by: Theodore Ts'o <tytso@mit.edu>
24 Reported: Jan Kara <jack@suse.cz>
25 ---
26  fs/ext4/fsync.c | 13 ++++---------
27  1 file changed, 4 insertions(+), 9 deletions(-)
29 diff --git a/fs/ext4/fsync.c b/fs/ext4/fsync.c
30 index 712f00995390..5508baa11bb6 100644
31 --- a/fs/ext4/fsync.c
32 +++ b/fs/ext4/fsync.c
33 @@ -116,16 +116,8 @@ int ext4_sync_file(struct file *file, loff_t start, loff_t end, int datasync)
34                 goto out;
35         }
37 -       ret = file_write_and_wait_range(file, start, end);
38 -       if (ret)
39 -               return ret;
41         if (!journal) {
42 -               struct writeback_control wbc = {
43 -                       .sync_mode = WB_SYNC_ALL
44 -               };
46 -               ret = ext4_write_inode(inode, &wbc);
47 +               ret = __generic_file_fsync(file, start, end, datasync);
48                 if (!ret)
49                         ret = ext4_sync_parent(inode);
50                 if (test_opt(inode->i_sb, BARRIER))
51 @@ -133,6 +125,9 @@ int ext4_sync_file(struct file *file, loff_t start, loff_t end, int datasync)
52                 goto out;
53         }
55 +       ret = file_write_and_wait_range(file, start, end);
56 +       if (ret)
57 +               return ret;
58         /*
59          * data=writeback,ordered:
60          *  The caller's filemap_fdatawrite()/wait will sync the data.
61 -- 
62 2.19.1