On Tue, Mar 26, 2019 at 3:57 AM robbieko <robbi...@synology.com> wrote:
>
> From: Robbie Ko <robbi...@synology.com>
>
> When doing fallocate, we first add the range to the reserve_list
> and then reserve the quota.
> If quota reservation fails, we'll release all reserved parts of
> reserve_list.
> However, cur_offset is not updated to indicate that this
> range is already been inserted into the list.
> Therefore, the same range is freed twice.
> Once at list_for_each_entry loop, and once at the end of the
> function.
> This will result in WARN_ON on bytes_may_use when we free the
> remaining space.
>
> At the end, under the 'out' label we have a call to:
>    btrfs_free_reserved_data_space(inode, data_reserved, alloc_start,
> alloc_end - cur_offset);
> The start offset, third argument, should be cur_offset.
> Everything from alloc_start to cur_offset was freed by the
> list_for_each_entry_safe_loop.
>
> Fixes: 18513091af94 ("btrfs: update btrfs_space_info's bytes_may_use timely")
> Signed-off-by: Robbie Ko <robbi...@synology.com>

Reviewed-by: Filipe Manana <fdman...@suse.com>

Now it looks good, thanks.

> ---
>  fs/btrfs/file.c | 3 ++-
>  1 file changed, 2 insertions(+), 1 deletion(-)
>
> diff --git a/fs/btrfs/file.c b/fs/btrfs/file.c
> index 34fe8a5..0832449 100644
> --- a/fs/btrfs/file.c
> +++ b/fs/btrfs/file.c
> @@ -3132,6 +3132,7 @@ static long btrfs_fallocate(struct file *file, int mode,
>                         ret = btrfs_qgroup_reserve_data(inode, &data_reserved,
>                                         cur_offset, last_byte - cur_offset);
>                         if (ret < 0) {
> +                               cur_offset = last_byte;
>                                 free_extent_map(em);
>                                 break;
>                         }
> @@ -3181,7 +3182,7 @@ static long btrfs_fallocate(struct file *file, int mode,
>         /* Let go of our reservation. */
>         if (ret != 0 && !(mode & FALLOC_FL_ZERO_RANGE))
>                 btrfs_free_reserved_data_space(inode, data_reserved,
> -                               alloc_start, alloc_end - cur_offset);
> +                               cur_offset, alloc_end - cur_offset);
>         extent_changeset_free(data_reserved);
>         return ret;
>  }
> --
> 1.9.1
>


-- 
Filipe David Manana,

“Whether you think you can, or you think you can't — you're right.”

Reply via email to