diff mbox series

[v4,1/3] btrfs: zoned: reset zones of relocated block groups

Message ID d3aec3e168a547dcc39a764f242d1df9d3489928.1618494550.git.johannes.thumshirn@wdc.com (mailing list archive)
State New, archived
Headers show
Series btrfs: zoned: automatic BG reclaim | expand

Commit Message

Johannes Thumshirn April 15, 2021, 1:58 p.m. UTC
When relocating a block group the freed up space is not discarded in one
big block, but each extent is discarded on it's own with -odisard=sync.

For a zoned filesystem we need to discard the whole block group at once,
so btrfs_discard_extent() will translate the discard into a
REQ_OP_ZONE_RESET operation, which then resets the device's zone.

Link: https://lore.kernel.org/linux-btrfs/459e2932c48e12e883dcfd3dda828d9da251d5b5.1617962110.git.johannes.thumshirn@wdc.com
Signed-off-by: Johannes Thumshirn <johannes.thumshirn@wdc.com>
---
 fs/btrfs/volumes.c | 21 +++++++++++++++++----
 1 file changed, 17 insertions(+), 4 deletions(-)

Comments

Josef Bacik April 15, 2021, 6:26 p.m. UTC | #1
On 4/15/21 9:58 AM, Johannes Thumshirn wrote:
> When relocating a block group the freed up space is not discarded in one
> big block, but each extent is discarded on it's own with -odisard=sync.
> 
> For a zoned filesystem we need to discard the whole block group at once,
> so btrfs_discard_extent() will translate the discard into a
> REQ_OP_ZONE_RESET operation, which then resets the device's zone.
> 
> Link: https://lore.kernel.org/linux-btrfs/459e2932c48e12e883dcfd3dda828d9da251d5b5.1617962110.git.johannes.thumshirn@wdc.com
> Signed-off-by: Johannes Thumshirn <johannes.thumshirn@wdc.com>

What would be cool is if we could disable discard per bg so we don't discard at 
all during the relocation, and then discard the whole block group no matter if 
we have zoned or not.  However not really something you need to do, just 
thinking out loud

Reviewed-by: Josef Bacik <josef@toxicpanda.com>

Thanks,

Josef
Johannes Thumshirn April 16, 2021, 5:50 a.m. UTC | #2
On 15/04/2021 20:26, Josef Bacik wrote:
> On 4/15/21 9:58 AM, Johannes Thumshirn wrote:
>> When relocating a block group the freed up space is not discarded in one
>> big block, but each extent is discarded on it's own with -odisard=sync.
>>
>> For a zoned filesystem we need to discard the whole block group at once,
>> so btrfs_discard_extent() will translate the discard into a
>> REQ_OP_ZONE_RESET operation, which then resets the device's zone.
>>
>> Link: https://lore.kernel.org/linux-btrfs/459e2932c48e12e883dcfd3dda828d9da251d5b5.1617962110.git.johannes.thumshirn@wdc.com
>> Signed-off-by: Johannes Thumshirn <johannes.thumshirn@wdc.com>
> 
> What would be cool is if we could disable discard per bg so we don't discard at 
> all during the relocation, and then discard the whole block group no matter if 
> we have zoned or not.  However not really something you need to do, just 
> thinking out loud

I could say I'll add it to my queue, but that's already so long, I have no
idea when that's gonna happen.


> Reviewed-by: Josef Bacik <josef@toxicpanda.com>

