Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit e4a2bcac authored by Josef Bacik's avatar Josef Bacik
Browse files

Btrfs: if we aren't committing just end the transaction if we error out



I hit a deadlock where transaction commit was waiting on num_writers to be
0.  This happened because somebody came into btrfs_commit_transaction and
noticed we had aborted and it went to cleanup_transaction.  This shouldn't
happen because cleanup_transaction is really to fixup a bad commit, it
doesn't do the normal trans handle cleanup things.  So if we have an error
just do the normal btrfs_end_transaction dance and return.  Once we are in
the actual commit path we can use cleanup_transaction and be good to go.
Thanks,

Signed-off-by: default avatarJosef Bacik <jbacik@fusionio.com>
parent 3e04e7f1
Loading
Loading
Loading
Loading
+12 −6
Original line number Diff line number Diff line
@@ -1476,21 +1476,25 @@ int btrfs_commit_transaction(struct btrfs_trans_handle *trans,
	ret = btrfs_run_ordered_operations(root, 0);
	if (ret) {
		btrfs_abort_transaction(trans, root, ret);
		goto cleanup_transaction;
		btrfs_end_transaction(trans, root);
		return ret;
	}

	/* Stop the commit early if ->aborted is set */
	if (unlikely(ACCESS_ONCE(cur_trans->aborted))) {
		ret = cur_trans->aborted;
		goto cleanup_transaction;
		btrfs_end_transaction(trans, root);
		return ret;
	}

	/* make a pass through all the delayed refs we have so far
	 * any runnings procs may add more while we are here
	 */
	ret = btrfs_run_delayed_refs(trans, root, 0);
	if (ret)
		goto cleanup_transaction;
	if (ret) {
		btrfs_end_transaction(trans, root);
		return ret;
	}

	btrfs_trans_release_metadata(trans, root);
	trans->block_rsv = NULL;
@@ -1507,8 +1511,10 @@ int btrfs_commit_transaction(struct btrfs_trans_handle *trans,
		btrfs_create_pending_block_groups(trans, root);

	ret = btrfs_run_delayed_refs(trans, root, 0);
	if (ret)
		goto cleanup_transaction;
	if (ret) {
		btrfs_end_transaction(trans, root);
		return ret;
	}

	spin_lock(&cur_trans->commit_lock);
	if (cur_trans->in_commit) {