WARN_ON(atomic_read(&transaction->use_count) == 0);
if (atomic_dec_and_test(&transaction->use_count)) {
BUG_ON(!list_empty(&transaction->list));
- WARN_ON(transaction->delayed_refs.root.rb_node);
+ WARN_ON(!RB_EMPTY_ROOT(&transaction->delayed_refs.root));
+ WARN_ON(!RB_EMPTY_ROOT(&transaction->delayed_refs.href_root));
while (!list_empty(&transaction->pending_chunks)) {
struct extent_map *em;
cur_trans->start_time = get_seconds();
cur_trans->delayed_refs.root = RB_ROOT;
+ cur_trans->delayed_refs.href_root = RB_ROOT;
cur_trans->delayed_refs.num_entries = 0;
cur_trans->delayed_refs.num_heads_ready = 0;
cur_trans->delayed_refs.num_heads = 0;
*/
smp_mb();
if (!list_empty(&fs_info->tree_mod_seq_list))
- WARN(1, KERN_ERR "btrfs: tree_mod_seq_list not empty when "
+ WARN(1, KERN_ERR "BTRFS: tree_mod_seq_list not empty when "
"creating a fresh transaction\n");
if (!RB_EMPTY_ROOT(&fs_info->tree_mod_log))
- WARN(1, KERN_ERR "btrfs: tree_mod_log rb tree not empty when "
+ WARN(1, KERN_ERR "BTRFS: tree_mod_log rb tree not empty when "
"creating a fresh transaction\n");
atomic64_set(&fs_info->tree_mod_seq, 0);
h->type = type;
h->allocating_chunk = false;
h->reloc_reserved = false;
+ h->sync = false;
INIT_LIST_HEAD(&h->qgroup_ref_list);
INIT_LIST_HEAD(&h->new_bgs);
btrfs_create_pending_block_groups(trans, root);
trans->delayed_ref_updates = 0;
- if (btrfs_should_throttle_delayed_refs(trans, root)) {
+ if (!trans->sync && btrfs_should_throttle_delayed_refs(trans, root)) {
cur = max_t(unsigned long, cur, 1);
trans->delayed_ref_updates = 0;
btrfs_run_delayed_refs(trans, root, cur);
return __btrfs_end_transaction(trans, root, 1);
}
-int btrfs_end_transaction_dmeta(struct btrfs_trans_handle *trans,
- struct btrfs_root *root)
-{
- return __btrfs_end_transaction(trans, root, 1);
-}
-
/*
* when btree blocks are allocated, they have some corresponding bits set for
* them in one of two extent_io trees. This is used to make sure all of
break;
if (btrfs_defrag_cancelled(root->fs_info)) {
- printk(KERN_DEBUG "btrfs: defrag_root cancelled\n");
+ pr_debug("BTRFS: defrag_root cancelled\n");
ret = -EAGAIN;
break;
}
* We've got freeze protection passed with the transaction.
* Tell lockdep about it.
*/
- if (ac->newtrans->type < TRANS_JOIN_NOLOCK)
+ if (ac->newtrans->type & __TRANS_FREEZABLE)
rwsem_acquire_read(
&ac->root->fs_info->sb->s_writers.lock_map[SB_FREEZE_FS-1],
0, 1, _THIS_IP_);
* Tell lockdep we've released the freeze rwsem, since the
* async commit thread will be the one to unlock it.
*/
- if (trans->type < TRANS_JOIN_NOLOCK)
+ if (ac->newtrans->type & __TRANS_FREEZABLE)
rwsem_release(
&root->fs_info->sb->s_writers.lock_map[SB_FREEZE_FS-1],
1, _THIS_IP_);
goto cleanup_transaction;
btrfs_wait_delalloc_flush(root->fs_info);
+
+ btrfs_scrub_pause(root);
/*
* Ok now we need to make sure to block out any other joins while we
* commit the transaction. We could have started a join before setting
WARN_ON(cur_trans != trans->transaction);
- btrfs_scrub_pause(root);
/* btrfs_commit_tree_roots is responsible for getting the
* various roots consistent with each other. Every pointer
* in the tree of tree roots has to point to the most up to date
}
root = list_first_entry(&fs_info->dead_roots,
struct btrfs_root, root_list);
+ /*
+ * Make sure root is not involved in send,
+ * if we fail with first root, we return
+ * directly rather than continue.
+ */
+ spin_lock(&root->root_item_lock);
+ if (root->send_in_progress) {
+ spin_unlock(&fs_info->trans_lock);
+ spin_unlock(&root->root_item_lock);
+ return 0;
+ }
+ spin_unlock(&root->root_item_lock);
+
list_del_init(&root->root_list);
spin_unlock(&fs_info->trans_lock);
- pr_debug("btrfs: cleaner removing %llu\n", root->objectid);
+ pr_debug("BTRFS: cleaner removing %llu\n", root->objectid);
btrfs_kill_all_delayed_nodes(root);