Thanks
Filipe Manana April 16, 2021, 9:11 a.m. UTC | #3
On Thu, Apr 15, 2021 at 3:00 PM Johannes Thumshirn
<johannes.thumshirn@wdc.com> wrote:
>
> When relocating a block group the freed up space is not discarded in one
> big block, but each extent is discarded on it's own with -odisard=sync.
>
> For a zoned filesystem we need to discard the whole block group at once,
> so btrfs_discard_extent() will translate the discard into a
> REQ_OP_ZONE_RESET operation, which then resets the device's zone.
>
> Link: https://lore.kernel.org/linux-btrfs/459e2932c48e12e883dcfd3dda828d9da251d5b5.1617962110.git.johannes.thumshirn@wdc.com
> Signed-off-by: Johannes Thumshirn <johannes.thumshirn@wdc.com>
> ---
>  fs/btrfs/volumes.c | 21 +++++++++++++++++----
>  1 file changed, 17 insertions(+), 4 deletions(-)
>
> diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c
> index 6d9b2369f17a..b1bab75ec12a 100644
> --- a/fs/btrfs/volumes.c
> +++ b/fs/btrfs/volumes.c
> @@ -3103,6 +3103,7 @@ static int btrfs_relocate_chunk(struct btrfs_fs_info *fs_info, u64 chunk_offset)
>         struct btrfs_root *root = fs_info->chunk_root;
>         struct btrfs_trans_handle *trans;
>         struct btrfs_block_group *block_group;
> +       u64 length;
>         int ret;
>
>         /*
> @@ -3130,8 +3131,24 @@ static int btrfs_relocate_chunk(struct btrfs_fs_info *fs_info, u64 chunk_offset)
>         if (!block_group)
>                 return -ENOENT;
>         btrfs_discard_cancel_work(&fs_info->discard_ctl, block_group);
> +       length = block_group->length;
>         btrfs_put_block_group(block_group);
>
> +       /*
> +        * Step two, delete the device extents and the chunk tree entries.
> +        *
> +        * On a zoned file system, discard the whole block group, this will
> +        * trigger a REQ_OP_ZONE_RESET operation on the device zone. If
> +        * resetting the zone fails, don't treat it as a fatal problem from the
> +        * filesystem's point of view.
> +        */
> +       if (btrfs_is_zoned(fs_info)) {
> +               ret = btrfs_discard_extent(fs_info, chunk_offset, length, NULL);
> +               if (ret)
> +                       btrfs_info(fs_info, "failed to reset zone %llu",
> +                                  chunk_offset);
> +       }
> +
>         trans = btrfs_start_trans_remove_block_group(root->fs_info,
>                                                      chunk_offset);
>         if (IS_ERR(trans)) {
> @@ -3140,10 +3157,6 @@ static int btrfs_relocate_chunk(struct btrfs_fs_info *fs_info, u64 chunk_offset)
>                 return ret;
>         }
>
> -       /*
> -        * step two, delete the device extents and the
> -        * chunk tree entries
> -        */

This hunk seems unrelated and unintentional.
Not that the comment adds any value, but if the removal was
intentional, I would suggest a separate patch for that.

Other than that, it looks good, thanks.

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

>         ret = btrfs_remove_chunk(trans, chunk_offset);
>         btrfs_end_transaction(trans);
>         return ret;
> --
> 2.30.0
>
Johannes Thumshirn April 16, 2021, 9:14 a.m. UTC | #4
On 16/04/2021 11:12, Filipe Manana wrote:
> On Thu, Apr 15, 2021 at 3:00 PM Johannes Thumshirn
> <johannes.thumshirn@wdc.com> wrote:
>>
>> When relocating a block group the freed up space is not discarded in one
>> big block, but each extent is discarded on it's own with -odisard=sync.
>>
>> For a zoned filesystem we need to discard the whole block group at once,
>> so btrfs_discard_extent() will translate the discard into a
>> REQ_OP_ZONE_RESET operation, which then resets the device's zone.
>>
>> Link: https://lore.kernel.org/linux-btrfs/459e2932c48e12e883dcfd3dda828d9da251d5b5.1617962110.git.johannes.thumshirn@wdc.com
>> Signed-off-by: Johannes Thumshirn <johannes.thumshirn@wdc.com>
>> ---
>>  fs/btrfs/volumes.c | 21 +++++++++++++++++----
>>  1 file changed, 17 insertions(+), 4 deletions(-)
>>
>> diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c
>> index 6d9b2369f17a..b1bab75ec12a 100644
>> --- a/fs/btrfs/volumes.c
>> +++ b/fs/btrfs/volumes.c
>> @@ -3103,6 +3103,7 @@ static int btrfs_relocate_chunk(struct btrfs_fs_info *fs_info, u64 chunk_offset)
>>         struct btrfs_root *root = fs_info->chunk_root;
>>         struct btrfs_trans_handle *trans;
>>         struct btrfs_block_group *block_group;
>> +       u64 length;
>>         int ret;
>>
>>         /*
>> @@ -3130,8 +3131,24 @@ static int btrfs_relocate_chunk(struct btrfs_fs_info *fs_info, u64 chunk_offset)
>>         if (!block_group)
>>                 return -ENOENT;
>>         btrfs_discard_cancel_work(&fs_info->discard_ctl, block_group);
>> +       length = block_group->length;
>>         btrfs_put_block_group(block_group);
>>
>> +       /*
>> +        * Step two, delete the device extents and the chunk tree entries.
>> +        *
>> +        * On a zoned file system, discard the whole block group, this will
>> +        * trigger a REQ_OP_ZONE_RESET operation on the device zone. If
>> +        * resetting the zone fails, don't treat it as a fatal problem from the
>> +        * filesystem's point of view.
>> +        */
>> +       if (btrfs_is_zoned(fs_info)) {
>> +               ret = btrfs_discard_extent(fs_info, chunk_offset, length, NULL);
>> +               if (ret)
>> +                       btrfs_info(fs_info, "failed to reset zone %llu",
>> +                                  chunk_offset);
>> +       }
>> +
>>         trans = btrfs_start_trans_remove_block_group(root->fs_info,
>>                                                      chunk_offset);
>>         if (IS_ERR(trans)) {
>> @@ -3140,10 +3157,6 @@ static int btrfs_relocate_chunk(struct btrfs_fs_info *fs_info, u64 chunk_offset)
>>                 return ret;
>>         }
>>
>> -       /*
>> -        * step two, delete the device extents and the
>> -        * chunk tree entries
>> -        */
> 
> This hunk seems unrelated and unintentional.
> Not that the comment adds any value, but if the removal was
> intentional, I would suggest a separate patch for that.

