Skip to content

Commit 47e6f74

Browse files
committed
btrfs: add support for 3-copy replication (raid1c3)
Add new block group profile to store 3 copies in a simliar way that current RAID1 does. The profile attributes and constraints are defined in the raid table and used by the same code that already handles the 2-copy RAID1. The minimum number of devices is 3, the maximum number of devices/chunks that can be lost/damaged is 2. Like RAID6 but with 33% space utilization. Signed-off-by: David Sterba <dsterba@suse.com>
1 parent fac07d2 commit 47e6f74

File tree

6 files changed

+30
-6
lines changed

6 files changed

+30
-6
lines changed

fs/btrfs/ctree.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -57,9 +57,9 @@ struct btrfs_ref;
5757
* filesystem data as well that can be used to read data in order to repair
5858
* read errors on other disks.
5959
*
60-
* Current value is derived from RAID1 with 2 copies.
60+
* Current value is derived from RAID1C3 with 3 copies.
6161
*/
62-
#define BTRFS_MAX_MIRRORS (2 + 1)
62+
#define BTRFS_MAX_MIRRORS (3 + 1)
6363

6464
#define BTRFS_MAX_LEVEL 8
6565

fs/btrfs/super.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1935,6 +1935,8 @@ static inline int btrfs_calc_avail_data_space(struct btrfs_fs_info *fs_info,
19351935
num_stripes = nr_devices;
19361936
else if (type & BTRFS_BLOCK_GROUP_RAID1)
19371937
num_stripes = 2;
1938+
else if (type & BTRFS_BLOCK_GROUP_RAID1C3)
1939+
num_stripes = 3;
19381940
else if (type & BTRFS_BLOCK_GROUP_RAID10)
19391941
num_stripes = 4;
19401942

fs/btrfs/volumes.c

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,18 @@ const struct btrfs_raid_attr btrfs_raid_array[BTRFS_NR_RAID_TYPES] = {
5858
.bg_flag = BTRFS_BLOCK_GROUP_RAID1,
5959
.mindev_error = BTRFS_ERROR_DEV_RAID1_MIN_NOT_MET,
6060
},
61+
[BTRFS_RAID_RAID1C3] = {
62+
.sub_stripes = 1,
63+
.dev_stripes = 1,
64+
.devs_max = 0,
65+
.devs_min = 3,
66+
.tolerated_failures = 2,
67+
.devs_increment = 3,
68+
.ncopies = 3,
69+
.raid_name = "raid1c3",
70+
.bg_flag = BTRFS_BLOCK_GROUP_RAID1C3,
71+
.mindev_error = BTRFS_ERROR_DEV_RAID1C3_MIN_NOT_MET,
72+
},
6173
[BTRFS_RAID_DUP] = {
6274
.sub_stripes = 1,
6375
.dev_stripes = 2,
@@ -4839,8 +4851,11 @@ static int __btrfs_alloc_chunk(struct btrfs_trans_handle *trans,
48394851
sort(devices_info, ndevs, sizeof(struct btrfs_device_info),
48404852
btrfs_cmp_device_info, NULL);
48414853

4842-
/* round down to number of usable stripes */
4843-
ndevs = round_down(ndevs, devs_increment);
4854+
/*
4855+
* Round down to number of usable stripes, devs_increment can be any
4856+
* number so we can't use round_down()
4857+
*/
4858+
ndevs -= ndevs % devs_increment;
48444859

48454860
if (ndevs < devs_min) {
48464861
ret = -ENOSPC;

fs/btrfs/volumes.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -545,6 +545,8 @@ static inline enum btrfs_raid_types btrfs_bg_flags_to_raid_index(u64 flags)
545545
return BTRFS_RAID_RAID10;
546546
else if (flags & BTRFS_BLOCK_GROUP_RAID1)
547547
return BTRFS_RAID_RAID1;
548+
else if (flags & BTRFS_BLOCK_GROUP_RAID1C3)
549+
return BTRFS_RAID_RAID1C3;
548550
else if (flags & BTRFS_BLOCK_GROUP_DUP)
549551
return BTRFS_RAID_DUP;
550552
else if (flags & BTRFS_BLOCK_GROUP_RAID0)

include/uapi/linux/btrfs.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -831,7 +831,8 @@ enum btrfs_err_code {
831831
BTRFS_ERROR_DEV_TGT_REPLACE,
832832
BTRFS_ERROR_DEV_MISSING_NOT_FOUND,
833833
BTRFS_ERROR_DEV_ONLY_WRITABLE,
834-
BTRFS_ERROR_DEV_EXCL_RUN_IN_PROGRESS
834+
BTRFS_ERROR_DEV_EXCL_RUN_IN_PROGRESS,
835+
BTRFS_ERROR_DEV_RAID1C3_MIN_NOT_MET,
835836
};
836837

837838
#define BTRFS_IOC_SNAP_CREATE _IOW(BTRFS_IOCTL_MAGIC, 1, \

include/uapi/linux/btrfs_tree.h

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -841,6 +841,7 @@ struct btrfs_dev_replace_item {
841841
#define BTRFS_BLOCK_GROUP_RAID10 (1ULL << 6)
842842
#define BTRFS_BLOCK_GROUP_RAID5 (1ULL << 7)
843843
#define BTRFS_BLOCK_GROUP_RAID6 (1ULL << 8)
844+
#define BTRFS_BLOCK_GROUP_RAID1C3 (1ULL << 9)
844845
#define BTRFS_BLOCK_GROUP_RESERVED (BTRFS_AVAIL_ALLOC_BIT_SINGLE | \
845846
BTRFS_SPACE_INFO_GLOBAL_RSV)
846847

@@ -852,6 +853,7 @@ enum btrfs_raid_types {
852853
BTRFS_RAID_SINGLE,
853854
BTRFS_RAID_RAID5,
854855
BTRFS_RAID_RAID6,
856+
BTRFS_RAID_RAID1C3,
855857
BTRFS_NR_RAID_TYPES
856858
};
857859

@@ -861,14 +863,16 @@ enum btrfs_raid_types {
861863

862864
#define BTRFS_BLOCK_GROUP_PROFILE_MASK (BTRFS_BLOCK_GROUP_RAID0 | \
863865
BTRFS_BLOCK_GROUP_RAID1 | \
866+
BTRFS_BLOCK_GROUP_RAID1C3 | \
864867
BTRFS_BLOCK_GROUP_RAID5 | \
865868
BTRFS_BLOCK_GROUP_RAID6 | \
866869
BTRFS_BLOCK_GROUP_DUP | \
867870
BTRFS_BLOCK_GROUP_RAID10)
868871
#define BTRFS_BLOCK_GROUP_RAID56_MASK (BTRFS_BLOCK_GROUP_RAID5 | \
869872
BTRFS_BLOCK_GROUP_RAID6)
870873

871-
#define BTRFS_BLOCK_GROUP_RAID1_MASK (BTRFS_BLOCK_GROUP_RAID1)
874+
#define BTRFS_BLOCK_GROUP_RAID1_MASK (BTRFS_BLOCK_GROUP_RAID1 | \
875+
BTRFS_BLOCK_GROUP_RAID1C3)
872876

873877
/*
874878
* We need a bit for restriper to be able to tell when chunks of type

0 commit comments

Comments
 (0)