Add stripes filter
Subsystems (2)
Hello everyone!
The attached patches to linux and btrfs-progs add support for filtering based on the number of strips in a block when balancing.
This is my first attempt at kernel development, I'd love if you could please point out any mistakes that I've made.
Thanks,
Gabríel
P.S. I could not figure out how to subscribe to this mailing list, so please remember to include me in your replies.
Documentation/btrfs-balance.asciidoc +4 -0
@@ -110,6 +110,10 @@ Process only given number of chunks, after all filters apply. This can be used to specifically target a chunk in connection with other filters (drange, vrange) or just simply limit the amount of work done by a single balance run. +*stripes*:: +Balances only block groups which have the given number of stripes. The +parameter is either a range specified as <start..end>, or a single integer. + *soft*:: Takes no parameters. Only has meaning when converting between profiles. When doing convert from one profile to another and soft mode is on,
cmds-balance.c +24 -0
@@ -226,6 +226,21 @@ static int parse_filters(char *filters, struct btrfs_balance_args *args)return 1 ; } args->flags |=BTRFS_BALANCE_ARGS_LIMIT ; + }else if (!strcmp (this_char,"stripes" )) { +if (!value || !*value) { +fprintf (stderr, +"the stripes filter requires an argument\n" ); +return 1 ; + } +if (parse_u64 (value, &args->sstart)) { +if (parse_range (value, &args->sstart, &args->send)) { +fprintf (stderr,"Invalid stripes argument\n" ); +return 1 ; + } + }else { + args->send = args->sstart; + } + args->flags |=BTRFS_BALANCE_ARGS_STRIPES ; }else {fprintf (stderr,"Unrecognized balance option '%s'\n" , this_char);
@@ -262,6 +277,15 @@ static void dump_balance_args(struct btrfs_balance_args *args) (unsigned long long)args->vend);if (args->flags &BTRFS_BALANCE_ARGS_LIMIT )printf (", limit=%llu" , (unsigned long long )args->limit); +if (args->flags &BTRFS_BALANCE_ARGS_STRIPES ) { +if (args->sstart == args->send) { +printf (", stripes=%llu" , (unsigned long long )args->sstart); + }else { +printf (", stripes=%llu..%llu" , + (unsigned long long )args->sstart, + (unsigned long long )args->send); + } + }printf ("\n" ); }
ioctl.h +5 -1
@@ -228,7 +228,11 @@ struct btrfs_balance_args {__u64 flags;__u64 limit;/* limit number of processed chunks */ -__u64 unused[7 ]; + +__u64 sstart; +__u64 send; + +__u64 unused[5 ]; } __attribute__ ((__packed__));/* report balance progress to userspace */
volumes.h +1 -0
@@ -136,6 +136,7 @@ struct map_lookup {#define BTRFS_BALANCE_ARGS_DRANGE (1ULL << 3)#define BTRFS_BALANCE_ARGS_VRANGE (1ULL << 4)#define BTRFS_BALANCE_ARGS_LIMIT (1ULL << 5) +#define BTRFS_BALANCE_ARGS_STRIPES (1ULL << 6)/* * Profile changing flags. When SOFT is set we won't relocate chunk if
fs/btrfs/ctree.h +5 -1
@@ -849,7 +849,11 @@ struct btrfs_disk_balance_args {/* BTRFS_BALANCE_ARGS_LIMIT value */ __le64 limit; -__le64 unused[7 ]; +/* btrfs stripes filter */ +__le64 sstart; +__le64 send; + +__le64 unused[5 ]; } __attribute__ ((__packed__));/*
fs/btrfs/volumes.c +18 -0
@@ -3170,6 +3170,18 @@ static int chunk_vrange_filter(struct extent_buffer *leaf,return 1 ; } +static int chunk_stripes_filter (struct extent_buffer *leaf, +struct btrfs_chunk *chunk, +struct btrfs_balance_args *bargs) +{ +int num_stripes =btrfs_chunk_num_stripes (leaf, chunk); + +if (bargs->sstart <= num_stripes && num_stripes <= bargs->send) +return 0 ; + +return 1 ; +} +static int chunk_soft_convert_filter (u64 chunk_type,struct btrfs_balance_args *bargs) {
@@ -3236,6 +3248,12 @@ static int should_balance_chunk(struct btrfs_root *root,return 0 ; } +/* stripes filter */ +if ((bargs->flags &BTRFS_BALANCE_ARGS_STRIPES ) && +chunk_stripes_filter (leaf, chunk, bargs)) { +return 0 ; + } +/* soft profile changing mode */ if ((bargs->flags &BTRFS_BALANCE_ARGS_SOFT ) &&chunk_soft_convert_filter (chunk_type, bargs)) {
fs/btrfs/volumes.h +1 -0
@@ -375,6 +375,7 @@ struct map_lookup {#define BTRFS_BALANCE_ARGS_DRANGE (1ULL << 3)#define BTRFS_BALANCE_ARGS_VRANGE (1ULL << 4)#define BTRFS_BALANCE_ARGS_LIMIT (1ULL << 5) +#define BTRFS_BALANCE_ARGS_STRIPES (1ULL << 6)/* * Profile changing flags. When SOFT is set we won't relocate chunk if
include/uapi/linux/btrfs.h +5 -1
@@ -218,7 +218,11 @@ struct btrfs_balance_args {__u64 flags;__u64 limit;/* limit number of processed chunks */ -__u64 unused[7 ]; + +__u64 sstart; +__u64 send; + +__u64 unused[5 ]; } __attribute__ ((__packed__));/* report balance progress to userspace */
Quoted 5 lines · Gabríel Arthúr Pétursson
Hello everyone!
The attached patches to linux and btrfs-progs add support for filtering based on the number of strips in a block when balancing.
Quoted 8 lines
This is my first attempt at kernel development, I'd love if you could please point out any mistakes that I've made.
Thanks,
Gabríel
P.S. I could not figure out how to subscribe to this mailing list, so please remember to include me in your replies.
Hi, Gabríel,
To subscribe to the mailing list, all you have to do is email [email protected] with "subscribe linux-btrfs" in the body (see
http://vger.kernel.org/vger-lists.html#linux-btrfs). Also, be sure to take a look at https://btrfs.wiki.kernel.org/index.php/Developer%27s_FAQ
and https://www.kernel.org/doc/Documentation/SubmittingPatches
for instructions on how to send in patches. The biggest takeaway is to use git format-patch and git send-email.
Thanks!
Signature · 1 line
Omar
PATCH 1/1 btrfs: add stripes filter
In reply to Gabríel Arthúr Pétursson--- fs/btrfs/ctree.h | 6 +++++- fs/btrfs/volumes.c | 18 ++++++++++++++++++ fs/btrfs/volumes.h | 1 + include/uapi/linux/btrfs.h | 6 +++++- 4 files changed, 29 insertions(+), 2 deletions(-)
fs/btrfs/ctree.h +5 -1
@@ -849,7 +849,11 @@ struct btrfs_disk_balance_args {/* BTRFS_BALANCE_ARGS_LIMIT value */ __le64 limit; -__le64 unused[7 ]; +/* btrfs stripes filter */ +__le64 sstart; +__le64 send; + +__le64 unused[5 ]; } __attribute__ ((__packed__));/*
fs/btrfs/volumes.c +18 -0
@@ -3170,6 +3170,18 @@ static int chunk_vrange_filter(struct extent_buffer *leaf,return 1 ; } +static int chunk_stripes_filter (struct extent_buffer *leaf, +struct btrfs_chunk *chunk, +struct btrfs_balance_args *bargs) +{ +int num_stripes =btrfs_chunk_num_stripes (leaf, chunk); + +if (bargs->sstart <= num_stripes && num_stripes <= bargs->send) +return 0 ; + +return 1 ; +} +static int chunk_soft_convert_filter (u64 chunk_type,struct btrfs_balance_args *bargs) {
@@ -3236,6 +3248,12 @@ static int should_balance_chunk(struct btrfs_root *root,return 0 ; } +/* stripes filter */ +if ((bargs->flags &BTRFS_BALANCE_ARGS_STRIPES ) && +chunk_stripes_filter (leaf, chunk, bargs)) { +return 0 ; + } +/* soft profile changing mode */ if ((bargs->flags &BTRFS_BALANCE_ARGS_SOFT ) &&chunk_soft_convert_filter (chunk_type, bargs)) {
fs/btrfs/volumes.h +1 -0
@@ -375,6 +375,7 @@ struct map_lookup {#define BTRFS_BALANCE_ARGS_DRANGE (1ULL << 3)#define BTRFS_BALANCE_ARGS_VRANGE (1ULL << 4)#define BTRFS_BALANCE_ARGS_LIMIT (1ULL << 5) +#define BTRFS_BALANCE_ARGS_STRIPES (1ULL << 6)/* * Profile changing flags. When SOFT is set we won't relocate chunk if
include/uapi/linux/btrfs.h +5 -1
@@ -218,7 +218,11 @@ struct btrfs_balance_args {__u64 flags;__u64 limit;/* limit number of processed chunks */ -__u64 unused[7 ]; + +__u64 sstart; +__u64 send; + +__u64 unused[5 ]; } __attribute__ ((__packed__));/* report balance progress to userspace */
Signature · 1 line
2.5.3
PATCH 1/1 btrfs-progs: add stripes filter
In reply to Gabríel Arthúr Pétursson--- Documentation/btrfs-balance.asciidoc | 4 ++++ cmds-balance.c | 24 ++++++++++++++++++++++++ ioctl.h | 6 +++++- volumes.h | 1 + 4 files changed, 34 insertions(+), 1 deletion(-)
Documentation/btrfs-balance.asciidoc +4 -0
@@ -110,6 +110,10 @@ Process only given number of chunks, after all filters apply. This can be used to specifically target a chunk in connection with other filters (drange, vrange) or just simply limit the amount of work done by a single balance run. +*stripes*:: +Balances only block groups which have the given number of stripes. The +parameter is either a range specified as <start..end>, or a single integer. + *soft*:: Takes no parameters. Only has meaning when converting between profiles. When doing convert from one profile to another and soft mode is on,
cmds-balance.c +24 -0
@@ -226,6 +226,21 @@ static int parse_filters(char *filters, struct btrfs_balance_args *args)return 1 ; } args->flags |=BTRFS_BALANCE_ARGS_LIMIT ; + }else if (!strcmp (this_char,"stripes" )) { +if (!value || !*value) { +fprintf (stderr, +"the stripes filter requires an argument\n" ); +return 1 ; + } +if (parse_u64 (value, &args->sstart)) { +if (parse_range (value, &args->sstart, &args->send)) { +fprintf (stderr,"Invalid stripes argument\n" ); +return 1 ; + } + }else { + args->send = args->sstart; + } + args->flags |=BTRFS_BALANCE_ARGS_STRIPES ; }else {fprintf (stderr,"Unrecognized balance option '%s'\n" , this_char);
@@ -262,6 +277,15 @@ static void dump_balance_args(struct btrfs_balance_args *args) (unsigned long long)args->vend);if (args->flags &BTRFS_BALANCE_ARGS_LIMIT )printf (", limit=%llu" , (unsigned long long )args->limit); +if (args->flags &BTRFS_BALANCE_ARGS_STRIPES ) { +if (args->sstart == args->send) { +printf (", stripes=%llu" , (unsigned long long )args->sstart); + }else { +printf (", stripes=%llu..%llu" , + (unsigned long long )args->sstart, + (unsigned long long )args->send); + } + }printf ("\n" ); }
ioctl.h +5 -1
@@ -228,7 +228,11 @@ struct btrfs_balance_args {__u64 flags;__u64 limit;/* limit number of processed chunks */ -__u64 unused[7 ]; + +__u64 sstart; +__u64 send; + +__u64 unused[5 ]; } __attribute__ ((__packed__));/* report balance progress to userspace */
volumes.h +1 -0
@@ -136,6 +136,7 @@ struct map_lookup {#define BTRFS_BALANCE_ARGS_DRANGE (1ULL << 3)#define BTRFS_BALANCE_ARGS_VRANGE (1ULL << 4)#define BTRFS_BALANCE_ARGS_LIMIT (1ULL << 5) +#define BTRFS_BALANCE_ARGS_STRIPES (1ULL << 6)/* * Profile changing flags. When SOFT is set we won't relocate chunk if
Signature · 1 line
2.5.3
Quoted 2 lines · Gabríel Arthúr Pétursson
The attached patches to linux and btrfs-progs add support for filtering based on the number of strips in a block when balancing.
What usecase do you want to address? As I understand it, this would help the raid56 rebalancing to process only blockgroups that are not spread accross enough devices.
Quoted 7 lines · David Sterba
Quoted 2 lines · Gabríel Arthúr Pétursson
The attached patches to linux and btrfs-progs add support for filtering based on the number of strips in a block when balancing.
What usecase do you want to address? As I understand it, this would help the raid56 rebalancing to process only blockgroups that are not spread accross enough devices.
This could also be helpful when reshaping a raid10 or raid0 setup.
Quoted 8 lines · Austin S Hemmelgarn
Quoted 7 lines · David Sterba
Quoted 2 lines · Gabríel Arthúr Pétursson
The attached patches to linux and btrfs-progs add support for filtering based on the number of strips in a block when balancing.
What usecase do you want to address? As I understand it, this would help the raid56 rebalancing to process only blockgroups that are not spread accross enough devices.
Exactly. Last week, I was trying to help Gabríel on IRC with a
close-to-full filesystem balance it to add some new devices in a parity RAID configuration. He'd added the devices and balanced, but the usage was unequal across the devices. The only way I could think of dealing with it with the current tools was either to do a full balance repeatedly until it worked itself out, or to delve into the metadata with btrfs-debug-tree, and balance selected block groups individually.
I whinged that we needed a filter to pick just the block groups
that weren't "as full as possible", and Gabríel picked up the idea and ran with it.
Quoted 1 line
This could also be helpful when reshaping a raid10 or raid0 setup.
Yes, although ultimately less important in most cases, I think,
because you don't lose space by reducing the number of devices in a block group for those. There are some corner cases where you could end up losing space by having one (for RAID-0) or up to three (for RAID-10) devices with more space left than the rest.
Hugo.
Signature · 4 lines
Hugo Mills | Dullest spy film ever: The Eastbourne Ultimatum hugo@... carfax.org.uk | http://carfax.org.uk/ | PGP: E2AB1DE4 | The Thick of It
Quoted 9 lines · Austin S Hemmelgarn
Quoted 7 lines · David Sterba
Quoted 2 lines · Gabríel Arthúr Pétursson
The attached patches to linux and btrfs-progs add support for filtering based on the number of strips in a block when balancing.
What usecase do you want to address? As I understand it, this would help the raid56 rebalancing to process only blockgroups that are not spread accross enough devices.
This could also be helpful when reshaping a raid10 or raid0 setup.
Right, I forgot to mention it, I should have said "any raid profile that uses stripes".
Quoted 19 lines · Hugo Mills
Quoted 8 lines · Austin S Hemmelgarn
Quoted 7 lines · David Sterba
Quoted 2 lines · Gabríel Arthúr Pétursson
The attached patches to linux and btrfs-progs add support for filtering based on the number of strips in a block when balancing.
What usecase do you want to address? As I understand it, this would help the raid56 rebalancing to process only blockgroups that are not spread accross enough devices.
Exactly. Last week, I was trying to help Gabríel on IRC with a
close-to-full filesystem balance it to add some new devices in a parity RAID configuration. He'd added the devices and balanced, but the usage was unequal across the devices. The only way I could think of dealing with it with the current tools was either to do a full balance repeatedly until it worked itself out, or to delve into the metadata with btrfs-debug-tree, and balance selected block groups individually.
Quoted 3 lines
I whinged that we needed a filter to pick just the block groups
that weren't "as full as possible", and Gabríel picked up the idea and ran with it.
That's great, thanks. The stripe filters are really missing.
Re: [PATCH] btrfs: add stripes filter
In reply to Gabríel Arthúr PéturssonHi,
thanks for the patch. The stripe filter is really helpful. There are some minor comments below but otherwise the patch looks good.
fs/btrfs/ctree.h struct btrfs_disk_balance_args { · line 854
Quoted 10 lines · Gabríel Arthúr Pétursson
fs/btrfs/ctree.h +3
-1@@ -849,7 +849,11 @@ struct btrfs_disk_balance_args {/* BTRFS_BALANCE_ARGS_LIMIT value */ __le64 limit; -__le64 unused[7 ]; +/* btrfs stripes filter */ +__le64 sstart; +__le64 send;
Please be more descriptive, eg. min_stripes/max_stripes. The u64 type seems too much, I think we can fit the stripe count into a 32bit number. I made a mistake with u64 type for the 'limit' filter but I think that we can somehow extend it to be two u32 with the min/max meaning as well. Either way, this is independent of your patch.
Quoted 8 lines
fs/btrfs/ctree.h +2
-0+ +__le64 unused[5 ]; } __attribute__ ((__packed__));/*
fs/btrfs/volumes.c static int should_balance_chunk(struct btrfs_root *root, · line 3255
Quoted 8 lines
fs/btrfs/volumes.c +5
-0@@ -3236,6 +3248,12 @@ static int should_balance_chunk(struct btrfs_root *root,return 0 ; } +/* stripes filter */ +if ((bargs->flags &BTRFS_BALANCE_ARGS_STRIPES ) && +chunk_stripes_filter (leaf, chunk, bargs)) { +return 0 ; + }
Ok, I think that this ordering of the filters is right.
Quoted 21 lines
fs/btrfs/volumes.c +1
-0+/* soft profile changing mode */ if ((bargs->flags &BTRFS_BALANCE_ARGS_SOFT ) &&chunk_soft_convert_filter (chunk_type, bargs)) {fs/btrfs/volumes.h +1
-0@@ -375,6 +375,7 @@ struct map_lookup {#define BTRFS_BALANCE_ARGS_DRANGE (1ULL << 3)#define BTRFS_BALANCE_ARGS_VRANGE (1ULL << 4)#define BTRFS_BALANCE_ARGS_LIMIT (1ULL << 5) +#define BTRFS_BALANCE_ARGS_STRIPES (1ULL << 6)/* * Profile changing flags. When SOFT is set we won't relocate chunk if include/uapi/linux/btrfs.h +0
-0
include/uapi/linux/btrfs.h struct btrfs_balance_args { · line 221
Quoted 4 lines
include/uapi/linux/btrfs.h +0
-1@@ -218,7 +218,11 @@ struct btrfs_balance_args {__u64 flags;__u64 limit;/* limit number of processed chunks */ -__u64 unused[7 ];
same comment from the ctree.h applies here
Quoted 8 lines
include/uapi/linux/btrfs.h +5
-0+ +__u64 sstart; +__u64 send; + +__u64 unused[5 ]; } __attribute__ ((__packed__));/* report balance progress to userspace */
Quoted 2 lines · Gabríel Arthúr Pétursson
The attached patches to linux and btrfs-progs add support for filtering based on the number of strips in a block when balancing.
FYI, I'm going to make the fixups myself as they're mostly cosmetic and prepare this patch for 4.4 merge window, together with the extension to the 'limit' filter I mentioned.