It's moved upwards

+       /*
+        * Step two, delete the device extents and the chunk tree entries.
+        *
+        * On a zoned file system, discard the whole block group, this will
+        * trigger a REQ_OP_ZONE_RESET operation on the device zone. If
+        * resetting the zone fails, don't treat it as a fatal problem from the
+        * filesystem's point of view.
+        */

'cause technically the "delete extents" step starts with the discard now. But I
can leave it where it was.

> Other than that, it looks good, thanks.
> 
> Reviewed-by: Filipe Manana <fdmanana@suse.com>
> 

Thanks
Filipe Manana April 16, 2021, 9:30 a.m. UTC | #5
On Fri, Apr 16, 2021 at 10:14 AM Johannes Thumshirn
<Johannes.Thumshirn@wdc.com> wrote:
>
> On 16/04/2021 11:12, Filipe Manana wrote:
> > On Thu, Apr 15, 2021 at 3:00 PM Johannes Thumshirn
> > <johannes.thumshirn@wdc.com> wrote:
> >>
> >> When relocating a block group the freed up space is not discarded in one
> >> big block, but each extent is discarded on it's own with -odisard=sync.
> >>
> >> For a zoned filesystem we need to discard the whole block group at once,
> >> so btrfs_discard_extent() will translate the discard into a
> >> REQ_OP_ZONE_RESET operation, which then resets the device's zone.
> >>
> >> Link: https://lore.kernel.org/linux-btrfs/459e2932c48e12e883dcfd3dda828d9da251d5b5.1617962110.git.johannes.thumshirn@wdc.com
> >> Signed-off-by: Johannes Thumshirn <johannes.thumshirn@wdc.com>
> >> ---
> >>  fs/btrfs/volumes.c | 21 +++++++++++++++++----
> >>  1 file changed, 17 insertions(+), 4 deletions(-)
> >>
> >> diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c
> >> index 6d9b2369f17a..b1bab75ec12a 100644
> >> --- a/fs/btrfs/volumes.c
> >> +++ b/fs/btrfs/volumes.c
> >> @@ -3103,6 +3103,7 @@ static int btrfs_relocate_chunk(struct btrfs_fs_info *fs_info, u64 chunk_offset)
> >>         struct btrfs_root *root = fs_info->chunk_root;
> >>         struct btrfs_trans_handle *trans;
> >>         struct btrfs_block_group *block_group;
> >> +       u64 length;
> >>         int ret;
> >>
> >>         /*
> >> @@ -3130,8 +3131,24 @@ static int btrfs_relocate_chunk(struct btrfs_fs_info *fs_info, u64 chunk_offset)
> >>         if (!block_group)
> >>                 return -ENOENT;
> >>         btrfs_discard_cancel_work(&fs_info->discard_ctl, block_group);
> >> +       length = block_group->length;
> >>         btrfs_put_block_group(block_group);
> >>
> >> +       /*
> >> +        * Step two, delete the device extents and the chunk tree entries.
> >> +        *
> >> +        * On a zoned file system, discard the whole block group, this will
> >> +        * trigger a REQ_OP_ZONE_RESET operation on the device zone. If
> >> +        * resetting the zone fails, don't treat it as a fatal problem from the
> >> +        * filesystem's point of view.
> >> +        */
> >> +       if (btrfs_is_zoned(fs_info)) {
> >> +               ret = btrfs_discard_extent(fs_info, chunk_offset, length, NULL);
> >> +               if (ret)
> >> +                       btrfs_info(fs_info, "failed to reset zone %llu",
> >> +                                  chunk_offset);
> >> +       }
> >> +
> >>         trans = btrfs_start_trans_remove_block_group(root->fs_info,
> >>                                                      chunk_offset);
> >>         if (IS_ERR(trans)) {
> >> @@ -3140,10 +3157,6 @@ static int btrfs_relocate_chunk(struct btrfs_fs_info *fs_info, u64 chunk_offset)
> >>                 return ret;
> >>         }
> >>
> >> -       /*
> >> -        * step two, delete the device extents and the
> >> -        * chunk tree entries
> >> -        */
> >
> > This hunk seems unrelated and unintentional.
> > Not that the comment adds any value, but if the removal was
> > intentional, I would suggest a separate patch for that.
>
> It's moved upwards
>
> +       /*
> +        * Step two, delete the device extents and the chunk tree entries.
> +        *
> +        * On a zoned file system, discard the whole block group, this will
> +        * trigger a REQ_OP_ZONE_RESET operation on the device zone. If
> +        * resetting the zone fails, don't treat it as a fatal problem from the
> +        * filesystem's point of view.
> +        */
>
> 'cause technically the "delete extents" step starts with the discard now. But I
> can leave it where it was.

