Btrfs: fix deadlock when throttling transactions
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 <josef@redhat.com> Signed-off-by: Chris Mason <chris.mason@oracle.com>
This commit is contained in:
Родитель
a65917156e
Коммит
81317fdedd
|
@ -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);
|
||||
|
|
Загрузка…
Ссылка в новой задаче