Skip to content

Commit

Permalink
Btrfs: if we've already started a trans handle, use that one
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Josef Bacik committed May 23, 2011
1 parent 7a7eaa4 commit 2a1eb46
Show file tree
Hide file tree
Showing 2 changed files with 19 additions and 0 deletions.
17 changes: 17 additions & 0 deletions fs/btrfs/transaction.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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)) {
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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;
Expand Down
2 changes: 2 additions & 0 deletions fs/btrfs/transaction.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down

0 comments on commit 2a1eb46

Please sign in to comment.