|
@@ -175,9 +175,13 @@ static int ocfs2_sync_file(struct file *file, loff_t start, loff_t end,
|
|
|
int datasync)
|
|
|
{
|
|
|
int err = 0;
|
|
|
- journal_t *journal;
|
|
|
struct inode *inode = file->f_mapping->host;
|
|
|
struct ocfs2_super *osb = OCFS2_SB(inode->i_sb);
|
|
|
+ struct ocfs2_inode_info *oi = OCFS2_I(inode);
|
|
|
+ journal_t *journal = osb->journal->j_journal;
|
|
|
+ int ret;
|
|
|
+ tid_t commit_tid;
|
|
|
+ bool needs_barrier = false;
|
|
|
|
|
|
trace_ocfs2_sync_file(inode, file, file->f_path.dentry,
|
|
|
OCFS2_I(inode)->ip_blkno,
|
|
@@ -192,29 +196,19 @@ static int ocfs2_sync_file(struct file *file, loff_t start, loff_t end,
|
|
|
if (err)
|
|
|
return err;
|
|
|
|
|
|
- /*
|
|
|
- * Probably don't need the i_mutex at all in here, just putting it here
|
|
|
- * to be consistent with how fsync used to be called, someone more
|
|
|
- * familiar with the fs could possibly remove it.
|
|
|
- */
|
|
|
- mutex_lock(&inode->i_mutex);
|
|
|
- if (datasync && !(inode->i_state & I_DIRTY_DATASYNC)) {
|
|
|
- /*
|
|
|
- * We still have to flush drive's caches to get data to the
|
|
|
- * platter
|
|
|
- */
|
|
|
- if (osb->s_mount_opt & OCFS2_MOUNT_BARRIER)
|
|
|
- blkdev_issue_flush(inode->i_sb->s_bdev, GFP_KERNEL, NULL);
|
|
|
- goto bail;
|
|
|
+ commit_tid = datasync ? oi->i_datasync_tid : oi->i_sync_tid;
|
|
|
+ if (journal->j_flags & JBD2_BARRIER &&
|
|
|
+ !jbd2_trans_will_send_data_barrier(journal, commit_tid))
|
|
|
+ needs_barrier = true;
|
|
|
+ err = jbd2_complete_transaction(journal, commit_tid);
|
|
|
+ if (needs_barrier) {
|
|
|
+ ret = blkdev_issue_flush(inode->i_sb->s_bdev, GFP_KERNEL, NULL);
|
|
|
+ if (!err)
|
|
|
+ err = ret;
|
|
|
}
|
|
|
|
|
|
- journal = osb->journal->j_journal;
|
|
|
- err = jbd2_journal_force_commit(journal);
|
|
|
-
|
|
|
-bail:
|
|
|
if (err)
|
|
|
mlog_errno(err);
|
|
|
- mutex_unlock(&inode->i_mutex);
|
|
|
|
|
|
return (err < 0) ? -EIO : 0;
|
|
|
}
|
|
@@ -650,7 +644,7 @@ restarted_transaction:
|
|
|
mlog_errno(status);
|
|
|
goto leave;
|
|
|
}
|
|
|
-
|
|
|
+ ocfs2_update_inode_fsync_trans(handle, inode, 1);
|
|
|
ocfs2_journal_dirty(handle, bh);
|
|
|
|
|
|
spin_lock(&OCFS2_I(inode)->ip_lock);
|