On Tue, Mar 26, 2019 at 3:57 AM robbieko <robbieko@xxxxxxxxxxxx> wrote:
>
> From: Robbie Ko <robbieko@xxxxxxxxxxxx>
>
> 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 <robbieko@xxxxxxxxxxxx>
Reviewed-by: Filipe Manana <fdmanana@xxxxxxxx>
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.”