diff options
author | Ilya Dryomov <idryomov@gmail.com> | 2012-01-16 22:04:48 +0200 |
---|---|---|
committer | Ilya Dryomov <idryomov@gmail.com> | 2012-01-16 22:04:48 +0200 |
commit | cfa4c961cc69ffb7bda450972320a25cbd413e19 (patch) | |
tree | 68ed15b8303d8aa7385df5383aebbef47debea4f /fs | |
parent | e4d8ec0f65b91bfb4984a4927632ded95f9825ad (diff) | |
download | linux-3.10-cfa4c961cc69ffb7bda450972320a25cbd413e19.tar.gz linux-3.10-cfa4c961cc69ffb7bda450972320a25cbd413e19.tar.bz2 linux-3.10-cfa4c961cc69ffb7bda450972320a25cbd413e19.zip |
Btrfs: soft profile changing mode (aka soft convert)
When doing convert from one profile to another if soft mode is on
restriper won't touch chunks that already have the profile we are
converting to. This is useful if e.g. half of the FS was converted
earlier.
The soft mode switch is (like every other filter) per-type. This means
that we can convert for example meta chunks the "hard" way while
converting data chunks selectively with soft switch.
Signed-off-by: Ilya Dryomov <idryomov@gmail.com>
Diffstat (limited to 'fs')
-rw-r--r-- | fs/btrfs/volumes.c | 23 | ||||
-rw-r--r-- | fs/btrfs/volumes.h | 6 |
2 files changed, 29 insertions, 0 deletions
diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c index f08210e8333..98b4067017f 100644 --- a/fs/btrfs/volumes.c +++ b/fs/btrfs/volumes.c @@ -2221,6 +2221,23 @@ static int chunk_vrange_filter(struct extent_buffer *leaf, return 1; } +static int chunk_soft_convert_filter(u64 chunk_profile, + struct btrfs_balance_args *bargs) +{ + if (!(bargs->flags & BTRFS_BALANCE_ARGS_CONVERT)) + return 0; + + chunk_profile &= BTRFS_BLOCK_GROUP_PROFILE_MASK; + + if (chunk_profile == 0) + chunk_profile = BTRFS_AVAIL_ALLOC_BIT_SINGLE; + + if (bargs->target & chunk_profile) + return 1; + + return 0; +} + static int should_balance_chunk(struct btrfs_root *root, struct extent_buffer *leaf, struct btrfs_chunk *chunk, u64 chunk_offset) @@ -2272,6 +2289,12 @@ static int should_balance_chunk(struct btrfs_root *root, return 0; } + /* soft profile changing mode */ + if ((bargs->flags & BTRFS_BALANCE_ARGS_SOFT) && + chunk_soft_convert_filter(chunk_type, bargs)) { + return 0; + } + return 1; } diff --git a/fs/btrfs/volumes.h b/fs/btrfs/volumes.h index 79ee9c32456..6c143c98017 100644 --- a/fs/btrfs/volumes.h +++ b/fs/btrfs/volumes.h @@ -208,7 +208,13 @@ struct map_lookup { #define BTRFS_BALANCE_ARGS_DRANGE (1ULL << 3) #define BTRFS_BALANCE_ARGS_VRANGE (1ULL << 4) +/* + * Profile changing flags. When SOFT is set we won't relocate chunk if + * it already has the target profile (even though it may be + * half-filled). + */ #define BTRFS_BALANCE_ARGS_CONVERT (1ULL << 8) +#define BTRFS_BALANCE_ARGS_SOFT (1ULL << 9) struct btrfs_balance_args; struct btrfs_balance_control { |