btrfs: merge unlocking to common exit block in btrfs_commit_transaction
The tree_log_mutex and reloc_mutex locks are properly nested so we can simplify error handling and add labels for them. This reduces line count of the function. Reviewed-by: Anand Jain <anand.jain@oracle.com> Signed-off-by: David Sterba <dsterba@suse.com>
This commit is contained in:
parent
15b6e8a83e
commit
56e9f6ea32
|
@ -2194,10 +2194,8 @@ int btrfs_commit_transaction(struct btrfs_trans_handle *trans)
|
||||||
* core function of the snapshot creation.
|
* core function of the snapshot creation.
|
||||||
*/
|
*/
|
||||||
ret = create_pending_snapshots(trans);
|
ret = create_pending_snapshots(trans);
|
||||||
if (ret) {
|
if (ret)
|
||||||
mutex_unlock(&fs_info->reloc_mutex);
|
goto unlock_reloc;
|
||||||
goto scrub_continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* We insert the dir indexes of the snapshots and update the inode
|
* We insert the dir indexes of the snapshots and update the inode
|
||||||
|
@ -2210,16 +2208,12 @@ int btrfs_commit_transaction(struct btrfs_trans_handle *trans)
|
||||||
* the nodes and leaves.
|
* the nodes and leaves.
|
||||||
*/
|
*/
|
||||||
ret = btrfs_run_delayed_items(trans);
|
ret = btrfs_run_delayed_items(trans);
|
||||||
if (ret) {
|
if (ret)
|
||||||
mutex_unlock(&fs_info->reloc_mutex);
|
goto unlock_reloc;
|
||||||
goto scrub_continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
ret = btrfs_run_delayed_refs(trans, (unsigned long)-1);
|
ret = btrfs_run_delayed_refs(trans, (unsigned long)-1);
|
||||||
if (ret) {
|
if (ret)
|
||||||
mutex_unlock(&fs_info->reloc_mutex);
|
goto unlock_reloc;
|
||||||
goto scrub_continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* make sure none of the code above managed to slip in a
|
* make sure none of the code above managed to slip in a
|
||||||
|
@ -2245,11 +2239,8 @@ int btrfs_commit_transaction(struct btrfs_trans_handle *trans)
|
||||||
mutex_lock(&fs_info->tree_log_mutex);
|
mutex_lock(&fs_info->tree_log_mutex);
|
||||||
|
|
||||||
ret = commit_fs_roots(trans);
|
ret = commit_fs_roots(trans);
|
||||||
if (ret) {
|
if (ret)
|
||||||
mutex_unlock(&fs_info->tree_log_mutex);
|
goto unlock_tree_log;
|
||||||
mutex_unlock(&fs_info->reloc_mutex);
|
|
||||||
goto scrub_continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Since the transaction is done, we can apply the pending changes
|
* Since the transaction is done, we can apply the pending changes
|
||||||
|
@ -2267,29 +2258,20 @@ int btrfs_commit_transaction(struct btrfs_trans_handle *trans)
|
||||||
* new delayed refs. Must handle them or qgroup can be wrong.
|
* new delayed refs. Must handle them or qgroup can be wrong.
|
||||||
*/
|
*/
|
||||||
ret = btrfs_run_delayed_refs(trans, (unsigned long)-1);
|
ret = btrfs_run_delayed_refs(trans, (unsigned long)-1);
|
||||||
if (ret) {
|
if (ret)
|
||||||
mutex_unlock(&fs_info->tree_log_mutex);
|
goto unlock_tree_log;
|
||||||
mutex_unlock(&fs_info->reloc_mutex);
|
|
||||||
goto scrub_continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Since fs roots are all committed, we can get a quite accurate
|
* Since fs roots are all committed, we can get a quite accurate
|
||||||
* new_roots. So let's do quota accounting.
|
* new_roots. So let's do quota accounting.
|
||||||
*/
|
*/
|
||||||
ret = btrfs_qgroup_account_extents(trans);
|
ret = btrfs_qgroup_account_extents(trans);
|
||||||
if (ret < 0) {
|
if (ret < 0)
|
||||||
mutex_unlock(&fs_info->tree_log_mutex);
|
goto unlock_tree_log;
|
||||||
mutex_unlock(&fs_info->reloc_mutex);
|
|
||||||
goto scrub_continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
ret = commit_cowonly_roots(trans);
|
ret = commit_cowonly_roots(trans);
|
||||||
if (ret) {
|
if (ret)
|
||||||
mutex_unlock(&fs_info->tree_log_mutex);
|
goto unlock_tree_log;
|
||||||
mutex_unlock(&fs_info->reloc_mutex);
|
|
||||||
goto scrub_continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The tasks which save the space cache and inode cache may also
|
* The tasks which save the space cache and inode cache may also
|
||||||
|
@ -2297,9 +2279,7 @@ int btrfs_commit_transaction(struct btrfs_trans_handle *trans)
|
||||||
*/
|
*/
|
||||||
if (TRANS_ABORTED(cur_trans)) {
|
if (TRANS_ABORTED(cur_trans)) {
|
||||||
ret = cur_trans->aborted;
|
ret = cur_trans->aborted;
|
||||||
mutex_unlock(&fs_info->tree_log_mutex);
|
goto unlock_tree_log;
|
||||||
mutex_unlock(&fs_info->reloc_mutex);
|
|
||||||
goto scrub_continue;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
btrfs_prepare_extent_commit(fs_info);
|
btrfs_prepare_extent_commit(fs_info);
|
||||||
|
@ -2346,6 +2326,10 @@ int btrfs_commit_transaction(struct btrfs_trans_handle *trans)
|
||||||
if (ret) {
|
if (ret) {
|
||||||
btrfs_handle_fs_error(fs_info, ret,
|
btrfs_handle_fs_error(fs_info, ret,
|
||||||
"Error while writing out transaction");
|
"Error while writing out transaction");
|
||||||
|
/*
|
||||||
|
* reloc_mutex has been unlocked, tree_log_mutex is still held
|
||||||
|
* but we can't jump to unlock_tree_log causing double unlock
|
||||||
|
*/
|
||||||
mutex_unlock(&fs_info->tree_log_mutex);
|
mutex_unlock(&fs_info->tree_log_mutex);
|
||||||
goto scrub_continue;
|
goto scrub_continue;
|
||||||
}
|
}
|
||||||
|
@ -2394,6 +2378,10 @@ int btrfs_commit_transaction(struct btrfs_trans_handle *trans)
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
|
unlock_tree_log:
|
||||||
|
mutex_unlock(&fs_info->tree_log_mutex);
|
||||||
|
unlock_reloc:
|
||||||
|
mutex_unlock(&fs_info->reloc_mutex);
|
||||||
scrub_continue:
|
scrub_continue:
|
||||||
btrfs_scrub_continue(fs_info);
|
btrfs_scrub_continue(fs_info);
|
||||||
cleanup_transaction:
|
cleanup_transaction:
|
||||||
|
|
Loading…
Reference in New Issue