On 2019/1/17 上午12:00, Josef Bacik wrote:
> qgroups will do the old roots lookup at delayed ref time, which could be
> while walking down the extent root while running a delayed ref.  This
> should be fine, except we specifically lock eb's in the backref walking
> code irrespective of path->skip_locking, which deadlocks the system.
> Fix up the backref code to honor path->skip_locking, nobody will be
> modifying the commit_root when we're searching so it's completely safe
> to do.  Thanks,
> 
> Signed-off-by: Josef Bacik <[email protected]>

Reviewed-by: Qu Wenruo <[email protected]>

Thanks,
Qu

> ---
>  fs/btrfs/backref.c | 16 ++++++++++------
>  1 file changed, 10 insertions(+), 6 deletions(-)
> 
> diff --git a/fs/btrfs/backref.c b/fs/btrfs/backref.c
> index 78556447e1d5..973e8251b1bf 100644
> --- a/fs/btrfs/backref.c
> +++ b/fs/btrfs/backref.c
> @@ -712,7 +712,7 @@ static int resolve_indirect_refs(struct btrfs_fs_info 
> *fs_info,
>   * read tree blocks and add keys where required.
>   */
>  static int add_missing_keys(struct btrfs_fs_info *fs_info,
> -                         struct preftrees *preftrees)
> +                         struct preftrees *preftrees, bool lock)
>  {
>       struct prelim_ref *ref;
>       struct extent_buffer *eb;
> @@ -737,12 +737,14 @@ static int add_missing_keys(struct btrfs_fs_info 
> *fs_info,
>                       free_extent_buffer(eb);
>                       return -EIO;
>               }
> -             btrfs_tree_read_lock(eb);
> +             if (lock)
> +                     btrfs_tree_read_lock(eb);
>               if (btrfs_header_level(eb) == 0)
>                       btrfs_item_key_to_cpu(eb, &ref->key_for_search, 0);
>               else
>                       btrfs_node_key_to_cpu(eb, &ref->key_for_search, 0);
> -             btrfs_tree_read_unlock(eb);
> +             if (lock)
> +                     btrfs_tree_read_unlock(eb);
>               free_extent_buffer(eb);
>               prelim_ref_insert(fs_info, &preftrees->indirect, ref, NULL);
>               cond_resched();
> @@ -1227,7 +1229,7 @@ static int find_parent_nodes(struct btrfs_trans_handle 
> *trans,
>  
>       btrfs_release_path(path);
>  
> -     ret = add_missing_keys(fs_info, &preftrees);
> +     ret = add_missing_keys(fs_info, &preftrees, path->skip_locking == 0);
>       if (ret)
>               goto out;
>  
> @@ -1288,11 +1290,13 @@ static int find_parent_nodes(struct 
> btrfs_trans_handle *trans,
>                                       ret = -EIO;
>                                       goto out;
>                               }
> -                             btrfs_tree_read_lock(eb);
> +                             if (!path->skip_locking)
> +                                     btrfs_tree_read_lock(eb);
>                               btrfs_set_lock_blocking_rw(eb, BTRFS_READ_LOCK);
>                               ret = find_extent_in_eb(eb, bytenr,
>                                                       *extent_item_pos, &eie, 
> ignore_offset);
> -                             btrfs_tree_read_unlock_blocking(eb);
> +                             if (!path->skip_locking)
> +                                     btrfs_tree_read_unlock_blocking(eb);
>                               free_extent_buffer(eb);
>                               if (ret < 0)
>                                       goto out;
> 

Attachment: signature.asc
Description: OpenPGP digital signature

Reply via email to