alpha: convert srm code to seq_file
[safe/jmp/linux-2.6] / fs / ext4 / fsync.c
index 272faa2..0b22497 100644 (file)
 #include <linux/fs.h>
 #include <linux/sched.h>
 #include <linux/writeback.h>
-#include <linux/jbd.h>
-#include <linux/ext4_fs.h>
-#include <linux/ext4_jbd.h>
+#include <linux/jbd2.h>
+#include <linux/blkdev.h>
+
+#include "ext4.h"
+#include "ext4_jbd2.h"
+
+#include <trace/events/ext4.h>
 
 /*
  * akpm: A new design for ext4_sync_file().
  *
  * What we do is just kick off a commit and wait on it.  This will snapshot the
  * inode to disk.
+ *
+ * i_mutex lock is held when entering and exiting this function
  */
 
-int ext4_sync_file(struct file * file, struct dentry *dentry, int datasync)
+int ext4_sync_file(struct file *file, struct dentry *dentry, int datasync)
 {
        struct inode *inode = dentry->d_inode;
-       int ret = 0;
+       struct ext4_inode_info *ei = EXT4_I(inode);
+       journal_t *journal = EXT4_SB(inode->i_sb)->s_journal;
+       int ret;
+       tid_t commit_tid;
+
+       J_ASSERT(ext4_journal_current_handle() == NULL);
+
+       trace_ext4_sync_file(file, dentry, datasync);
 
-       J_ASSERT(ext4_journal_current_handle() == 0);
+       if (inode->i_sb->s_flags & MS_RDONLY)
+               return 0;
+
+       ret = flush_aio_dio_completed_IO(inode);
+       if (ret < 0)
+               return ret;
+       
+       if (!journal)
+               return simple_fsync(file, dentry, datasync);
 
        /*
-        * data=writeback:
+        * data=writeback,ordered:
         *  The caller's filemap_fdatawrite()/wait will sync the data.
-        *  sync_inode() will sync the metadata
-        *
-        * data=ordered:
-        *  The caller's filemap_fdatawrite() will write the data and
-        *  sync_inode() will write the inode if it is dirty.  Then the caller's
-        *  filemap_fdatawait() will wait on the pages.
+        *  Metadata is in the journal, we wait for proper transaction to
+        *  commit here.
         *
         * data=journal:
         *  filemap_fdatawrite won't do anything (the buffers are clean).
@@ -67,22 +84,13 @@ int ext4_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 (ext4_should_journal_data(inode)) {
-               ret = ext4_force_commit(inode->i_sb);
-               goto out;
-       }
+       if (ext4_should_journal_data(inode))
+               return ext4_force_commit(inode->i_sb);
 
-       /*
-        * The VFS has written the file data.  If the inode is unaltered
-        * then we need not start a commit.
-        */
-       if (inode->i_state & (I_DIRTY_SYNC|I_DIRTY_DATASYNC)) {
-               struct writeback_control wbc = {
-                       .sync_mode = WB_SYNC_ALL,
-                       .nr_to_write = 0, /* sys_fsync did this */
-               };
-               ret = sync_inode(inode, &wbc);
-       }
-out:
+       commit_tid = datasync ? ei->i_datasync_tid : ei->i_sync_tid;
+       if (jbd2_log_start_commit(journal, commit_tid))
+               jbd2_log_wait_commit(journal, commit_tid);
+       else if (journal->j_flags & JBD2_BARRIER)
+               blkdev_issue_flush(inode->i_sb->s_bdev, NULL);
        return ret;
 }