aboutsummaryrefslogtreecommitdiffstats
path: root/fs/ext4/fsync.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/ext4/fsync.c')
-rw-r--r--fs/ext4/fsync.c18
1 files changed, 14 insertions, 4 deletions
diff --git a/fs/ext4/fsync.c b/fs/ext4/fsync.c
index 83cf6415f599..2b1531266ee2 100644
--- a/fs/ext4/fsync.c
+++ b/fs/ext4/fsync.c
@@ -44,18 +44,23 @@
44 * 44 *
45 * What we do is just kick off a commit and wait on it. This will snapshot the 45 * What we do is just kick off a commit and wait on it. This will snapshot the
46 * inode to disk. 46 * inode to disk.
47 *
48 * i_mutex lock is held when entering and exiting this function
47 */ 49 */
48 50
49int ext4_sync_file(struct file *file, struct dentry *dentry, int datasync) 51int ext4_sync_file(struct file *file, struct dentry *dentry, int datasync)
50{ 52{
51 struct inode *inode = dentry->d_inode; 53 struct inode *inode = dentry->d_inode;
52 journal_t *journal = EXT4_SB(inode->i_sb)->s_journal; 54 journal_t *journal = EXT4_SB(inode->i_sb)->s_journal;
53 int ret = 0; 55 int err, ret = 0;
54 56
55 J_ASSERT(ext4_journal_current_handle() == NULL); 57 J_ASSERT(ext4_journal_current_handle() == NULL);
56 58
57 trace_ext4_sync_file(file, dentry, datasync); 59 trace_ext4_sync_file(file, dentry, datasync);
58 60
61 ret = flush_aio_dio_completed_IO(inode);
62 if (ret < 0)
63 goto out;
59 /* 64 /*
60 * data=writeback: 65 * data=writeback:
61 * The caller's filemap_fdatawrite()/wait will sync the data. 66 * The caller's filemap_fdatawrite()/wait will sync the data.
@@ -79,6 +84,9 @@ int ext4_sync_file(struct file *file, struct dentry *dentry, int datasync)
79 goto out; 84 goto out;
80 } 85 }
81 86
87 if (!journal)
88 ret = sync_mapping_buffers(inode->i_mapping);
89
82 if (datasync && !(inode->i_state & I_DIRTY_DATASYNC)) 90 if (datasync && !(inode->i_state & I_DIRTY_DATASYNC))
83 goto out; 91 goto out;
84 92
@@ -91,10 +99,12 @@ int ext4_sync_file(struct file *file, struct dentry *dentry, int datasync)
91 .sync_mode = WB_SYNC_ALL, 99 .sync_mode = WB_SYNC_ALL,
92 .nr_to_write = 0, /* sys_fsync did this */ 100 .nr_to_write = 0, /* sys_fsync did this */
93 }; 101 };
94 ret = sync_inode(inode, &wbc); 102 err = sync_inode(inode, &wbc);
95 if (journal && (journal->j_flags & JBD2_BARRIER)) 103 if (ret == 0)
96 blkdev_issue_flush(inode->i_sb->s_bdev, NULL); 104 ret = err;
97 } 105 }
98out: 106out:
107 if (journal && (journal->j_flags & JBD2_BARRIER))
108 blkdev_issue_flush(inode->i_sb->s_bdev, NULL);
99 return ret; 109 return ret;
100} 110}