summaryrefslogtreecommitdiff
path: root/fs/ext3/fsync.c
diff options
context:
space:
mode:
authorFrederic Weisbecker <fweisbec@gmail.com>2009-12-07 06:28:35 (GMT)
committerFrederic Weisbecker <fweisbec@gmail.com>2009-12-07 06:29:22 (GMT)
commit6548698f929814375fa5d62ae1db96959b0418c1 (patch)
tree340924ae82cb0946aa15045b2b72186de52a8146 /fs/ext3/fsync.c
parent1d2c6cfd40b2dece3bb958cbbc405a2c1536ab75 (diff)
parent22763c5cf3690a681551162c15d34d935308c8d7 (diff)
downloadlinux-fsl-qoriq-6548698f929814375fa5d62ae1db96959b0418c1.tar.xz
Merge commit 'v2.6.32' into reiserfs/kill-bkl
Merge-reason: The tree was based 2.6.31. It's better to be up to date with 2.6.32. Although no conflicting changes were made in between, it gives benchmarking results closer to the lastest kernel behaviour.
Diffstat (limited to 'fs/ext3/fsync.c')
-rw-r--r--fs/ext3/fsync.c40
1 files changed, 23 insertions, 17 deletions
diff --git a/fs/ext3/fsync.c b/fs/ext3/fsync.c
index d336341..8209f26 100644
--- a/fs/ext3/fsync.c
+++ b/fs/ext3/fsync.c
@@ -23,6 +23,7 @@
*/
#include <linux/time.h>
+#include <linux/blkdev.h>
#include <linux/fs.h>
#include <linux/sched.h>
#include <linux/writeback.h>
@@ -45,19 +46,21 @@
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).
@@ -72,20 +75,23 @@ int ext3_sync_file(struct file * file, struct dentry *dentry, int datasync)
goto out;
}
- if (datasync && !(inode->i_state & I_DIRTY_DATASYNC))
+ 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;
+ }
/*
- * The VFS has written the file data. If the inode is unaltered
- * then we need not start a commit.
+ * In case we didn't commit a transaction, we have to flush
+ * disk caches manually so that data really is on persistent
+ * storage
*/
- 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 (test_opt(inode->i_sb, BARRIER))
+ blkdev_issue_flush(inode->i_sb->s_bdev, NULL);
out:
return ret;
}