diff options
Diffstat (limited to 'fs/ext4/fsync.c')
-rw-r--r-- | fs/ext4/fsync.c | 18 |
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 | ||
49 | int ext4_sync_file(struct file *file, struct dentry *dentry, int datasync) | 51 | int 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 | } |
98 | out: | 106 | out: |
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 | } |