summaryrefslogtreecommitdiffstats
path: root/fs/btrfs/file.c
diff options
context:
space:
mode:
authorChris Mason2008-09-11 21:53:12 +0200
committerChris Mason2008-09-25 17:04:07 +0200
commit49eb7e46d47ea72a9bd2a5f8cedb04f5159cc277 (patch)
treec3d05588c3cf73453673206214fadedc07bd79d7 /fs/btrfs/file.c
parentBtrfs: Fix releasepage to properly keep dirty and writeback pages (diff)
downloadkernel-qcow2-linux-49eb7e46d47ea72a9bd2a5f8cedb04f5159cc277.tar.gz
kernel-qcow2-linux-49eb7e46d47ea72a9bd2a5f8cedb04f5159cc277.tar.xz
kernel-qcow2-linux-49eb7e46d47ea72a9bd2a5f8cedb04f5159cc277.zip
Btrfs: Dir fsync optimizations
Drop i_mutex during the commit Don't bother doing the fsync at all unless the dir is marked as dirtied and needing fsync in this transaction. For directories, this means that someone has unlinked a file from the dir without fsyncing the file. Signed-off-by: Chris Mason <chris.mason@oracle.com>
Diffstat (limited to 'fs/btrfs/file.c')
-rw-r--r--fs/btrfs/file.c19
1 files changed, 18 insertions, 1 deletions
diff --git a/fs/btrfs/file.c b/fs/btrfs/file.c
index 84ecf3ab8511..58b329ddb426 100644
--- a/fs/btrfs/file.c
+++ b/fs/btrfs/file.c
@@ -1061,7 +1061,9 @@ int btrfs_sync_file(struct file *file, struct dentry *dentry, int datasync)
}
mutex_unlock(&root->fs_info->trans_mutex);
+ root->fs_info->tree_log_batch++;
filemap_fdatawait(inode->i_mapping);
+ root->fs_info->tree_log_batch++;
/*
* ok we haven't committed the transaction yet, lets do a commit
@@ -1076,14 +1078,29 @@ int btrfs_sync_file(struct file *file, struct dentry *dentry, int datasync)
}
ret = btrfs_log_dentry_safe(trans, root, file->f_dentry);
- if (ret < 0)
+ if (ret < 0) {
goto out;
+ }
+
+ /* we've logged all the items and now have a consistent
+ * version of the file in the log. It is possible that
+ * someone will come in and modify the file, but that's
+ * fine because the log is consistent on disk, and we
+ * have references to all of the file's extents
+ *
+ * It is possible that someone will come in and log the
+ * file again, but that will end up using the synchronization
+ * inside btrfs_sync_log to keep things safe.
+ */
+ mutex_unlock(&file->f_dentry->d_inode->i_mutex);
+
if (ret > 0) {
ret = btrfs_commit_transaction(trans, root);
} else {
btrfs_sync_log(trans, root);
ret = btrfs_end_transaction(trans, root);
}
+ mutex_lock(&file->f_dentry->d_inode->i_mutex);
out:
return ret > 0 ? EIO : ret;
}