mirror of
https://github.com/kdave/btrfs-progs
synced 2025-02-16 17:56:51 +00:00
btrfs-progs: allow zoned RAID
Allow for RAID levels 0, 1 and 10 on zoned devices if the RAID stripe tree is used. Signed-off-by: Johannes Thumshirn <johannes.thumshirn@wdc.com> Signed-off-by: David Sterba <dsterba@suse.com>
This commit is contained in:
parent
81d6ecd5c2
commit
b4ab282686
@ -190,6 +190,14 @@ static const struct btrfs_feature mkfs_features[] = {
|
|||||||
VERSION_NULL(safe),
|
VERSION_NULL(safe),
|
||||||
VERSION_NULL(default),
|
VERSION_NULL(default),
|
||||||
.desc = "new extent tree format"
|
.desc = "new extent tree format"
|
||||||
|
} , {
|
||||||
|
.name = "raid-stripe-tree",
|
||||||
|
.incompat_flag = BTRFS_FEATURE_INCOMPAT_RAID_STRIPE_TREE,
|
||||||
|
.sysfs_name = NULL,
|
||||||
|
VERSION_TO_STRING2(compat, 6,7),
|
||||||
|
VERSION_NULL(safe),
|
||||||
|
VERSION_NULL(default),
|
||||||
|
.desc = "raid stripe tree"
|
||||||
},
|
},
|
||||||
#endif
|
#endif
|
||||||
/* Keep this one last */
|
/* Keep this one last */
|
||||||
|
@ -103,7 +103,8 @@ static inline u32 __BTRFS_LEAF_DATA_SIZE(u32 nodesize)
|
|||||||
BTRFS_FEATURE_INCOMPAT_RAID1C34 | \
|
BTRFS_FEATURE_INCOMPAT_RAID1C34 | \
|
||||||
BTRFS_FEATURE_INCOMPAT_METADATA_UUID | \
|
BTRFS_FEATURE_INCOMPAT_METADATA_UUID | \
|
||||||
BTRFS_FEATURE_INCOMPAT_ZONED | \
|
BTRFS_FEATURE_INCOMPAT_ZONED | \
|
||||||
BTRFS_FEATURE_INCOMPAT_EXTENT_TREE_V2)
|
BTRFS_FEATURE_INCOMPAT_EXTENT_TREE_V2 | \
|
||||||
|
BTRFS_FEATURE_INCOMPAT_RAID_STRIPE_TREE)
|
||||||
#else
|
#else
|
||||||
#define BTRFS_FEATURE_INCOMPAT_SUPP \
|
#define BTRFS_FEATURE_INCOMPAT_SUPP \
|
||||||
(BTRFS_FEATURE_INCOMPAT_MIXED_BACKREF | \
|
(BTRFS_FEATURE_INCOMPAT_MIXED_BACKREF | \
|
||||||
|
@ -737,7 +737,7 @@ out:
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool zoned_profile_supported(u64 map_type)
|
bool zoned_profile_supported(u64 map_type, bool rst)
|
||||||
{
|
{
|
||||||
bool data = (map_type & BTRFS_BLOCK_GROUP_DATA);
|
bool data = (map_type & BTRFS_BLOCK_GROUP_DATA);
|
||||||
u64 flags = (map_type & BTRFS_BLOCK_GROUP_PROFILE_MASK);
|
u64 flags = (map_type & BTRFS_BLOCK_GROUP_PROFILE_MASK);
|
||||||
@ -746,9 +746,37 @@ bool zoned_profile_supported(u64 map_type)
|
|||||||
if (flags == 0)
|
if (flags == 0)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
/* We can support DUP on metadata */
|
#if EXPERIMENTAL
|
||||||
|
if (data) {
|
||||||
|
if ((flags & BTRFS_BLOCK_GROUP_DUP) && rst)
|
||||||
|
return true;
|
||||||
|
/* Data RAID1 needs a raid-stripe-tree. */
|
||||||
|
if ((flags & BTRFS_BLOCK_GROUP_RAID1_MASK) && rst)
|
||||||
|
return true;
|
||||||
|
/* Data RAID0 needs a raid-stripe-tree. */
|
||||||
|
if ((flags & BTRFS_BLOCK_GROUP_RAID0) && rst)
|
||||||
|
return true;
|
||||||
|
/* Data RAID10 needs a raid-stripe-tree. */
|
||||||
|
if ((flags & BTRFS_BLOCK_GROUP_RAID10) && rst)
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
/* We can support DUP on metadata/system. */
|
||||||
|
if (flags & BTRFS_BLOCK_GROUP_DUP)
|
||||||
|
return true;
|
||||||
|
/* We can support RAID1 on metadata/system. */
|
||||||
|
if (flags & BTRFS_BLOCK_GROUP_RAID1_MASK)
|
||||||
|
return true;
|
||||||
|
/* We can support RAID0 on metadata/system. */
|
||||||
|
if (flags & BTRFS_BLOCK_GROUP_RAID0)
|
||||||
|
return true;
|
||||||
|
/* We can support RAID10 on metadata/system. */
|
||||||
|
if (flags & BTRFS_BLOCK_GROUP_RAID10)
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
#else
|
||||||
if (!data && (flags & BTRFS_BLOCK_GROUP_DUP))
|
if (!data && (flags & BTRFS_BLOCK_GROUP_DUP))
|
||||||
return true;
|
return true;
|
||||||
|
#endif
|
||||||
|
|
||||||
/* All other profiles are not supported yet */
|
/* All other profiles are not supported yet */
|
||||||
return false;
|
return false;
|
||||||
@ -863,7 +891,7 @@ int btrfs_load_block_group_zone_info(struct btrfs_fs_info *fs_info,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!zoned_profile_supported(map->type)) {
|
if (!zoned_profile_supported(map->type, !!fs_info->stripe_root)) {
|
||||||
error("zoned: profile %s not yet supported",
|
error("zoned: profile %s not yet supported",
|
||||||
btrfs_group_profile_str(map->type));
|
btrfs_group_profile_str(map->type));
|
||||||
ret = -EINVAL;
|
ret = -EINVAL;
|
||||||
|
@ -133,7 +133,7 @@ static inline bool btrfs_dev_is_empty_zone(struct btrfs_device *device, u64 pos)
|
|||||||
return zinfo->zones[zno].cond == BLK_ZONE_COND_EMPTY;
|
return zinfo->zones[zno].cond == BLK_ZONE_COND_EMPTY;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool zoned_profile_supported(u64 map_type);
|
bool zoned_profile_supported(u64 map_type, bool rst);
|
||||||
int btrfs_reset_dev_zone(int fd, struct blk_zone *zone);
|
int btrfs_reset_dev_zone(int fd, struct blk_zone *zone);
|
||||||
u64 btrfs_find_allocatable_zones(struct btrfs_device *device, u64 hole_start,
|
u64 btrfs_find_allocatable_zones(struct btrfs_device *device, u64 hole_start,
|
||||||
u64 hole_end, u64 num_bytes);
|
u64 hole_end, u64 num_bytes);
|
||||||
@ -214,7 +214,7 @@ static inline int btrfs_wipe_temporary_sb(struct btrfs_fs_devices *fs_devices)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline bool zoned_profile_supported(u64 map_type)
|
static inline bool zoned_profile_supported(u64 map_type, bool rst)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
70
mkfs/main.c
70
mkfs/main.c
@ -962,6 +962,36 @@ fail:
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int setup_raid_stripe_tree_root(struct btrfs_fs_info *fs_info)
|
||||||
|
{
|
||||||
|
struct btrfs_trans_handle *trans;
|
||||||
|
struct btrfs_root *stripe_root;
|
||||||
|
struct btrfs_key key = {
|
||||||
|
.objectid = BTRFS_RAID_STRIPE_TREE_OBJECTID,
|
||||||
|
.type = BTRFS_ROOT_ITEM_KEY,
|
||||||
|
};
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
trans = btrfs_start_transaction(fs_info->tree_root, 0);
|
||||||
|
if (IS_ERR(trans))
|
||||||
|
return PTR_ERR(trans);
|
||||||
|
|
||||||
|
stripe_root = btrfs_create_tree(trans, fs_info, &key);
|
||||||
|
if (IS_ERR(stripe_root)) {
|
||||||
|
ret = PTR_ERR(stripe_root);
|
||||||
|
btrfs_abort_transaction(trans, ret);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
fs_info->stripe_root = stripe_root;
|
||||||
|
add_root_to_dirty_list(stripe_root);
|
||||||
|
|
||||||
|
ret = btrfs_commit_transaction(trans, fs_info->tree_root);
|
||||||
|
if (ret)
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
/* Thread callback for device preparation */
|
/* Thread callback for device preparation */
|
||||||
static void *prepare_one_device(void *ctx)
|
static void *prepare_one_device(void *ctx)
|
||||||
{
|
{
|
||||||
@ -1472,11 +1502,39 @@ int BOX_MAIN(mkfs)(int argc, char **argv)
|
|||||||
if (ret)
|
if (ret)
|
||||||
goto error;
|
goto error;
|
||||||
|
|
||||||
if (opt_zoned && (!zoned_profile_supported(BTRFS_BLOCK_GROUP_METADATA | metadata_profile) ||
|
#if EXPERIMENTAL
|
||||||
!zoned_profile_supported(BTRFS_BLOCK_GROUP_DATA | data_profile))) {
|
if (opt_zoned && device_count) {
|
||||||
|
switch (data_profile & BTRFS_BLOCK_GROUP_PROFILE_MASK) {
|
||||||
|
case BTRFS_BLOCK_GROUP_DUP:
|
||||||
|
case BTRFS_BLOCK_GROUP_RAID1:
|
||||||
|
case BTRFS_BLOCK_GROUP_RAID1C3:
|
||||||
|
case BTRFS_BLOCK_GROUP_RAID1C4:
|
||||||
|
case BTRFS_BLOCK_GROUP_RAID0:
|
||||||
|
case BTRFS_BLOCK_GROUP_RAID10:
|
||||||
|
features.incompat_flags |= BTRFS_FEATURE_INCOMPAT_RAID_STRIPE_TREE;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (opt_zoned) {
|
||||||
|
u64 metadata = BTRFS_BLOCK_GROUP_METADATA | metadata_profile;
|
||||||
|
u64 data = BTRFS_BLOCK_GROUP_DATA | data_profile;
|
||||||
|
bool rst = false;
|
||||||
|
|
||||||
|
#if EXPERIMENTAL
|
||||||
|
if (features.incompat_flags & BTRFS_FEATURE_INCOMPAT_RAID_STRIPE_TREE)
|
||||||
|
rst = true;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (!zoned_profile_supported(metadata, rst) ||
|
||||||
|
!zoned_profile_supported(data, rst)) {
|
||||||
error("zoned mode does not yet support RAID/DUP profiles, please specify '-d single -m single' manually");
|
error("zoned mode does not yet support RAID/DUP profiles, please specify '-d single -m single' manually");
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
t_prepare = calloc(device_count, sizeof(*t_prepare));
|
t_prepare = calloc(device_count, sizeof(*t_prepare));
|
||||||
prepare_ctx = calloc(device_count, sizeof(*prepare_ctx));
|
prepare_ctx = calloc(device_count, sizeof(*prepare_ctx));
|
||||||
@ -1585,6 +1643,14 @@ int BOX_MAIN(mkfs)(int argc, char **argv)
|
|||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (features.incompat_flags & BTRFS_FEATURE_INCOMPAT_RAID_STRIPE_TREE) {
|
||||||
|
ret = setup_raid_stripe_tree_root(fs_info);
|
||||||
|
if (ret < 0) {
|
||||||
|
error("failed to initialize raid-stripe-tree: %d (%m)", ret);
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
trans = btrfs_start_transaction(root, 1);
|
trans = btrfs_start_transaction(root, 1);
|
||||||
if (IS_ERR(trans)) {
|
if (IS_ERR(trans)) {
|
||||||
errno = -PTR_ERR(trans);
|
errno = -PTR_ERR(trans);
|
||||||
|
Loading…
Reference in New Issue
Block a user