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)
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)) {
}
}
+got_it:
if (type != TRANS_JOIN_NOLOCK)
mutex_lock(&root->fs_info->trans_mutex);
record_root_in_trans(h, root);
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;
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 {