mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-08-26 02:39:48 +00:00
Btrfs: make avail_*_alloc_bits fields dynamic
Currently when new chunks are created respective avail_alloc_bits field is updated to reflect profiles of all chunks present in the system. However when chunks are removed profile bits are never cleared. This patch clears profile bit of respective avail_alloc_bits field when the last chunk with that profile is removed. Restriper needs this to properly operate when "downgrading". Signed-off-by: Ilya Dryomov <idryomov@gmail.com>
This commit is contained in:
parent
a46d11a8b0
commit
10ea00f55a
1 changed files with 20 additions and 0 deletions
|
@ -7469,6 +7469,22 @@ int btrfs_make_block_group(struct btrfs_trans_handle *trans,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static void clear_avail_alloc_bits(struct btrfs_fs_info *fs_info, u64 flags)
|
||||
{
|
||||
u64 extra_flags = flags & BTRFS_BLOCK_GROUP_PROFILE_MASK;
|
||||
|
||||
/* chunk -> extended profile */
|
||||
if (extra_flags == 0)
|
||||
extra_flags = BTRFS_AVAIL_ALLOC_BIT_SINGLE;
|
||||
|
||||
if (flags & BTRFS_BLOCK_GROUP_DATA)
|
||||
fs_info->avail_data_alloc_bits &= ~extra_flags;
|
||||
if (flags & BTRFS_BLOCK_GROUP_METADATA)
|
||||
fs_info->avail_metadata_alloc_bits &= ~extra_flags;
|
||||
if (flags & BTRFS_BLOCK_GROUP_SYSTEM)
|
||||
fs_info->avail_system_alloc_bits &= ~extra_flags;
|
||||
}
|
||||
|
||||
int btrfs_remove_block_group(struct btrfs_trans_handle *trans,
|
||||
struct btrfs_root *root, u64 group_start)
|
||||
{
|
||||
|
@ -7479,6 +7495,7 @@ int btrfs_remove_block_group(struct btrfs_trans_handle *trans,
|
|||
struct btrfs_key key;
|
||||
struct inode *inode;
|
||||
int ret;
|
||||
int index;
|
||||
int factor;
|
||||
|
||||
root = root->fs_info->extent_root;
|
||||
|
@ -7494,6 +7511,7 @@ int btrfs_remove_block_group(struct btrfs_trans_handle *trans,
|
|||
free_excluded_extents(root, block_group);
|
||||
|
||||
memcpy(&key, &block_group->key, sizeof(key));
|
||||
index = get_block_group_index(block_group);
|
||||
if (block_group->flags & (BTRFS_BLOCK_GROUP_DUP |
|
||||
BTRFS_BLOCK_GROUP_RAID1 |
|
||||
BTRFS_BLOCK_GROUP_RAID10))
|
||||
|
@ -7568,6 +7586,8 @@ int btrfs_remove_block_group(struct btrfs_trans_handle *trans,
|
|||
* are still on the list after taking the semaphore
|
||||
*/
|
||||
list_del_init(&block_group->list);
|
||||
if (list_empty(&block_group->space_info->block_groups[index]))
|
||||
clear_avail_alloc_bits(root->fs_info, block_group->flags);
|
||||
up_write(&block_group->space_info->groups_sem);
|
||||
|
||||
if (block_group->cached == BTRFS_CACHE_STARTED)
|
||||
|
|
Loading…
Reference in a new issue