The comment refers to deleting the device extent items from the device
tree, not really extents on disk.
I.e. it's all about the items from the block group in the chunk and
device trees.

>
> > Other than that, it looks good, thanks.
> >
> > Reviewed-by: Filipe Manana <fdmanana@suse.com>
> >
>
> Thanks
Johannes Thumshirn April 16, 2021, 9:32 a.m. UTC | #6
On 16/04/2021 11:30, Filipe Manana wrote:
> The comment refers to deleting the device extent items from the device
> tree, not really extents on disk.
> I.e. it's all about the items from the block group in the chunk and
> device trees.

OK I'll move it back where it was.
diff mbox series

Patch

diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c
index 6d9b2369f17a..b1bab75ec12a 100644
--- a/fs/btrfs/volumes.c
+++ b/fs/btrfs/volumes.c
@@ -3103,6 +3103,7 @@  static int btrfs_relocate_chunk(struct btrfs_fs_info *fs_info, u64 chunk_offset)
 	struct btrfs_root *root = fs_info->chunk_root;
 	struct btrfs_trans_handle *trans;
 	struct btrfs_block_group *block_group;
+	u64 length;
 	int ret;
 
 	/*
@@ -3130,8 +3131,24 @@  static int btrfs_relocate_chunk(struct btrfs_fs_info *fs_info, u64 chunk_offset)
 	if (!block_group)
 		return -ENOENT;
 	btrfs_discard_cancel_work(&fs_info->discard_ctl, block_group);
+	length = block_group->length;
 	btrfs_put_block_group(block_group);
 
+	/*
+	 * Step two, delete the device extents and the chunk tree entries.
+	 *
+	 * On a zoned file system, discard the whole block group, this will
+	 * trigger a REQ_OP_ZONE_RESET operation on the device zone. If
+	 * resetting the zone fails, don't treat it as a fatal problem from the
+	 * filesystem's point of view.
+	 */
+	if (btrfs_is_zoned(fs_info)) {
+		ret = btrfs_discard_extent(fs_info, chunk_offset, length, NULL);
+		if (ret)
+			btrfs_info(fs_info, "failed to reset zone %llu",
+				   chunk_offset);
+	}
+
 	trans = btrfs_start_trans_remove_block_group(root->fs_info,
 						     chunk_offset);
 	if (IS_ERR(trans)) {
@@ -3140,10 +3157,6 @@  static int btrfs_relocate_chunk(struct btrfs_fs_info *fs_info, u64 chunk_offset)
 		return ret;
 	}
 
-	/*
-	 * step two, delete the device extents and the
-	 * chunk tree entries
-	 */
 	ret = btrfs_remove_chunk(trans, chunk_offset);
 	btrfs_end_transaction(trans);
 	return ret;