btrfs: Add raid56 support for updating
num_tolerated_disk_barrier_failures in btrfs_balance Code for updating fs_info->num_tolerated_disk_barrier_failures in btrfs_balance() lacks raid56 support. Reason: Above code was wroten in 2012-08-01, together with btrfs_calc_num_tolerated_disk_barrier_failures()'s first version. Then, btrfs_calc_num_tolerated_disk_barrier_failures() got updated later to support raid56, but code in btrfs_balance() was not updated together. Fix: Merge above similar code to a common function: btrfs_get_num_tolerated_disk_barrier_failures() and make it support both case. It can fix this bug with a bonus of cleanup, and make these code never in above no-sync state from now on. Suggested-by: Anand Jain <anand.jain@oracle.com> Signed-off-by: Zhao Lei <zhaolei@cn.fujitsu.com> Signed-off-by: Chris Mason <clm@fb.com>
This commit is contained in:
parent
2c4580454f
commit
943c6e9925
3 changed files with 30 additions and 39 deletions
|
@ -3440,6 +3440,26 @@ static int barrier_all_devices(struct btrfs_fs_info *info)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int btrfs_get_num_tolerated_disk_barrier_failures(u64 flags)
|
||||||
|
{
|
||||||
|
if ((flags & (BTRFS_BLOCK_GROUP_DUP |
|
||||||
|
BTRFS_BLOCK_GROUP_RAID0 |
|
||||||
|
BTRFS_AVAIL_ALLOC_BIT_SINGLE)) ||
|
||||||
|
((flags & BTRFS_BLOCK_GROUP_PROFILE_MASK) == 0))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (flags & (BTRFS_BLOCK_GROUP_RAID1 |
|
||||||
|
BTRFS_BLOCK_GROUP_RAID5 |
|
||||||
|
BTRFS_BLOCK_GROUP_RAID10))
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
if (flags & BTRFS_BLOCK_GROUP_RAID6)
|
||||||
|
return 2;
|
||||||
|
|
||||||
|
pr_warn("BTRFS: unknown raid type: %llu\n", flags);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
int btrfs_calc_num_tolerated_disk_barrier_failures(
|
int btrfs_calc_num_tolerated_disk_barrier_failures(
|
||||||
struct btrfs_fs_info *fs_info)
|
struct btrfs_fs_info *fs_info)
|
||||||
{
|
{
|
||||||
|
@ -3482,28 +3502,11 @@ int btrfs_calc_num_tolerated_disk_barrier_failures(
|
||||||
if (space.total_bytes == 0 || space.used_bytes == 0)
|
if (space.total_bytes == 0 || space.used_bytes == 0)
|
||||||
continue;
|
continue;
|
||||||
flags = space.flags;
|
flags = space.flags;
|
||||||
/*
|
|
||||||
* return
|
num_tolerated_disk_barrier_failures = min(
|
||||||
* 0: if dup, single or RAID0 is configured for
|
num_tolerated_disk_barrier_failures,
|
||||||
* any of metadata, system or data, else
|
btrfs_get_num_tolerated_disk_barrier_failures(
|
||||||
* 1: if RAID5 is configured, or if RAID1 or
|
flags));
|
||||||
* RAID10 is configured and only two mirrors
|
|
||||||
* are used, else
|
|
||||||
* 2: if RAID6 is configured
|
|
||||||
*/
|
|
||||||
if (num_tolerated_disk_barrier_failures > 0 &&
|
|
||||||
((flags & (BTRFS_BLOCK_GROUP_DUP |
|
|
||||||
BTRFS_BLOCK_GROUP_RAID0)) ||
|
|
||||||
((flags & BTRFS_BLOCK_GROUP_PROFILE_MASK) == 0)))
|
|
||||||
num_tolerated_disk_barrier_failures = 0;
|
|
||||||
else if (num_tolerated_disk_barrier_failures > 1 &&
|
|
||||||
(flags & (BTRFS_BLOCK_GROUP_RAID1 |
|
|
||||||
BTRFS_BLOCK_GROUP_RAID5 |
|
|
||||||
BTRFS_BLOCK_GROUP_RAID10)))
|
|
||||||
num_tolerated_disk_barrier_failures = 1;
|
|
||||||
else if (num_tolerated_disk_barrier_failures > 2 &&
|
|
||||||
(flags & BTRFS_BLOCK_GROUP_RAID6))
|
|
||||||
num_tolerated_disk_barrier_failures = 2;
|
|
||||||
}
|
}
|
||||||
up_read(&sinfo->groups_sem);
|
up_read(&sinfo->groups_sem);
|
||||||
}
|
}
|
||||||
|
|
|
@ -139,6 +139,7 @@ struct btrfs_root *btrfs_create_tree(struct btrfs_trans_handle *trans,
|
||||||
u64 objectid);
|
u64 objectid);
|
||||||
int btree_lock_page_hook(struct page *page, void *data,
|
int btree_lock_page_hook(struct page *page, void *data,
|
||||||
void (*flush_fn)(void *));
|
void (*flush_fn)(void *));
|
||||||
|
int btrfs_get_num_tolerated_disk_barrier_failures(u64 flags);
|
||||||
int btrfs_calc_num_tolerated_disk_barrier_failures(
|
int btrfs_calc_num_tolerated_disk_barrier_failures(
|
||||||
struct btrfs_fs_info *fs_info);
|
struct btrfs_fs_info *fs_info);
|
||||||
int __init btrfs_end_io_wq_init(void);
|
int __init btrfs_end_io_wq_init(void);
|
||||||
|
|
|
@ -3585,23 +3585,10 @@ int btrfs_balance(struct btrfs_balance_control *bctl,
|
||||||
} while (read_seqretry(&fs_info->profiles_lock, seq));
|
} while (read_seqretry(&fs_info->profiles_lock, seq));
|
||||||
|
|
||||||
if (bctl->sys.flags & BTRFS_BALANCE_ARGS_CONVERT) {
|
if (bctl->sys.flags & BTRFS_BALANCE_ARGS_CONVERT) {
|
||||||
int num_tolerated_disk_barrier_failures;
|
fs_info->num_tolerated_disk_barrier_failures = min(
|
||||||
u64 target = bctl->sys.target;
|
btrfs_calc_num_tolerated_disk_barrier_failures(fs_info),
|
||||||
|
btrfs_get_num_tolerated_disk_barrier_failures(
|
||||||
num_tolerated_disk_barrier_failures =
|
bctl->sys.target));
|
||||||
btrfs_calc_num_tolerated_disk_barrier_failures(fs_info);
|
|
||||||
if (num_tolerated_disk_barrier_failures > 0 &&
|
|
||||||
(target &
|
|
||||||
(BTRFS_BLOCK_GROUP_DUP | BTRFS_BLOCK_GROUP_RAID0 |
|
|
||||||
BTRFS_AVAIL_ALLOC_BIT_SINGLE)))
|
|
||||||
num_tolerated_disk_barrier_failures = 0;
|
|
||||||
else if (num_tolerated_disk_barrier_failures > 1 &&
|
|
||||||
(target &
|
|
||||||
(BTRFS_BLOCK_GROUP_RAID1 | BTRFS_BLOCK_GROUP_RAID10)))
|
|
||||||
num_tolerated_disk_barrier_failures = 1;
|
|
||||||
|
|
||||||
fs_info->num_tolerated_disk_barrier_failures =
|
|
||||||
num_tolerated_disk_barrier_failures;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = insert_balance_item(fs_info->tree_root, bctl);
|
ret = insert_balance_item(fs_info->tree_root, bctl);
|
||||||
|
|
Loading…
Add table
Reference in a new issue