|
@@ -1087,8 +1087,10 @@ out_nolock:
|
|
btrfs_end_transaction(trans, root);
|
|
btrfs_end_transaction(trans, root);
|
|
else
|
|
else
|
|
btrfs_commit_transaction(trans, root);
|
|
btrfs_commit_transaction(trans, root);
|
|
- } else {
|
|
|
|
|
|
+ } else if (ret != BTRFS_NO_LOG_SYNC) {
|
|
btrfs_commit_transaction(trans, root);
|
|
btrfs_commit_transaction(trans, root);
|
|
|
|
+ } else {
|
|
|
|
+ btrfs_end_transaction(trans, root);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
if (file->f_flags & O_DIRECT) {
|
|
if (file->f_flags & O_DIRECT) {
|
|
@@ -1138,6 +1140,13 @@ int btrfs_sync_file(struct file *file, struct dentry *dentry, int datasync)
|
|
int ret = 0;
|
|
int ret = 0;
|
|
struct btrfs_trans_handle *trans;
|
|
struct btrfs_trans_handle *trans;
|
|
|
|
|
|
|
|
+
|
|
|
|
+ /* we wait first, since the writeback may change the inode */
|
|
|
|
+ root->log_batch++;
|
|
|
|
+ /* the VFS called filemap_fdatawrite for us */
|
|
|
|
+ btrfs_wait_ordered_range(inode, 0, (u64)-1);
|
|
|
|
+ root->log_batch++;
|
|
|
|
+
|
|
/*
|
|
/*
|
|
* check the transaction that last modified this inode
|
|
* check the transaction that last modified this inode
|
|
* and see if its already been committed
|
|
* and see if its already been committed
|
|
@@ -1145,6 +1154,11 @@ int btrfs_sync_file(struct file *file, struct dentry *dentry, int datasync)
|
|
if (!BTRFS_I(inode)->last_trans)
|
|
if (!BTRFS_I(inode)->last_trans)
|
|
goto out;
|
|
goto out;
|
|
|
|
|
|
|
|
+ /*
|
|
|
|
+ * if the last transaction that changed this file was before
|
|
|
|
+ * the current transaction, we can bail out now without any
|
|
|
|
+ * syncing
|
|
|
|
+ */
|
|
mutex_lock(&root->fs_info->trans_mutex);
|
|
mutex_lock(&root->fs_info->trans_mutex);
|
|
if (BTRFS_I(inode)->last_trans <=
|
|
if (BTRFS_I(inode)->last_trans <=
|
|
root->fs_info->last_trans_committed) {
|
|
root->fs_info->last_trans_committed) {
|
|
@@ -1154,13 +1168,6 @@ int btrfs_sync_file(struct file *file, struct dentry *dentry, int datasync)
|
|
}
|
|
}
|
|
mutex_unlock(&root->fs_info->trans_mutex);
|
|
mutex_unlock(&root->fs_info->trans_mutex);
|
|
|
|
|
|
- root->log_batch++;
|
|
|
|
- filemap_fdatawrite(inode->i_mapping);
|
|
|
|
- btrfs_wait_ordered_range(inode, 0, (u64)-1);
|
|
|
|
- root->log_batch++;
|
|
|
|
-
|
|
|
|
- if (datasync && !(inode->i_state & I_DIRTY_PAGES))
|
|
|
|
- goto out;
|
|
|
|
/*
|
|
/*
|
|
* ok we haven't committed the transaction yet, lets do a commit
|
|
* ok we haven't committed the transaction yet, lets do a commit
|
|
*/
|
|
*/
|
|
@@ -1189,14 +1196,18 @@ int btrfs_sync_file(struct file *file, struct dentry *dentry, int datasync)
|
|
*/
|
|
*/
|
|
mutex_unlock(&dentry->d_inode->i_mutex);
|
|
mutex_unlock(&dentry->d_inode->i_mutex);
|
|
|
|
|
|
- if (ret > 0) {
|
|
|
|
- ret = btrfs_commit_transaction(trans, root);
|
|
|
|
- } else {
|
|
|
|
- ret = btrfs_sync_log(trans, root);
|
|
|
|
- if (ret == 0)
|
|
|
|
- ret = btrfs_end_transaction(trans, root);
|
|
|
|
- else
|
|
|
|
|
|
+ if (ret != BTRFS_NO_LOG_SYNC) {
|
|
|
|
+ if (ret > 0) {
|
|
ret = btrfs_commit_transaction(trans, root);
|
|
ret = btrfs_commit_transaction(trans, root);
|
|
|
|
+ } else {
|
|
|
|
+ ret = btrfs_sync_log(trans, root);
|
|
|
|
+ if (ret == 0)
|
|
|
|
+ ret = btrfs_end_transaction(trans, root);
|
|
|
|
+ else
|
|
|
|
+ ret = btrfs_commit_transaction(trans, root);
|
|
|
|
+ }
|
|
|
|
+ } else {
|
|
|
|
+ ret = btrfs_end_transaction(trans, root);
|
|
}
|
|
}
|
|
mutex_lock(&dentry->d_inode->i_mutex);
|
|
mutex_lock(&dentry->d_inode->i_mutex);
|
|
out:
|
|
out:
|