On Thu 31-01-19 23:42:19, Theodore Ts'o wrote: > This reverts commit ad211f3e94b314a910d4af03178a0b52a7d1ee0a. > > As Jan Kara pointed out, this change was unsafe since it means we lose > the call to sync_mapping_buffers() in the nojournal case. The > original point of the commit was avoid taking the inode mutex (since > it causes a lockdep warning in generic/113); but we need the mutex in > order to call sync_mapping_buffers(). Actually, I don't think sync_mapping_buffers() needs inode mutex (i_rwsem these days). It uses blkdev_mapping->private_lock for synchronization of operations on the list of buffers and fsync_buffers_list() seems to be pretty careful about races with mark_buffer_dirty_inode(). So why do you think we need i_rwsem? > The real fix to this problem was discussed here: > > https://lore.kernel.org/lkml/20181025150540.259281-4-bvanassche@xxxxxxx > > The proposed patch was to fix a syzbot complaint, but the problem can > also demonstrated via "kvm-xfstests -c nojournal generic/113". > Multiple solutions were discused in the e-mail thread, but none have > landed in the kernel as of this writing. Anyway, commit > ad211f3e94b314 is absolutely the wrong way to suppress the lockdep, so > revert it. > > Fixes: ad211f3e94b314a910d4af03178a0b52a7d1ee0a ("ext4: use ext4_write_inode() when fsyncing w/o a journal") > Signed-off-by: Theodore Ts'o <tytso@xxxxxxx> > Reported: Jan Kara <jack@xxxxxxx> So if you decide to go via a safe way of reverting the change, I'm fine with that so feel free to add: Reviewed-by: Jan Kara <jack@xxxxxxx> Honza > --- > fs/ext4/fsync.c | 13 ++++--------- > 1 file changed, 4 insertions(+), 9 deletions(-) > > diff --git a/fs/ext4/fsync.c b/fs/ext4/fsync.c > index 712f00995390..5508baa11bb6 100644 > --- a/fs/ext4/fsync.c > +++ b/fs/ext4/fsync.c > @@ -116,16 +116,8 @@ int ext4_sync_file(struct file *file, loff_t start, loff_t end, int datasync) > goto out; > } > > - ret = file_write_and_wait_range(file, start, end); > - if (ret) > - return ret; > - > if (!journal) { > - struct writeback_control wbc = { > - .sync_mode = WB_SYNC_ALL > - }; > - > - ret = ext4_write_inode(inode, &wbc); > + ret = __generic_file_fsync(file, start, end, datasync); > if (!ret) > ret = ext4_sync_parent(inode); > if (test_opt(inode->i_sb, BARRIER)) > @@ -133,6 +125,9 @@ int ext4_sync_file(struct file *file, loff_t start, loff_t end, int datasync) > goto out; > } > > + ret = file_write_and_wait_range(file, start, end); > + if (ret) > + return ret; > /* > * data=writeback,ordered: > * The caller's filemap_fdatawrite()/wait will sync the data. > -- > 2.19.1 > -- Jan Kara <jack@xxxxxxxx> SUSE Labs, CR