From fae994276f87f9222d4d95c446298e2514fc2666 Mon Sep 17 00:00:00 2001 From: Josef Bacik Date: Wed, 13 Apr 2011 15:15:59 -0400 Subject: [PATCH] --- yaml --- r: 253078 b: refs/heads/master c: 2a1eb4614d984d5cd4c928784e9afcf5c07f93be h: refs/heads/master v: v3 --- [refs] | 2 +- trunk/fs/btrfs/transaction.c | 17 +++++++++++++++++ trunk/fs/btrfs/transaction.h | 2 ++ 3 files changed, 20 insertions(+), 1 deletion(-) diff --git a/[refs] b/[refs] index e2ce3a833bdb..5aa5fd1373d1 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 7a7eaa40a39bde4eefc91aadeb1ce3dc4e6a1252 +refs/heads/master: 2a1eb4614d984d5cd4c928784e9afcf5c07f93be diff --git a/trunk/fs/btrfs/transaction.c b/trunk/fs/btrfs/transaction.c index 70bfb26df967..46f40564c168 100644 --- a/trunk/fs/btrfs/transaction.c +++ b/trunk/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 @@ static struct btrfs_trans_handle *start_transaction(struct btrfs_root *root, 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 @@ static struct btrfs_trans_handle *start_transaction(struct btrfs_root *root, } } +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; diff --git a/trunk/fs/btrfs/transaction.h b/trunk/fs/btrfs/transaction.h index 1f573f09dba2..154314f80f8d 100644 --- a/trunk/fs/btrfs/transaction.h +++ b/trunk/fs/btrfs/transaction.h @@ -47,11 +47,13 @@ struct btrfs_trans_handle { u64 transid; u64 block_group; u64 bytes_reserved; + unsigned long use_count; unsigned long blocks_reserved; unsigned long blocks_used; unsigned long delayed_ref_updates; struct btrfs_transaction *transaction; struct btrfs_block_rsv *block_rsv; + struct btrfs_block_rsv *orig_rsv; }; struct btrfs_pending_snapshot {