mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-08-23 09:19:51 +00:00
Btrfs: fix a deadlock in aborting transaction due to ENOSPC
When committing a transaction, we may bail out of running delayed refs due to ENOSPC, and then abort the current transaction to flip into readonly. But we'll hit a deadlock on ref head's lock since we forget to release its lock and other cleanup stuff. Signed-off-by: Liu Bo <bo.li.liu@oracle.com> Signed-off-by: Chris Mason <chris.mason@fusionio.com>
This commit is contained in:
parent
6c1500f22a
commit
37c4146d22
1 changed files with 7 additions and 0 deletions
|
@ -2297,6 +2297,9 @@ static noinline int run_clustered_refs(struct btrfs_trans_handle *trans,
|
||||||
kfree(extent_op);
|
kfree(extent_op);
|
||||||
|
|
||||||
if (ret) {
|
if (ret) {
|
||||||
|
list_del_init(&locked_ref->cluster);
|
||||||
|
mutex_unlock(&locked_ref->mutex);
|
||||||
|
|
||||||
printk(KERN_DEBUG "btrfs: run_delayed_extent_op returned %d\n", ret);
|
printk(KERN_DEBUG "btrfs: run_delayed_extent_op returned %d\n", ret);
|
||||||
spin_lock(&delayed_refs->lock);
|
spin_lock(&delayed_refs->lock);
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -2339,6 +2342,10 @@ static noinline int run_clustered_refs(struct btrfs_trans_handle *trans,
|
||||||
count++;
|
count++;
|
||||||
|
|
||||||
if (ret) {
|
if (ret) {
|
||||||
|
if (locked_ref) {
|
||||||
|
list_del_init(&locked_ref->cluster);
|
||||||
|
mutex_unlock(&locked_ref->mutex);
|
||||||
|
}
|
||||||
printk(KERN_DEBUG "btrfs: run_one_delayed_ref returned %d\n", ret);
|
printk(KERN_DEBUG "btrfs: run_one_delayed_ref returned %d\n", ret);
|
||||||
spin_lock(&delayed_refs->lock);
|
spin_lock(&delayed_refs->lock);
|
||||||
return ret;
|
return ret;
|
||||||
|
|
Loading…
Reference in a new issue