aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs
diff options
context:
space:
mode:
authorJosef Bacik <josef@redhat.com>2012-05-29 16:57:49 -0400
committerJosef Bacik <josef@redhat.com>2012-05-30 10:23:42 -0400
commit22ee6985de7d3e81ec0cef9c6ba01b45ad1bafeb (patch)
tree96f9f1b4a4e0f0e77503fd63e6552a4a4b477e21 /fs/btrfs
parent018642a1f197887058e97291460b890d296e8953 (diff)
Btrfs: check to see if the inode is in the log before fsyncing
We have this check down in the actual logging code, but this is after we start a transaction and all that good stuff. So move the helper inode_in_log() out so we can call it in fsync() and avoid starting a transaction altogether and just exit if we've already fsync()'ed this file recently. You would notice this issue if you fsync()'ed a file over and over again until the transaction committed. Thanks, Signed-off-by: Josef Bacik <josef@redhat.com>
Diffstat (limited to 'fs/btrfs')
-rw-r--r--fs/btrfs/btrfs_inode.h13
-rw-r--r--fs/btrfs/file.c3
-rw-r--r--fs/btrfs/tree-log.c17
3 files changed, 16 insertions, 17 deletions
diff --git a/fs/btrfs/btrfs_inode.h b/fs/btrfs/btrfs_inode.h
index ce2c9d60031e..e616f8872e69 100644
--- a/fs/btrfs/btrfs_inode.h
+++ b/fs/btrfs/btrfs_inode.h
@@ -199,4 +199,17 @@ static inline bool btrfs_is_free_space_inode(struct btrfs_root *root,
199 return false; 199 return false;
200} 200}
201 201
202static inline int btrfs_inode_in_log(struct inode *inode, u64 generation)
203{
204 struct btrfs_root *root = BTRFS_I(inode)->root;
205 int ret = 0;
206
207 mutex_lock(&root->log_mutex);
208 if (BTRFS_I(inode)->logged_trans == generation &&
209 BTRFS_I(inode)->last_sub_trans <= root->last_log_commit)
210 ret = 1;
211 mutex_unlock(&root->log_mutex);
212 return ret;
213}
214
202#endif 215#endif
diff --git a/fs/btrfs/file.c b/fs/btrfs/file.c
index 2e63cdc2b093..876cddd6b2f0 100644
--- a/fs/btrfs/file.c
+++ b/fs/btrfs/file.c
@@ -1552,7 +1552,8 @@ int btrfs_sync_file(struct file *file, loff_t start, loff_t end, int datasync)
1552 * syncing 1552 * syncing
1553 */ 1553 */
1554 smp_mb(); 1554 smp_mb();
1555 if (BTRFS_I(inode)->last_trans <= 1555 if (btrfs_inode_in_log(inode, root->fs_info->generation) ||
1556 BTRFS_I(inode)->last_trans <=
1556 root->fs_info->last_trans_committed) { 1557 root->fs_info->last_trans_committed) {
1557 BTRFS_I(inode)->last_trans = 0; 1558 BTRFS_I(inode)->last_trans = 0;
1558 mutex_unlock(&inode->i_mutex); 1559 mutex_unlock(&inode->i_mutex);
diff --git a/fs/btrfs/tree-log.c b/fs/btrfs/tree-log.c
index 6f22a4fca8db..425014bdc6ac 100644
--- a/fs/btrfs/tree-log.c
+++ b/fs/btrfs/tree-log.c
@@ -3038,21 +3038,6 @@ out:
3038 return ret; 3038 return ret;
3039} 3039}
3040 3040
3041static int inode_in_log(struct btrfs_trans_handle *trans,
3042 struct inode *inode)
3043{
3044 struct btrfs_root *root = BTRFS_I(inode)->root;
3045 int ret = 0;
3046
3047 mutex_lock(&root->log_mutex);
3048 if (BTRFS_I(inode)->logged_trans == trans->transid &&
3049 BTRFS_I(inode)->last_sub_trans <= root->last_log_commit)
3050 ret = 1;
3051 mutex_unlock(&root->log_mutex);
3052 return ret;
3053}
3054
3055
3056/* 3041/*
3057 * helper function around btrfs_log_inode to make sure newly created 3042 * helper function around btrfs_log_inode to make sure newly created
3058 * parent directories also end up in the log. A minimal inode and backref 3043 * parent directories also end up in the log. A minimal inode and backref
@@ -3093,7 +3078,7 @@ int btrfs_log_inode_parent(struct btrfs_trans_handle *trans,
3093 if (ret) 3078 if (ret)
3094 goto end_no_trans; 3079 goto end_no_trans;
3095 3080
3096 if (inode_in_log(trans, inode)) { 3081 if (btrfs_inode_in_log(inode, trans->transid)) {
3097 ret = BTRFS_NO_LOG_SYNC; 3082 ret = BTRFS_NO_LOG_SYNC;
3098 goto end_no_trans; 3083 goto end_no_trans;
3099 } 3084 }