/* * Transaction states and transitions * * No running transaction (fs tree blocks are not modified) * | * | To next stage: * | Call start_transaction() variants. Except btrfs_join_transaction_nostart(). * V * Transaction N [[TRANS_STATE_RUNNING]] * | * | New trans handles can be attached to transaction N by calling all * | start_transaction() variants. * | * | To next stage: * | Call btrfs_commit_transaction() on any trans handle attached to * | transaction N * V * Transaction N [[TRANS_STATE_COMMIT_PREP]] * | * | If there are simultaneous calls to btrfs_commit_transaction() one will win * | the race and the rest will wait for the winner to commit the transaction. * | * | The winner will wait for previous running transaction to completely finish * | if there is one. * | * Transaction N [[TRANS_STATE_COMMIT_START]] * | * | Then one of the following happens: * | - Wait for all other trans handle holders to release. * | The btrfs_commit_transaction() caller will do the commit work. * | - Wait for current transaction to be committed by others. * | Other btrfs_commit_transaction() caller will do the commit work. * | * | At this stage, only btrfs_join_transaction*() variants can attach * | to this running transaction. * | All other variants will wait for current one to finish and attach to * | transaction N+1. * | * | To next stage: * | Caller is chosen to commit transaction N, and all other trans handle * | haven been released. * V * Transaction N [[TRANS_STATE_COMMIT_DOING]] * | * | The heavy lifting transaction work is started. * | From running delayed refs (modifying extent tree) to creating pending * | snapshots, running qgroups. * | In short, modify supporting trees to reflect modifications of subvolume * | trees. * | * | At this stage, all start_transaction() calls will wait for this * | transaction to finish and attach to transaction N+1. * | * | To next stage: * | Until all supporting trees are updated. * V * Transaction N [[TRANS_STATE_UNBLOCKED]] * | Transaction N+1 * | All needed trees are modified, thus we only [[TRANS_STATE_RUNNING]] * | need to write them back to disk and update | * | super blocks. | * | | * | At this stage, new transaction is allowed to | * | start. | * | All new start_transaction() calls will be | * | attached to transid N+1. | * | | * | To next stage: | * | Until all tree blocks are super blocks are | * | written to block devices | * V | * Transaction N [[TRANS_STATE_COMPLETED]] V * All tree blocks and super blocks are written. Transaction N+1 * This transaction is finished and all its [[TRANS_STATE_COMMIT_START]] * data structures will be cleaned up. | Life goes on
*/ staticconstunsignedint btrfs_blocked_trans_types[TRANS_STATE_MAX] = {
[TRANS_STATE_RUNNING] = 0U,
[TRANS_STATE_COMMIT_PREP] = 0U,
[TRANS_STATE_COMMIT_START] = (__TRANS_START | __TRANS_ATTACH),
[TRANS_STATE_COMMIT_DOING] = (__TRANS_START |
__TRANS_ATTACH |
__TRANS_JOIN |
__TRANS_JOIN_NOSTART),
[TRANS_STATE_UNBLOCKED] = (__TRANS_START |
__TRANS_ATTACH |
__TRANS_JOIN |
__TRANS_JOIN_NOLOCK |
__TRANS_JOIN_NOSTART),
[TRANS_STATE_SUPER_COMMITTED] = (__TRANS_START |
__TRANS_ATTACH |
__TRANS_JOIN |
__TRANS_JOIN_NOLOCK |
__TRANS_JOIN_NOSTART),
[TRANS_STATE_COMPLETED] = (__TRANS_START |
__TRANS_ATTACH |
__TRANS_JOIN |
__TRANS_JOIN_NOLOCK |
__TRANS_JOIN_NOSTART),
};
void btrfs_put_transaction(struct btrfs_transaction *transaction)
{
WARN_ON(refcount_read(&transaction->use_count) == 0); if (refcount_dec_and_test(&transaction->use_count)) {
BUG_ON(!list_empty(&transaction->list));
WARN_ON(!xa_empty(&transaction->delayed_refs.head_refs));
WARN_ON(!xa_empty(&transaction->delayed_refs.dirty_extents)); if (transaction->delayed_refs.pending_csums)
btrfs_err(transaction->fs_info, "pending csums is %llu",
transaction->delayed_refs.pending_csums); /* * If any block groups are found in ->deleted_bgs then it's * because the transaction was aborted and a commit did not * happen (things failed before writing the new superblock * and calling btrfs_finish_extent_commit()), so we can not * discard the physical locations of the block groups.
*/ while (!list_empty(&transaction->deleted_bgs)) { struct btrfs_block_group *cache;
cache = list_first_entry(&transaction->deleted_bgs, struct btrfs_block_group,
bg_list); /* * Not strictly necessary to lock, as no other task will be using a * block_group on the deleted_bgs list during a transaction abort.
*/
spin_lock(&transaction->fs_info->unused_bgs_lock);
list_del_init(&cache->bg_list);
spin_unlock(&transaction->fs_info->unused_bgs_lock);
btrfs_unfreeze_block_group(cache);
btrfs_put_block_group(cache);
}
WARN_ON(!list_empty(&transaction->dev_update_list));
kfree(transaction);
}
}
/* * At this point no one can be using this transaction to modify any tree * and no one can start another transaction to modify any tree either.
*/
ASSERT(cur_trans->state == TRANS_STATE_COMMIT_DOING);
down_write(&fs_info->commit_root_sem);
if (test_bit(BTRFS_FS_RELOC_RUNNING, &fs_info->flags))
fs_info->last_reloc_trans = trans->transid;
/* * To be called after doing the chunk btree updates right after allocating a new * chunk (after btrfs_chunk_alloc_add_chunk_item() is called), when removing a * chunk after all chunk btree updates and after finishing the second phase of * chunk allocation (btrfs_create_pending_block_groups()) in case some block * group had its chunk item insertion delayed to the second phase.
*/ void btrfs_trans_release_chunk_metadata(struct btrfs_trans_handle *trans)
{ struct btrfs_fs_info *fs_info = trans->fs_info;
/* * either allocate a new transaction or hop into the existing one
*/ static noinline int join_transaction(struct btrfs_fs_info *fs_info, unsignedint type)
{ struct btrfs_transaction *cur_trans;
spin_lock(&fs_info->trans_lock);
loop: /* The file system has been taken offline. No new transactions. */ if (BTRFS_FS_ERROR(fs_info)) {
spin_unlock(&fs_info->trans_lock); return -EROFS;
}
cur_trans = fs_info->running_transaction; if (cur_trans) { if (TRANS_ABORTED(cur_trans)) { constint abort_error = cur_trans->aborted;
/* * If we are ATTACH or TRANS_JOIN_NOSTART, we just want to catch the * current transaction, and commit it. If there is no transaction, just * return ENOENT.
*/ if (type == TRANS_ATTACH || type == TRANS_JOIN_NOSTART) return -ENOENT;
/* * JOIN_NOLOCK only happens during the transaction commit, so * it is impossible that ->running_transaction is NULL
*/
BUG_ON(type == TRANS_JOIN_NOLOCK);
cur_trans = kmalloc(sizeof(*cur_trans), GFP_NOFS); if (!cur_trans) return -ENOMEM;
spin_lock(&fs_info->trans_lock); if (fs_info->running_transaction) { /* * someone started a transaction after we unlocked. Make sure * to redo the checks above
*/
btrfs_lockdep_release(fs_info, btrfs_trans_num_extwriters);
btrfs_lockdep_release(fs_info, btrfs_trans_num_writers);
kfree(cur_trans); goto loop;
} elseif (BTRFS_FS_ERROR(fs_info)) {
spin_unlock(&fs_info->trans_lock);
btrfs_lockdep_release(fs_info, btrfs_trans_num_extwriters);
btrfs_lockdep_release(fs_info, btrfs_trans_num_writers);
kfree(cur_trans); return -EROFS;
}
cur_trans->fs_info = fs_info;
atomic_set(&cur_trans->pending_ordered, 0);
init_waitqueue_head(&cur_trans->pending_wait);
atomic_set(&cur_trans->num_writers, 1);
extwriter_counter_init(cur_trans, type);
init_waitqueue_head(&cur_trans->writer_wait);
init_waitqueue_head(&cur_trans->commit_wait);
cur_trans->state = TRANS_STATE_RUNNING; /* * One for this trans handle, one so it will live on until we * commit the transaction.
*/
refcount_set(&cur_trans->use_count, 2);
cur_trans->flags = 0;
cur_trans->start_time = ktime_get_seconds();
/* * although the tree mod log is per file system and not per transaction, * the log must never go across transaction boundaries.
*/
smp_mb(); if (!list_empty(&fs_info->tree_mod_seq_list))
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 creating a fresh transaction\n");
atomic64_set(&fs_info->tree_mod_seq, 0);
/* * This does all the record keeping required to make sure that a shareable root * is properly recorded in a given transaction. This is required to make sure * the old root from before we joined the transaction is deleted when the * transaction commits.
*/ staticint record_root_in_trans(struct btrfs_trans_handle *trans, struct btrfs_root *root, int force)
{ struct btrfs_fs_info *fs_info = root->fs_info; int ret = 0;
/* * see below for IN_TRANS_SETUP usage rules * we have the reloc mutex held now, so there * is only one writer in this function
*/
set_bit(BTRFS_ROOT_IN_TRANS_SETUP, &root->state);
/* make sure readers find IN_TRANS_SETUP before * they find our root->last_trans update
*/
smp_wmb();
/* this is pretty tricky. We don't want to * take the relocation lock in btrfs_record_root_in_trans * unless we're really doing the first setup for this root in * this transaction. * * Normally we'd use root->last_trans as a flag to decide * if we want to take the expensive mutex. * * But, we have to set root->last_trans before we * init the relocation root, otherwise, we trip over warnings * in ctree.c. The solution used here is to flag ourselves * with root IN_TRANS_SETUP. When this is 1, we're still * fixing up the reloc trees and everyone must wait. * * When this is zero, they can trust root->last_trans and fly * through btrfs_record_root_in_trans without having to take the * lock. smp_wmb() makes sure that all the writes above are * done before we pop in the zero below
*/
ret = btrfs_init_reloc_root(trans, root);
smp_mb__before_atomic();
clear_bit(BTRFS_ROOT_IN_TRANS_SETUP, &root->state);
} return ret;
}
/* Add ourselves to the transaction dropped list */
spin_lock(&cur_trans->dropped_roots_lock);
list_add_tail(&root->root_list, &cur_trans->dropped_roots);
spin_unlock(&cur_trans->dropped_roots_lock);
/* Make sure we don't try to update the root at commit time */
spin_lock(&fs_info->fs_roots_radix_lock);
radix_tree_tag_clear(&fs_info->fs_roots_radix,
(unsignedlong)btrfs_root_id(root),
BTRFS_ROOT_TRANS_TAG);
spin_unlock(&fs_info->fs_roots_radix_lock);
}
int btrfs_record_root_in_trans(struct btrfs_trans_handle *trans, struct btrfs_root *root)
{ struct btrfs_fs_info *fs_info = root->fs_info; int ret;
if (!test_bit(BTRFS_ROOT_SHAREABLE, &root->state)) return 0;
/* * see record_root_in_trans for comments about IN_TRANS_SETUP usage * and barriers
*/
smp_rmb(); if (btrfs_get_root_last_trans(root) == trans->transid &&
!test_bit(BTRFS_ROOT_IN_TRANS_SETUP, &root->state)) return 0;
mutex_lock(&fs_info->reloc_mutex);
ret = record_root_in_trans(trans, root, 0);
mutex_unlock(&fs_info->reloc_mutex);
/* wait for commit against the current transaction to become unblocked * when this is done, it is safe to start a new transaction, but the current * transaction might not be fully on disk.
*/ staticvoid wait_current_trans(struct btrfs_fs_info *fs_info)
{ struct btrfs_transaction *cur_trans;
/* * We want to reserve all the bytes we may need all at once, so we only * do 1 enospc flushing cycle per transaction start.
*/
ret = btrfs_reserve_metadata_bytes(fs_info, si, bytes, flush);
/* * If we are an emergency flush, which can steal from the global block * reserve, then attempt to not reserve space for the delayed refs, as * we will consume space for them from the global block reserve.
*/ if (ret && flush == BTRFS_RESERVE_FLUSH_ALL_STEAL) {
bytes -= *delayed_refs_bytes;
*delayed_refs_bytes = 0;
ret = btrfs_reserve_metadata_bytes(fs_info, si, bytes, flush);
}
/* * Do the reservation before we join the transaction so we can do all * the appropriate flushing if need be.
*/ if (num_items && root != fs_info->chunk_root) {
qgroup_reserved = num_items * fs_info->nodesize; /* * Use prealloc for now, as there might be a currently running * transaction that could free this reserved space prematurely * by committing.
*/
ret = btrfs_qgroup_reserve_meta_prealloc(root, qgroup_reserved,
enforce_qgroups, false); if (ret) return ERR_PTR(ret);
num_bytes = btrfs_calc_insert_metadata_size(fs_info, num_items); /* * If we plan to insert/update/delete "num_items" from a btree, * we will also generate delayed refs for extent buffers in the * respective btree paths, so reserve space for the delayed refs * that will be generated by the caller as it modifies btrees. * Try to reserve them to avoid excessive use of the global * block reserve.
*/
delayed_refs_bytes = btrfs_calc_delayed_ref_bytes(fs_info, num_items);
/* * Do the reservation for the relocation root creation
*/ if (need_reserve_reloc_root(root)) {
num_bytes += fs_info->nodesize;
reloc_reserved = true;
}
ret = btrfs_reserve_trans_metadata(fs_info, flush, num_bytes,
&delayed_refs_bytes); if (ret) goto reserve_fail;
if (trans_rsv->space_info->force_alloc)
do_chunk_alloc = true;
} elseif (num_items == 0 && flush == BTRFS_RESERVE_FLUSH_ALL &&
!btrfs_block_rsv_full(delayed_refs_rsv)) { /* * Some people call with btrfs_start_transaction(root, 0) * because they can be throttled, but have some other mechanism * for reserving space. We still want these guys to refill the * delayed block_rsv so just add 1 items worth of reservation * here.
*/
ret = btrfs_delayed_refs_rsv_refill(fs_info, flush); if (ret) goto reserve_fail;
}
again:
h = kmem_cache_zalloc(btrfs_trans_handle_cachep, GFP_NOFS); if (!h) {
ret = -ENOMEM; goto alloc_fail;
}
/* * If we are JOIN_NOLOCK we're already committing a transaction and * waiting on this guy, so we don't need to do the sb_start_intwrite * because we're already holding a ref. We need this because we could * have raced in and did an fsync() on a file which can kick a commit * and then we deadlock with somebody doing a freeze. * * If we are ATTACH, it means we just want to catch the current * transaction and commit it, so we needn't do sb_start_intwrite().
*/ if (type & __TRANS_FREEZABLE)
sb_start_intwrite(fs_info->sb);
if (may_wait_transaction(fs_info, type))
wait_current_trans(fs_info);
do {
ret = join_transaction(fs_info, type); if (ret == -EBUSY) {
wait_current_trans(fs_info); if (unlikely(type == TRANS_ATTACH ||
type == TRANS_JOIN_NOSTART))
ret = -ENOENT;
}
} while (ret == -EBUSY);
got_it: if (!current->journal_info)
current->journal_info = h;
/* * If the space_info is marked ALLOC_FORCE then we'll get upgraded to * ALLOC_FORCE the first run through, and then we won't allocate for * anybody else who races in later. We don't care about the return * value here.
*/ if (do_chunk_alloc && num_bytes) { struct btrfs_space_info *space_info = h->block_rsv->space_info;
u64 flags = space_info->flags;
/* * btrfs_record_root_in_trans() needs to alloc new extents, and may * call btrfs_join_transaction() while we're also starting a * transaction. * * Thus it need to be called after current->journal_info initialized, * or we can deadlock.
*/
ret = btrfs_record_root_in_trans(h, root); if (ret) { /* * The transaction handle is fully initialized and linked with * other structures so it needs to be ended in case of errors, * not just freed.
*/
btrfs_end_transaction(h); goto reserve_fail;
} /* * Now that we have found a transaction to be a part of, convert the * qgroup reservation from prealloc to pertrans. A different transaction * can't race in and free our pertrans out from under us.
*/ if (qgroup_reserved)
btrfs_qgroup_convert_reserved_meta(root, qgroup_reserved);
return h;
join_fail: if (type & __TRANS_FREEZABLE)
sb_end_intwrite(fs_info->sb);
kmem_cache_free(btrfs_trans_handle_cachep, h);
alloc_fail: if (num_bytes)
btrfs_block_rsv_release(fs_info, trans_rsv, num_bytes, NULL); if (delayed_refs_bytes)
btrfs_space_info_free_bytes_may_use(trans_rsv->space_info, delayed_refs_bytes);
reserve_fail:
btrfs_qgroup_free_meta_prealloc(root, qgroup_reserved); return ERR_PTR(ret);
}
/* * Similar to regular join but it never starts a transaction when none is * running or when there's a running one at a state >= TRANS_STATE_UNBLOCKED. * This is similar to btrfs_attach_transaction() but it allows the join to * happen if the transaction commit already started but it's not yet in the * "doing" phase (the state is < TRANS_STATE_COMMIT_DOING).
*/ struct btrfs_trans_handle *btrfs_join_transaction_nostart(struct btrfs_root *root)
{ return start_transaction(root, 0, TRANS_JOIN_NOSTART,
BTRFS_RESERVE_NO_FLUSH, true);
}
/* * Catch the running transaction. * * It is used when we want to commit the current the transaction, but * don't want to start a new one. * * Note: If this function return -ENOENT, it just means there is no * running transaction. But it is possible that the inactive transaction * is still in the memory, not fully on disk. If you hope there is no * inactive transaction in the fs when -ENOENT is returned, you should * invoke * btrfs_attach_transaction_barrier()
*/ struct btrfs_trans_handle *btrfs_attach_transaction(struct btrfs_root *root)
{ return start_transaction(root, 0, TRANS_ATTACH,
BTRFS_RESERVE_NO_FLUSH, true);
}
/* * Catch the running transaction. * * It is similar to the above function, the difference is this one * will wait for all the inactive transactions until they fully * complete.
*/ struct btrfs_trans_handle *
btrfs_attach_transaction_barrier(struct btrfs_root *root)
{ struct btrfs_trans_handle *trans;
trans = start_transaction(root, 0, TRANS_ATTACH,
BTRFS_RESERVE_NO_FLUSH, true); if (trans == ERR_PTR(-ENOENT)) { int ret;
ret = btrfs_wait_for_commit(root->fs_info, 0); if (ret) return ERR_PTR(ret);
}
return trans;
}
/* Wait for a transaction commit to reach at least the given state. */ static noinline void wait_for_commit(struct btrfs_transaction *commit, constenum btrfs_trans_state min_state)
{ struct btrfs_fs_info *fs_info = commit->fs_info;
u64 transid = commit->transid; bool put = false;
/* * At the moment this function is called with min_state either being * TRANS_STATE_COMPLETED or TRANS_STATE_SUPER_COMMITTED.
*/ if (min_state == TRANS_STATE_COMPLETED)
btrfs_might_wait_for_state(fs_info, BTRFS_LOCKDEP_TRANS_COMPLETED); else
btrfs_might_wait_for_state(fs_info, BTRFS_LOCKDEP_TRANS_SUPER_COMMITTED);
while (1) {
wait_event(commit->commit_wait, commit->state >= min_state); if (put)
btrfs_put_transaction(commit);
if (min_state < TRANS_STATE_COMPLETED) break;
/* * A transaction isn't really completed until all of the * previous transactions are completed, but with fsync we can * end up with SUPER_COMMITTED transactions before a COMPLETED * transaction. Wait for those.
*/
if (current->journal_info == trans)
current->journal_info = NULL;
if (throttle)
btrfs_run_delayed_iputs(info);
if (TRANS_ABORTED(trans) || BTRFS_FS_ERROR(info)) {
wake_up_process(info->transaction_kthread); if (TRANS_ABORTED(trans))
ret = trans->aborted; else
ret = -EROFS;
}
int btrfs_end_transaction(struct btrfs_trans_handle *trans)
{ return __btrfs_end_transaction(trans, 0);
}
int btrfs_end_transaction_throttle(struct btrfs_trans_handle *trans)
{ return __btrfs_end_transaction(trans, 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 * those extents are sent to disk but does not wait on them
*/ int btrfs_write_marked_extents(struct btrfs_fs_info *fs_info, struct extent_io_tree *dirty_pages, int mark)
{ int ret = 0; struct address_space *mapping = fs_info->btree_inode->i_mapping; struct extent_state *cached_state = NULL;
u64 start = 0;
u64 end;
ret = btrfs_convert_extent_bit(dirty_pages, start, end,
EXTENT_NEED_WAIT,
mark, &cached_state); /* * convert_extent_bit can return -ENOMEM, which is most of the * time a temporary error. So when it happens, ignore the error * and wait for writeback of this range to finish - because we * failed to set the bit EXTENT_NEED_WAIT for the range, a call * to __btrfs_wait_marked_extents() would not know that * writeback for this range started and therefore wouldn't * wait for it to finish - we don't want to commit a * superblock that points to btree nodes/leafs for which * writeback hasn't finished yet (and without errors). * We cleanup any entries left in the io tree when committing * the transaction (through extent_io_tree_release()).
*/ if (ret == -ENOMEM) {
ret = 0;
wait_writeback = true;
} if (!ret)
ret = filemap_fdatawrite_range(mapping, start, end); if (!ret && wait_writeback)
btrfs_btree_wait_writeback_range(fs_info, start, end);
btrfs_free_extent_state(cached_state); if (ret) break;
cached_state = NULL;
cond_resched();
start = end + 1;
} return ret;
}
/* * 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 * those extents are on disk for transaction or log commit. We wait * on all the pages and clear them from the dirty pages state tree
*/ staticint __btrfs_wait_marked_extents(struct btrfs_fs_info *fs_info, struct extent_io_tree *dirty_pages)
{ struct extent_state *cached_state = NULL;
u64 start = 0;
u64 end; int ret = 0;
while (btrfs_find_first_extent_bit(dirty_pages, start, &start, &end,
EXTENT_NEED_WAIT, &cached_state)) { /* * Ignore -ENOMEM errors returned by clear_extent_bit(). * When committing the transaction, we'll remove any entries * left in the io tree. For a log commit, we don't remove them * after committing the log because the tree can be accessed * concurrently - we do it only at transaction commit time when * it's safe to do it (through extent_io_tree_release()).
*/
ret = btrfs_clear_extent_bit(dirty_pages, start, end,
EXTENT_NEED_WAIT, &cached_state); if (ret == -ENOMEM)
ret = 0; if (!ret)
btrfs_btree_wait_writeback_range(fs_info, start, end);
btrfs_free_extent_state(cached_state); if (ret) break;
cached_state = NULL;
cond_resched();
start = end + 1;
} return ret;
}
ret = __btrfs_wait_marked_extents(fs_info, dirty_pages); if ((mark & EXTENT_DIRTY_LOG1) &&
test_and_clear_bit(BTRFS_FS_LOG1_ERR, &fs_info->flags))
errors = true;
if ((mark & EXTENT_DIRTY_LOG2) &&
test_and_clear_bit(BTRFS_FS_LOG2_ERR, &fs_info->flags))
errors = true;
if (errors && !ret)
ret = -EIO; return ret;
}
/* * When btree blocks are allocated the corresponding extents are marked dirty. * This function ensures such extents are persisted on disk for transaction or * log commit. * * @trans: transaction whose dirty pages we'd like to write
*/ staticint btrfs_write_and_wait_transaction(struct btrfs_trans_handle *trans)
{ int ret; int ret2; struct extent_io_tree *dirty_pages = &trans->transaction->dirty_pages; struct btrfs_fs_info *fs_info = trans->fs_info; struct blk_plug plug;
/* * this is used to update the root pointer in the tree of tree roots. * * But, in the case of the extent allocation tree, updating the root * pointer may allocate blocks which may change the root of the extent * allocation tree. * * So, this loops and repeats and makes sure the cowonly root didn't * change while the root pointer was being updated in the metadata.
*/ staticint update_cowonly_root(struct btrfs_trans_handle *trans, struct btrfs_root *root)
{ int ret;
u64 old_root_bytenr;
u64 old_root_used; struct btrfs_fs_info *fs_info = root->fs_info; struct btrfs_root *tree_root = fs_info->tree_root;
/* * update all the cowonly tree roots on disk * * The error handling in this function may not be obvious. Any of the * failures will cause the file system to go offline. We still need * to clean up the delayed refs.
*/ static noinline int commit_cowonly_roots(struct btrfs_trans_handle *trans)
{ struct btrfs_fs_info *fs_info = trans->fs_info; struct list_head *dirty_bgs = &trans->transaction->dirty_bgs; struct list_head *io_bgs = &trans->transaction->io_bgs; struct extent_buffer *eb; int ret;
/* * At this point no one can be using this transaction to modify any tree * and no one can start another transaction to modify any tree either.
*/
ASSERT(trans->transaction->state == TRANS_STATE_COMMIT_DOING);
ret = btrfs_run_dev_stats(trans); if (ret) return ret;
ret = btrfs_run_dev_replace(trans); if (ret) return ret;
ret = btrfs_run_qgroups(trans); if (ret) return ret;
ret = btrfs_setup_space_cache(trans); if (ret) return ret;
again: while (!list_empty(&fs_info->dirty_cowonly_roots)) { struct btrfs_root *root;
ret = update_cowonly_root(trans, root); if (ret) return ret;
}
/* Now flush any delayed refs generated by updating all of the roots */
ret = btrfs_run_delayed_refs(trans, U64_MAX); if (ret) return ret;
while (!list_empty(dirty_bgs) || !list_empty(io_bgs)) {
ret = btrfs_write_dirty_block_groups(trans); if (ret) return ret;
/* * We're writing the dirty block groups, which could generate * delayed refs, which could generate more dirty block groups, * so we want to keep this flushing in this loop to make sure * everything gets run.
*/
ret = btrfs_run_delayed_refs(trans, U64_MAX); if (ret) return ret;
}
if (!list_empty(&fs_info->dirty_cowonly_roots)) goto again;
/* Update dev-replace pointer once everything is committed */
fs_info->dev_replace.committed_cursor_left =
fs_info->dev_replace.cursor_left_last_write_of_item;
return 0;
}
/* * If we had a pending drop we need to see if there are any others left in our * dead roots list, and if not clear our bit and wake any waiters.
*/ void btrfs_maybe_wake_unfinished_drop(struct btrfs_fs_info *fs_info)
{ /* * We put the drop in progress roots at the front of the list, so if the * first entry doesn't have UNFINISHED_DROP set we can wake everybody * up.
*/
spin_lock(&fs_info->trans_lock); if (!list_empty(&fs_info->dead_roots)) { struct btrfs_root *root = list_first_entry(&fs_info->dead_roots, struct btrfs_root,
root_list); if (test_bit(BTRFS_ROOT_UNFINISHED_DROP, &root->state)) {
spin_unlock(&fs_info->trans_lock); return;
}
}
spin_unlock(&fs_info->trans_lock);
btrfs_wake_unfinished_drop(fs_info);
}
/* * dead roots are old snapshots that need to be deleted. This allocates * a dirty root struct and adds it into the list of dead roots that need to * be deleted
*/ void btrfs_add_dead_root(struct btrfs_root *root)
{ struct btrfs_fs_info *fs_info = root->fs_info;
spin_lock(&fs_info->trans_lock); if (list_empty(&root->root_list)) {
btrfs_grab_root(root);
/* We want to process the partially complete drops first. */ if (test_bit(BTRFS_ROOT_UNFINISHED_DROP, &root->state))
list_add(&root->root_list, &fs_info->dead_roots); else
list_add_tail(&root->root_list, &fs_info->dead_roots);
}
spin_unlock(&fs_info->trans_lock);
}
/* * Update each subvolume root and its relocation root, if it exists, in the tree * of tree roots. Also free log roots if they exist.
*/ static noinline int commit_fs_roots(struct btrfs_trans_handle *trans)
{ struct btrfs_fs_info *fs_info = trans->fs_info; struct btrfs_root *gang[8]; int i; int ret;
/* * At this point no one can be using this transaction to modify any tree * and no one can start another transaction to modify any tree either.
*/
ASSERT(trans->transaction->state == TRANS_STATE_COMMIT_DOING);
spin_lock(&fs_info->fs_roots_radix_lock); while (1) {
ret = radix_tree_gang_lookup_tag(&fs_info->fs_roots_radix,
(void **)gang, 0,
ARRAY_SIZE(gang),
BTRFS_ROOT_TRANS_TAG); if (ret == 0) break; for (i = 0; i < ret; i++) { struct btrfs_root *root = gang[i]; int ret2;
/* * At this point we can neither have tasks logging inodes * from a root nor trying to commit a log tree.
*/
ASSERT(atomic_read(&root->log_writers) == 0);
ASSERT(atomic_read(&root->log_commit[0]) == 0);
ASSERT(atomic_read(&root->log_commit[1]) == 0);
/* * Do all special snapshot related qgroup dirty hack. * * Will do all needed qgroup inherit and dirty hack like switch commit * roots inside one transaction and write all btree into disk, to make * qgroup works.
*/ staticint qgroup_account_snapshot(struct btrfs_trans_handle *trans, struct btrfs_root *src, struct btrfs_root *parent, struct btrfs_qgroup_inherit *inherit,
u64 dst_objectid)
{ struct btrfs_fs_info *fs_info = src->fs_info; int ret;
/* * Save some performance in the case that qgroups are not enabled. If * this check races with the ioctl, rescan will kick in anyway.
*/ if (!btrfs_qgroup_full_accounting(fs_info)) return 0;
/* * Ensure dirty @src will be committed. Or, after coming * commit_fs_roots() and switch_commit_roots(), any dirty but not * recorded root will never be updated again, causing an outdated root * item.
*/
ret = record_root_in_trans(trans, src, 1); if (ret) return ret;
/* * btrfs_qgroup_inherit relies on a consistent view of the usage for the * src root, so we must run the delayed refs here. * * However this isn't particularly fool proof, because there's no * synchronization keeping us from changing the tree after this point * before we do the qgroup_inherit, or even from making changes while * we're doing the qgroup_inherit. But that's a problem for the future, * for now flush the delayed refs to narrow the race window where the * qgroup counters could end up wrong.
*/
ret = btrfs_run_delayed_refs(trans, U64_MAX); if (ret) {
btrfs_abort_transaction(trans, ret); return ret;
}
ret = commit_fs_roots(trans); if (ret) goto out;
ret = btrfs_qgroup_account_extents(trans); if (ret < 0) goto out;
/* Now qgroup are all updated, we can inherit it to new qgroups */
ret = btrfs_qgroup_inherit(trans, btrfs_root_id(src), dst_objectid,
btrfs_root_id(parent), inherit); if (ret < 0) goto out;
/* * Now we do a simplified commit transaction, which will: * 1) commit all subvolume and extent tree * To ensure all subvolume and extent tree have a valid * commit_root to accounting later insert_dir_item() * 2) write all btree blocks onto disk * This is to make sure later btree modification will be cowed * Or commit_root can be populated and cause wrong qgroup numbers * In this simplified commit, we don't really care about other trees * like chunk and root tree, as they won't affect qgroup. * And we don't write super to avoid half committed status.
*/
ret = commit_cowonly_roots(trans); if (ret) goto out;
switch_commit_roots(trans);
ret = btrfs_write_and_wait_transaction(trans); if (ret)
btrfs_handle_fs_error(fs_info, ret, "Error while writing out transaction for qgroup");
out: /* * Force parent root to be updated, as we recorded it before so its * last_trans == cur_transid. * Or it won't be committed again onto disk after later * insert_dir_item()
*/ if (!ret)
ret = record_root_in_trans(trans, parent, 1); return ret;
}
/* * new snapshots need to be created at a very specific time in the * transaction commit. This does the actual creation. * * Note: * If the error which may affect the commitment of the current transaction * happens, we should return the error number. If the error which just affect * the creation of the pending snapshots, just return 0.
*/ static noinline int create_pending_snapshot(struct btrfs_trans_handle *trans, struct btrfs_pending_snapshot *pending)
{
/* * We're inside a transaction and must make sure that any potential * allocations with GFP_KERNEL in fscrypt won't recurse back to * filesystem.
*/
nofs_flags = memalloc_nofs_save();
pending->error = fscrypt_setup_filename(&parent_inode->vfs_inode,
&pending->dentry->d_name, 0,
&fname);
memalloc_nofs_restore(nofs_flags); if (pending->error) goto free_pending;
pending->error = btrfs_get_free_objectid(tree_root, &objectid); if (pending->error) goto free_fname;
/* * Make qgroup to skip current new snapshot's qgroupid, as it is * accounted by later btrfs_qgroup_inherit().
*/
btrfs_set_skip_qgroup(trans, objectid);
btrfs_reloc_pre_snapshot(pending, &to_reserve);
if (to_reserve > 0) {
pending->error = btrfs_block_rsv_add(fs_info,
&pending->block_rsv,
to_reserve,
BTRFS_RESERVE_NO_FLUSH); if (pending->error) goto clear_skip_qgroup;
}
/* * insert the directory item
*/
ret = btrfs_set_inode_index(parent_inode, &index); if (ret) {
btrfs_abort_transaction(trans, ret); goto fail;
}
/* check if there is a file/dir which has the same name. */
dir_item = btrfs_lookup_dir_item(NULL, parent_root, path,
btrfs_ino(parent_inode),
&fname.disk_name, 0); if (dir_item != NULL && !IS_ERR(dir_item)) {
pending->error = -EEXIST; goto dir_item_existed;
} elseif (IS_ERR(dir_item)) {
ret = PTR_ERR(dir_item);
btrfs_abort_transaction(trans, ret); goto fail;
}
btrfs_release_path(path);
ret = btrfs_create_qgroup(trans, objectid); if (ret && ret != -EEXIST) { if (ret != -ENOTCONN || btrfs_qgroup_enabled(fs_info)) {
btrfs_abort_transaction(trans, ret); goto fail;
}
}
/* * pull in the delayed directory update * and the delayed inode item * otherwise we corrupt the FS during * snapshot
*/
ret = btrfs_run_delayed_items(trans); if (ret) { /* Transaction aborted */
btrfs_abort_transaction(trans, ret); goto fail;
}
ret = record_root_in_trans(trans, root, 0); if (ret) {
btrfs_abort_transaction(trans, ret); goto fail;
}
btrfs_set_root_last_snapshot(&root->root_item, trans->transid);
memcpy(new_root_item, &root->root_item, sizeof(*new_root_item));
btrfs_check_and_init_root_item(new_root_item);
old = btrfs_lock_root_node(root);
ret = btrfs_cow_block(trans, root, old, NULL, 0, &old,
BTRFS_NESTING_COW); if (ret) {
btrfs_tree_unlock(old);
free_extent_buffer(old);
btrfs_abort_transaction(trans, ret); goto fail;
}
ret = btrfs_copy_root(trans, root, old, &tmp, objectid); /* clean up in any case */
btrfs_tree_unlock(old);
free_extent_buffer(old); if (ret) {
btrfs_abort_transaction(trans, ret); goto fail;
} /* see comments in should_cow_block() */
set_bit(BTRFS_ROOT_FORCE_COW, &root->state);
smp_mb__after_atomic();
btrfs_set_root_node(new_root_item, tmp); /* record when the snapshot was created in key.offset */
key.offset = trans->transid;
ret = btrfs_insert_root(trans, tree_root, &key, new_root_item);
btrfs_tree_unlock(tmp);
free_extent_buffer(tmp); if (ret) {
btrfs_abort_transaction(trans, ret); goto fail;
}
ret = btrfs_reloc_post_snapshot(trans, pending); if (ret) {
btrfs_abort_transaction(trans, ret); goto fail;
}
/* * Do special qgroup accounting for snapshot, as we do some qgroup * snapshot hack to do fast snapshot. * To co-operate with that hack, we do hack again. * Or snapshot will be greatly slowed down by a subtree qgroup rescan
*/ if (btrfs_qgroup_mode(fs_info) == BTRFS_QGROUP_MODE_FULL)
ret = qgroup_account_snapshot(trans, root, parent_root,
pending->inherit, objectid); elseif (btrfs_qgroup_mode(fs_info) == BTRFS_QGROUP_MODE_SIMPLE)
ret = btrfs_qgroup_inherit(trans, btrfs_root_id(root), objectid,
btrfs_root_id(parent_root), pending->inherit); if (ret < 0) goto fail;
ret = btrfs_insert_dir_item(trans, &fname.disk_name,
parent_inode, &key, BTRFS_FT_DIR,
index); if (ret) {
btrfs_abort_transaction(trans, ret); goto fail;
}
btrfs_i_size_write(parent_inode, parent_inode->vfs_inode.i_size +
fname.disk_name.len * 2);
inode_set_mtime_to_ts(&parent_inode->vfs_inode,
inode_set_ctime_current(&parent_inode->vfs_inode));
ret = btrfs_update_inode_fallback(trans, parent_inode); if (ret) {
btrfs_abort_transaction(trans, ret); goto fail;
}
ret = btrfs_uuid_tree_add(trans, new_root_item->uuid,
BTRFS_UUID_KEY_SUBVOL,
objectid); if (ret) {
btrfs_abort_transaction(trans, ret); goto fail;
} if (!btrfs_is_empty_uuid(new_root_item->received_uuid)) {
ret = btrfs_uuid_tree_add(trans, new_root_item->received_uuid,
BTRFS_UUID_KEY_RECEIVED_SUBVOL,
objectid); if (ret && ret != -EEXIST) {
btrfs_abort_transaction(trans, ret); goto fail;
}
}
int btrfs_transaction_blocked(struct btrfs_fs_info *info)
{ struct btrfs_transaction *trans; int ret = 0;
spin_lock(&info->trans_lock);
trans = info->running_transaction; if (trans)
ret = is_transaction_blocked(trans);
spin_unlock(&info->trans_lock); return ret;
}
/* Kick the transaction kthread. */
set_bit(BTRFS_FS_COMMIT_TRANS, &fs_info->flags);
wake_up_process(fs_info->transaction_kthread);
/* take transaction reference */
cur_trans = trans->transaction;
refcount_inc(&cur_trans->use_count);
btrfs_end_transaction(trans);
/* * Wait for the current transaction commit to start and block * subsequent transaction joins
*/
btrfs_might_wait_for_state(fs_info, BTRFS_LOCKDEP_TRANS_COMMIT_PREP);
wait_event(fs_info->transaction_blocked_wait,
cur_trans->state >= TRANS_STATE_COMMIT_START ||
TRANS_ABORTED(cur_trans));
btrfs_put_transaction(cur_trans);
}
/* * If there is a running transaction commit it or if it's already committing, * wait for its commit to complete. Does not start and commit a new transaction * if there isn't any running.
*/ int btrfs_commit_current_transaction(struct btrfs_root *root)
{ struct btrfs_trans_handle *trans;
trans = btrfs_attach_transaction_barrier(root); if (IS_ERR(trans)) { int ret = PTR_ERR(trans);
/* * If the transaction is removed from the list, it means this * transaction has been committed successfully, so it is impossible * to call the cleanup function.
*/
BUG_ON(list_empty(&cur_trans->list));
if (cur_trans == fs_info->running_transaction) {
cur_trans->state = TRANS_STATE_COMMIT_DOING;
spin_unlock(&fs_info->trans_lock);
/* * The thread has already released the lockdep map as reader * already in btrfs_commit_transaction().
*/
btrfs_might_wait_for_event(fs_info, btrfs_trans_num_writers);
wait_event(cur_trans->writer_wait,
atomic_read(&cur_trans->num_writers) == 1);
spin_lock(&fs_info->trans_lock);
}
/* * Now that we know no one else is still using the transaction we can * remove the transaction from the list of transactions. This avoids * the transaction kthread from cleaning up the transaction while some * other task is still using it, which could result in a use-after-free * on things like log trees, as it forces the transaction kthread to * wait for this transaction to be cleaned up by us.
*/
list_del_init(&cur_trans->list);
spin_lock(&fs_info->trans_lock); if (cur_trans == fs_info->running_transaction)
fs_info->running_transaction = NULL;
spin_unlock(&fs_info->trans_lock);
if (trans->type & __TRANS_FREEZABLE)
sb_end_intwrite(fs_info->sb);
btrfs_put_transaction(cur_trans);
btrfs_put_transaction(cur_trans);
trace_btrfs_transaction_commit(fs_info);
if (current->journal_info == trans)
current->journal_info = NULL;
/* * If relocation is running, we can't cancel scrub because that will * result in a deadlock. Before relocating a block group, relocation * pauses scrub, then starts and commits a transaction before unpausing * scrub. If the transaction commit is being done by the relocation * task or triggered by another task and the relocation task is waiting * for the commit, and we end up here due to an error in the commit * path, then calling btrfs_scrub_cancel() will deadlock, as we are * asking for scrub to stop while having it asked to be paused higher * above in relocation code.
*/ if (!test_bit(BTRFS_FS_RELOC_RUNNING, &fs_info->flags))
btrfs_scrub_cancel(fs_info);
/* * Release reserved delayed ref space of all pending block groups of the * transaction and remove them from the list
*/ staticvoid btrfs_cleanup_pending_block_groups(struct btrfs_trans_handle *trans)
{ struct btrfs_fs_info *fs_info = trans->fs_info; struct btrfs_block_group *block_group, *tmp;
list_for_each_entry_safe(block_group, tmp, &trans->new_bgs, bg_list) {
btrfs_dec_delayed_refs_rsv_bg_inserts(fs_info); /* * Not strictly necessary to lock, as no other task will be using a * block_group on the new_bgs list during a transaction abort.
*/
spin_lock(&fs_info->unused_bgs_lock);
list_del_init(&block_group->bg_list);
btrfs_put_block_group(block_group);
spin_unlock(&fs_info->unused_bgs_lock);
}
}
staticinlineint btrfs_start_delalloc_flush(struct btrfs_fs_info *fs_info)
{ /* * We use try_to_writeback_inodes_sb() here because if we used * btrfs_start_delalloc_roots we would deadlock with fs freeze. * Currently are holding the fs freeze lock, if we do an async flush * we'll do btrfs_join_transaction() and deadlock because we need to * wait for the fs freeze lock. Using the direct flushing we benefit * from already being in a transaction and our join_transaction doesn't * have to re-take the fs freeze lock. * * Note that try_to_writeback_inodes_sb() will only trigger writeback * if it can read lock sb->s_umount. It will always be able to lock it, * except when the filesystem is being unmounted or being frozen, but in * those cases sync_filesystem() is called, which results in calling * writeback_inodes_sb() while holding a write lock on sb->s_umount. * Note that we don't call writeback_inodes_sb() directly, because it * will emit a warning if sb->s_umount is not locked.
*/ if (btrfs_test_opt(fs_info, FLUSHONCOMMIT))
try_to_writeback_inodes_sb(fs_info->sb, WB_REASON_SYNC); return 0;
}
/* * Add a pending snapshot associated with the given transaction handle to the * respective handle. This must be called after the transaction commit started * and while holding fs_info->trans_lock. * This serves to guarantee a caller of btrfs_commit_transaction() that it can * safely free the pending snapshot pointer in case btrfs_commit_transaction() * returns an error.
*/ staticvoid add_pending_snapshot(struct btrfs_trans_handle *trans)
{ struct btrfs_transaction *cur_trans = trans->transaction;
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.