ext4: Use generic_buffers_fsync_noflush() implementation
authorRitesh Harjani (IBM) <ritesh.list@gmail.com>
Fri, 21 Apr 2023 09:46:13 +0000 (15:16 +0530)
committerJan Kara <jack@suse.cz>
Tue, 16 May 2023 09:32:42 +0000 (11:32 +0200)
ext4 when got converted to iomap for dio, it copied __generic_file_fsync
implementation to avoid taking inode_lock in order to avoid any deadlock
(since iomap takes an inode_lock while calling generic_write_sync()).

The previous patch already added generic_buffers_fsync*() which does not
take any inode_lock(). Hence kill the redundant code and use
generic_buffers_fsync_noflush() function instead.

Tested-by: Disha Goel <disgoel@linux.ibm.com>
Signed-off-by: Ritesh Harjani (IBM) <ritesh.list@gmail.com>
Signed-off-by: Jan Kara <jack@suse.cz>
Message-Id: <b43d4bb4403061ed86510c9587673e30a461ba14.1682069716.git.ritesh.list@gmail.com>

fs/ext4/fsync.c

index f65fdb2..9cd71d7 100644 (file)
@@ -28,6 +28,7 @@
 #include <linux/sched.h>
 #include <linux/writeback.h>
 #include <linux/blkdev.h>
+#include <linux/buffer_head.h>
 
 #include "ext4.h"
 #include "ext4_jbd2.h"
@@ -78,21 +79,13 @@ static int ext4_sync_parent(struct inode *inode)
        return ret;
 }
 
-static int ext4_fsync_nojournal(struct inode *inode, bool datasync,
-                               bool *needs_barrier)
+static int ext4_fsync_nojournal(struct file *file, loff_t start, loff_t end,
+                               int datasync, bool *needs_barrier)
 {
-       int ret, err;
-
-       ret = sync_mapping_buffers(inode->i_mapping);
-       if (!(inode->i_state & I_DIRTY_ALL))
-               return ret;
-       if (datasync && !(inode->i_state & I_DIRTY_DATASYNC))
-               return ret;
-
-       err = sync_inode_metadata(inode, 1);
-       if (!ret)
-               ret = err;
+       struct inode *inode = file->f_inode;
+       int ret;
 
+       ret = generic_buffers_fsync_noflush(file, start, end, datasync);
        if (!ret)
                ret = ext4_sync_parent(inode);
        if (test_opt(inode->i_sb, BARRIER))
@@ -148,6 +141,14 @@ int ext4_sync_file(struct file *file, loff_t start, loff_t end, int datasync)
                goto out;
        }
 
+       if (!sbi->s_journal) {
+               ret = ext4_fsync_nojournal(file, start, end, datasync,
+                                          &needs_barrier);
+               if (needs_barrier)
+                       goto issue_flush;
+               goto out;
+       }
+
        ret = file_write_and_wait_range(file, start, end);
        if (ret)
                goto out;
@@ -157,11 +158,9 @@ int ext4_sync_file(struct file *file, loff_t start, loff_t end, int datasync)
         *  Metadata is in the journal, we wait for proper transaction to
         *  commit here.
         */
-       if (!sbi->s_journal)
-               ret = ext4_fsync_nojournal(inode, datasync, &needs_barrier);
-       else
-               ret = ext4_fsync_journal(inode, datasync, &needs_barrier);
+       ret = ext4_fsync_journal(inode, datasync, &needs_barrier);
 
+issue_flush:
        if (needs_barrier) {
                err = blkdev_issue_flush(inode->i_sb->s_bdev);
                if (!ret)