btrfs: fix locking issues in find_parent_nodes()
- We might unlock head->mutex while it was not locked - We might leave the function without unlocking delayed_refs->lock Signed-off-by: Li Zefan <lizf@cn.fujitsu.com> Signed-off-by: Chris Mason <chris.mason@oracle.com>
This commit is contained in:
parent
e77266e4c4
commit
d3b010640e
|
@ -583,7 +583,7 @@ static int find_parent_nodes(struct btrfs_trans_handle *trans,
|
||||||
struct btrfs_path *path;
|
struct btrfs_path *path;
|
||||||
struct btrfs_key info_key = { 0 };
|
struct btrfs_key info_key = { 0 };
|
||||||
struct btrfs_delayed_ref_root *delayed_refs = NULL;
|
struct btrfs_delayed_ref_root *delayed_refs = NULL;
|
||||||
struct btrfs_delayed_ref_head *head = NULL;
|
struct btrfs_delayed_ref_head *head;
|
||||||
int info_level = 0;
|
int info_level = 0;
|
||||||
int ret;
|
int ret;
|
||||||
struct list_head prefs_delayed;
|
struct list_head prefs_delayed;
|
||||||
|
@ -607,6 +607,8 @@ static int find_parent_nodes(struct btrfs_trans_handle *trans,
|
||||||
* at a specified point in time
|
* at a specified point in time
|
||||||
*/
|
*/
|
||||||
again:
|
again:
|
||||||
|
head = NULL;
|
||||||
|
|
||||||
ret = btrfs_search_slot(trans, fs_info->extent_root, &key, path, 0, 0);
|
ret = btrfs_search_slot(trans, fs_info->extent_root, &key, path, 0, 0);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
goto out;
|
goto out;
|
||||||
|
@ -635,8 +637,10 @@ again:
|
||||||
goto again;
|
goto again;
|
||||||
}
|
}
|
||||||
ret = __add_delayed_refs(head, seq, &info_key, &prefs_delayed);
|
ret = __add_delayed_refs(head, seq, &info_key, &prefs_delayed);
|
||||||
if (ret)
|
if (ret) {
|
||||||
|
spin_unlock(&delayed_refs->lock);
|
||||||
goto out;
|
goto out;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
spin_unlock(&delayed_refs->lock);
|
spin_unlock(&delayed_refs->lock);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue