On 15.07.19 г. 16:16 ч., Johannes Thumshirn wrote:
> btrfs_get_io_geometry() calls btrfs_get_chunk_map() to acquire a reference
> on a extent_map, but on normal operation it does not drop this reference
> anymore.
>
> This leads to excessive kmemleak reports.
>
> Always call free_extent_map(), not just in the error case.
>
> Fixes: 5f1411265e16 ("btrfs: Introduce btrfs_io_geometry infrastructure")
> Signed-off-by: Johannes Thumshirn <jthumsh...@suse.de>
My bad:
Reviewed-by: Nikolay Borisov <nbori...@suse.com>
> ---
> fs/btrfs/volumes.c | 10 +++++++---
> 1 file changed, 7 insertions(+), 3 deletions(-)
>
> diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c
> index a13ddba1ebc3..d74b74ca07af 100644
> --- a/fs/btrfs/volumes.c
> +++ b/fs/btrfs/volumes.c
> @@ -5941,6 +5941,7 @@ int btrfs_get_io_geometry(struct btrfs_fs_info
> *fs_info, enum btrfs_map_op op,
> u64 stripe_len;
> u64 raid56_full_stripe_start = (u64)-1;
> int data_stripes;
> + int ret = 0;
>
> ASSERT(op != BTRFS_MAP_DISCARD);
>
> @@ -5961,8 +5962,8 @@ int btrfs_get_io_geometry(struct btrfs_fs_info
> *fs_info, enum btrfs_map_op op,
> btrfs_crit(fs_info,
> "stripe math has gone wrong, stripe_offset=%llu offset=%llu start=%llu
> logical=%llu stripe_len=%llu",
> stripe_offset, offset, em->start, logical, stripe_len);
> - free_extent_map(em);
> - return -EINVAL;
> + ret = -EINVAL;
> + goto out;
> }
>
> /* stripe_offset is the offset of this block in its stripe */
> @@ -6009,7 +6010,10 @@ int btrfs_get_io_geometry(struct btrfs_fs_info
> *fs_info, enum btrfs_map_op op,
> io_geom->stripe_offset = stripe_offset;
> io_geom->raid56_stripe_offset = raid56_full_stripe_start;
>
> - return 0;
> +out:
> + /* once for us */
> + free_extent_map(em);
> + return ret;
> }
>
> static int __btrfs_map_block(struct btrfs_fs_info *fs_info,
>