Skip to content

Commit

Permalink
Btrfs: fix deadlock when throttling transactions
Browse files Browse the repository at this point in the history
Hit this nice little deadlock.  What happens is this

__btrfs_end_transaction with throttle set, --use_count so it equals 0
  btrfs_commit_transaction
    <somebody else actually manages to start the commit>
    btrfs_end_transaction --use_count so now its -1 <== BAD
      we just return and wait on the transaction

This is bad because we just return after our use_count is -1 and don't let go
of our num_writer count on the transaction, so the guy committing the
transaction just sits there forever.  Fix this by inc'ing our use_count if we're
going to call commit_transaction so that if we call btrfs_end_transaction it's
valid.  Thanks,

Signed-off-by: Josef Bacik <[email protected]>
Signed-off-by: Chris Mason <[email protected]>
  • Loading branch information
Josef Bacik authored and chrismason-xx committed Jul 27, 2011
1 parent a659171 commit 81317fd
Showing 1 changed file with 9 additions and 2 deletions.
11 changes: 9 additions & 2 deletions fs/btrfs/transaction.c
Original file line number Diff line number Diff line change
Expand Up @@ -497,10 +497,17 @@ static int __btrfs_end_transaction(struct btrfs_trans_handle *trans,
}

if (lock && cur_trans->blocked && !cur_trans->in_commit) {
if (throttle)
if (throttle) {
/*
* We may race with somebody else here so end up having
* to call end_transaction on ourselves again, so inc
* our use_count.
*/
trans->use_count++;
return btrfs_commit_transaction(trans, root);
else
} else {
wake_up_process(info->transaction_kthread);
}
}

WARN_ON(cur_trans != info->running_transaction);
Expand Down

0 comments on commit 81317fd

Please sign in to comment.