]> Pileus Git - ~andy/linux/blobdiff - fs/ext3/fsync.c
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wirel...
[~andy/linux] / fs / ext3 / fsync.c
index 8209f266e9ade19dbcb244634cc39a02623f2fa5..d7e9f74dc3a6d7e6b02f65d9b54fb9a22ca2d764 100644 (file)
  * inode to disk.
  */
 
-int ext3_sync_file(struct file * file, struct dentry *dentry, int datasync)
+int ext3_sync_file(struct file *file, int datasync)
 {
-       struct inode *inode = dentry->d_inode;
+       struct inode *inode = file->f_mapping->host;
        struct ext3_inode_info *ei = EXT3_I(inode);
        journal_t *journal = EXT3_SB(inode->i_sb)->s_journal;
-       int ret = 0;
+       int ret, needs_barrier = 0;
        tid_t commit_tid;
 
        if (inode->i_sb->s_flags & MS_RDONLY)
@@ -70,28 +70,27 @@ int ext3_sync_file(struct file * file, struct dentry *dentry, int datasync)
         *  (they were dirtied by commit).  But that's OK - the blocks are
         *  safe in-journal, which is all fsync() needs to ensure.
         */
-       if (ext3_should_journal_data(inode)) {
-               ret = ext3_force_commit(inode->i_sb);
-               goto out;
-       }
+       if (ext3_should_journal_data(inode))
+               return ext3_force_commit(inode->i_sb);
 
        if (datasync)
                commit_tid = atomic_read(&ei->i_datasync_tid);
        else
                commit_tid = atomic_read(&ei->i_sync_tid);
 
-       if (log_start_commit(journal, commit_tid)) {
-               log_wait_commit(journal, commit_tid);
-               goto out;
-       }
+       if (test_opt(inode->i_sb, BARRIER) &&
+           !journal_trans_will_send_data_barrier(journal, commit_tid))
+               needs_barrier = 1;
+       log_start_commit(journal, commit_tid);
+       ret = log_wait_commit(journal, commit_tid);
 
        /*
         * In case we didn't commit a transaction, we have to flush
         * disk caches manually so that data really is on persistent
         * storage
         */
-       if (test_opt(inode->i_sb, BARRIER))
-               blkdev_issue_flush(inode->i_sb->s_bdev, NULL);
-out:
+       if (needs_barrier)
+               blkdev_issue_flush(inode->i_sb->s_bdev, GFP_KERNEL, NULL,
+                               BLKDEV_IFL_WAIT);
        return ret;
 }