Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/mason/btrfs-unstable
* 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/mason/btrfs-unstable: Btrfs: always pin metadata in discard mode Btrfs: enable discard support Btrfs: add -o discard option Btrfs: properly wait log writers during log sync Btrfs: fix possible ENOSPC problems with truncate Btrfs: fix btrfs acl #ifdef checks Btrfs: streamline tree-log btree block writeout Btrfs: avoid tree log commit when there are no changes Btrfs: only write one super copy during fsync
This commit is contained in:
@@ -1086,8 +1086,10 @@ out_nolock:
|
||||
btrfs_end_transaction(trans, root);
|
||||
else
|
||||
btrfs_commit_transaction(trans, root);
|
||||
} else {
|
||||
} else if (ret != BTRFS_NO_LOG_SYNC) {
|
||||
btrfs_commit_transaction(trans, root);
|
||||
} else {
|
||||
btrfs_end_transaction(trans, root);
|
||||
}
|
||||
}
|
||||
if (file->f_flags & O_DIRECT) {
|
||||
@@ -1137,6 +1139,13 @@ int btrfs_sync_file(struct file *file, struct dentry *dentry, int datasync)
|
||||
int ret = 0;
|
||||
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
|
||||
* and see if its already been committed
|
||||
@@ -1144,6 +1153,11 @@ int btrfs_sync_file(struct file *file, struct dentry *dentry, int datasync)
|
||||
if (!BTRFS_I(inode)->last_trans)
|
||||
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);
|
||||
if (BTRFS_I(inode)->last_trans <=
|
||||
root->fs_info->last_trans_committed) {
|
||||
@@ -1153,13 +1167,6 @@ int btrfs_sync_file(struct file *file, struct dentry *dentry, int datasync)
|
||||
}
|
||||
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
|
||||
*/
|
||||
@@ -1188,14 +1195,18 @@ int btrfs_sync_file(struct file *file, struct dentry *dentry, int datasync)
|
||||
*/
|
||||
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);
|
||||
} 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);
|
||||
out:
|
||||
|
Reference in New Issue
Block a user