Skip to content

Commit 943c6e9

Browse files
zhaoleiddmasoncl
authored andcommitted
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>
1 parent 2c45804 commit 943c6e9

File tree

3 files changed

+30
-39
lines changed

3 files changed

+30
-39
lines changed

fs/btrfs/disk-io.c

Lines changed: 25 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -3440,6 +3440,26 @@ static int barrier_all_devices(struct btrfs_fs_info *info)
34403440
return 0;
34413441
}
34423442

3443+
int btrfs_get_num_tolerated_disk_barrier_failures(u64 flags)
3444+
{
3445+
if ((flags & (BTRFS_BLOCK_GROUP_DUP |
3446+
BTRFS_BLOCK_GROUP_RAID0 |
3447+
BTRFS_AVAIL_ALLOC_BIT_SINGLE)) ||
3448+
((flags & BTRFS_BLOCK_GROUP_PROFILE_MASK) == 0))
3449+
return 0;
3450+
3451+
if (flags & (BTRFS_BLOCK_GROUP_RAID1 |
3452+
BTRFS_BLOCK_GROUP_RAID5 |
3453+
BTRFS_BLOCK_GROUP_RAID10))
3454+
return 1;
3455+
3456+
if (flags & BTRFS_BLOCK_GROUP_RAID6)
3457+
return 2;
3458+
3459+
pr_warn("BTRFS: unknown raid type: %llu\n", flags);
3460+
return 0;
3461+
}
3462+
34433463
int btrfs_calc_num_tolerated_disk_barrier_failures(
34443464
struct btrfs_fs_info *fs_info)
34453465
{
@@ -3482,28 +3502,11 @@ int btrfs_calc_num_tolerated_disk_barrier_failures(
34823502
if (space.total_bytes == 0 || space.used_bytes == 0)
34833503
continue;
34843504
flags = space.flags;
3485-
/*
3486-
* return
3487-
* 0: if dup, single or RAID0 is configured for
3488-
* any of metadata, system or data, else
3489-
* 1: if RAID5 is configured, or if RAID1 or
3490-
* RAID10 is configured and only two mirrors
3491-
* are used, else
3492-
* 2: if RAID6 is configured
3493-
*/
3494-
if (num_tolerated_disk_barrier_failures > 0 &&
3495-
((flags & (BTRFS_BLOCK_GROUP_DUP |
3496-
BTRFS_BLOCK_GROUP_RAID0)) ||
3497-
((flags & BTRFS_BLOCK_GROUP_PROFILE_MASK) == 0)))
3498-
num_tolerated_disk_barrier_failures = 0;
3499-
else if (num_tolerated_disk_barrier_failures > 1 &&
3500-
(flags & (BTRFS_BLOCK_GROUP_RAID1 |
3501-
BTRFS_BLOCK_GROUP_RAID5 |
3502-
BTRFS_BLOCK_GROUP_RAID10)))
3503-
num_tolerated_disk_barrier_failures = 1;
3504-
else if (num_tolerated_disk_barrier_failures > 2 &&
3505-
(flags & BTRFS_BLOCK_GROUP_RAID6))
3506-
num_tolerated_disk_barrier_failures = 2;
3505+
3506+
num_tolerated_disk_barrier_failures = min(
3507+
num_tolerated_disk_barrier_failures,
3508+
btrfs_get_num_tolerated_disk_barrier_failures(
3509+
flags));
35073510
}
35083511
up_read(&sinfo->groups_sem);
35093512
}

fs/btrfs/disk-io.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,7 @@ struct btrfs_root *btrfs_create_tree(struct btrfs_trans_handle *trans,
139139
u64 objectid);
140140
int btree_lock_page_hook(struct page *page, void *data,
141141
void (*flush_fn)(void *));
142+
int btrfs_get_num_tolerated_disk_barrier_failures(u64 flags);
142143
int btrfs_calc_num_tolerated_disk_barrier_failures(
143144
struct btrfs_fs_info *fs_info);
144145
int __init btrfs_end_io_wq_init(void);

fs/btrfs/volumes.c

Lines changed: 4 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -3585,23 +3585,10 @@ int btrfs_balance(struct btrfs_balance_control *bctl,
35853585
} while (read_seqretry(&fs_info->profiles_lock, seq));
35863586

35873587
if (bctl->sys.flags & BTRFS_BALANCE_ARGS_CONVERT) {
3588-
int num_tolerated_disk_barrier_failures;
3589-
u64 target = bctl->sys.target;
3590-
3591-
num_tolerated_disk_barrier_failures =
3592-
btrfs_calc_num_tolerated_disk_barrier_failures(fs_info);
3593-
if (num_tolerated_disk_barrier_failures > 0 &&
3594-
(target &
3595-
(BTRFS_BLOCK_GROUP_DUP | BTRFS_BLOCK_GROUP_RAID0 |
3596-
BTRFS_AVAIL_ALLOC_BIT_SINGLE)))
3597-
num_tolerated_disk_barrier_failures = 0;
3598-
else if (num_tolerated_disk_barrier_failures > 1 &&
3599-
(target &
3600-
(BTRFS_BLOCK_GROUP_RAID1 | BTRFS_BLOCK_GROUP_RAID10)))
3601-
num_tolerated_disk_barrier_failures = 1;
3602-
3603-
fs_info->num_tolerated_disk_barrier_failures =
3604-
num_tolerated_disk_barrier_failures;
3588+
fs_info->num_tolerated_disk_barrier_failures = min(
3589+
btrfs_calc_num_tolerated_disk_barrier_failures(fs_info),
3590+
btrfs_get_num_tolerated_disk_barrier_failures(
3591+
bctl->sys.target));
36053592
}
36063593

36073594
ret = insert_balance_item(fs_info->tree_root, bctl);

0 commit comments

Comments
 (0)