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:
David Sterba 2019-11-28 16:03:00 +01:00
parent 15b6e8a83e
commit 56e9f6ea32
1 changed files with 23 additions and 35 deletions

View File

@ -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: