summaryrefslogtreecommitdiffstats
path: root/fs/btrfs/transaction.c
diff options
context:
space:
mode:
authorJosef Bacik <josef@redhat.com>2011-04-13 21:15:59 +0200
committerJosef Bacik <josef@redhat.com>2011-05-23 19:00:57 +0200
commit2a1eb4614d984d5cd4c928784e9afcf5c07f93be (patch)
tree892b123c194e490a2dc0bc5b45f641ac921e9d26 /fs/btrfs/transaction.c
parentBtrfs: take away the num_items argument from btrfs_join_transaction (diff)
downloadlinux-2a1eb4614d984d5cd4c928784e9afcf5c07f93be.tar.xz
linux-2a1eb4614d984d5cd4c928784e9afcf5c07f93be.zip
Btrfs: if we've already started a trans handle, use that one
We currently track trans handles in current->journal_info, but we don't actually use it. This patch fixes it. This will cover the case where we have multiple people starting transactions down the call chain. This keeps us from having to allocate a new handle and all of that, we just increase the use count of the current handle, save the old block_rsv, and return. I tested this with xfstests and it worked out fine. Thanks, Signed-off-by: Josef Bacik <josef@redhat.com>
Diffstat (limited to 'fs/btrfs/transaction.c')
-rw-r--r--fs/btrfs/transaction.c17
1 files changed, 17 insertions, 0 deletions
diff --git a/fs/btrfs/transaction.c b/fs/btrfs/transaction.c
index 70bfb26df967..46f40564c168 100644
--- a/fs/btrfs/transaction.c
+++ b/fs/btrfs/transaction.c
@@ -184,6 +184,15 @@ static struct btrfs_trans_handle *start_transaction(struct btrfs_root *root,
if (root->fs_info->fs_state & BTRFS_SUPER_FLAG_ERROR)
return ERR_PTR(-EROFS);
+
+ if (current->journal_info) {
+ WARN_ON(type != TRANS_JOIN && type != TRANS_JOIN_NOLOCK);
+ h = current->journal_info;
+ h->use_count++;
+ h->orig_rsv = h->block_rsv;
+ h->block_rsv = NULL;
+ goto got_it;
+ }
again:
h = kmem_cache_alloc(btrfs_trans_handle_cachep, GFP_NOFS);
if (!h)
@@ -213,7 +222,9 @@ again:
h->block_group = 0;
h->bytes_reserved = 0;
h->delayed_ref_updates = 0;
+ h->use_count = 1;
h->block_rsv = NULL;
+ h->orig_rsv = NULL;
smp_mb();
if (cur_trans->blocked && may_wait_transaction(root, type)) {
@@ -241,6 +252,7 @@ again:
}
}
+got_it:
if (type != TRANS_JOIN_NOLOCK)
mutex_lock(&root->fs_info->trans_mutex);
record_root_in_trans(h, root);
@@ -428,6 +440,11 @@ static int __btrfs_end_transaction(struct btrfs_trans_handle *trans,
struct btrfs_fs_info *info = root->fs_info;
int count = 0;
+ if (--trans->use_count) {
+ trans->block_rsv = trans->orig_rsv;
+ return 0;
+ }
+
while (count < 4) {
unsigned long cur = trans->delayed_ref_updates;
trans->delayed_ref_updates = 0;