Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/ide-2.6
[cascardo/linux.git] / fs / ext3 / fsync.c
index 451d166..8209f26 100644 (file)
 int ext3_sync_file(struct file * file, struct dentry *dentry, int datasync)
 {
        struct inode *inode = dentry->d_inode;
+       struct ext3_inode_info *ei = EXT3_I(inode);
+       journal_t *journal = EXT3_SB(inode->i_sb)->s_journal;
        int ret = 0;
+       tid_t commit_tid;
+
+       if (inode->i_sb->s_flags & MS_RDONLY)
+               return 0;
 
        J_ASSERT(ext3_journal_current_handle() == NULL);
 
        /*
-        * 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 a proper transaction
+        *  to commit here.
         *
         * data=journal:
         *  filemap_fdatawrite won't do anything (the buffers are clean).
@@ -73,22 +75,16 @@ int ext3_sync_file(struct file * file, struct dentry *dentry, int datasync)
                goto out;
        }
 
-       if (datasync && !(inode->i_state & I_DIRTY_DATASYNC))
-               goto flush;
+       if (datasync)
+               commit_tid = atomic_read(&ei->i_datasync_tid);
+       else
+               commit_tid = atomic_read(&ei->i_sync_tid);
 
-       /*
-        * 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);
+       if (log_start_commit(journal, commit_tid)) {
+               log_wait_commit(journal, commit_tid);
                goto out;
        }
-flush:
+
        /*
         * In case we didn't commit a transaction, we have to flush
         * disk caches manually so that data really is on persistent