diff --git a/fs/btrfs/super.c b/fs/btrfs/super.c index 5157037a004837..97d1ef70708eed 100644 --- a/fs/btrfs/super.c +++ b/fs/btrfs/super.c @@ -2527,6 +2527,11 @@ static const struct init_sequence mod_init_seq[] = { }, { .init_func = extent_map_init, .exit_func = extent_map_exit, +#ifdef CONFIG_BTRFS_EXPERIMENTAL + }, { + .init_func = btrfs_raid1_balancing_init, + .exit_func = NULL, +#endif }, { .init_func = ordered_data_init, .exit_func = ordered_data_exit, diff --git a/fs/btrfs/sysfs.c b/fs/btrfs/sysfs.c index 3b290727dba7ee..282197daa7ee61 100644 --- a/fs/btrfs/sysfs.c +++ b/fs/btrfs/sysfs.c @@ -1313,7 +1313,21 @@ static const char *btrfs_read_policy_name[] = { #endif }; -static int btrfs_read_policy_to_enum(const char *str, s64 *value) +#ifdef CONFIG_BTRFS_EXPERIMENTAL +/* Global module configuration parameters */ +static char *raid1_balancing; +char *btrfs_get_raid1_balancing(void) +{ + return raid1_balancing; +} + +/* Set perm 0, disable sys/module/btrfs/parameter/raid1_balancing interface */ +module_param(raid1_balancing, charp, 0); +MODULE_PARM_DESC(raid1_balancing, +"Global read policy; pid (default), round-robin:[min_contiguous_read], devid:[[devid]|[latest-gen]|[oldest-gen]]"); +#endif + +int btrfs_read_policy_to_enum(const char *str, s64 *value) { char param[32] = {'\0'}; char *__maybe_unused value_str; @@ -1348,6 +1362,18 @@ static int btrfs_read_policy_to_enum(const char *str, s64 *value) return -EINVAL; } +#ifdef CONFIG_BTRFS_EXPERIMENTAL +int __init btrfs_raid1_balancing_init(void) +{ + if (btrfs_read_policy_to_enum(raid1_balancing, NULL) == -EINVAL) { + btrfs_err(NULL, "Invalid raid1_balancing %s", raid1_balancing); + return -EINVAL; + } + + return 0; +} +#endif + static ssize_t btrfs_read_policy_show(struct kobject *kobj, struct kobj_attribute *a, char *buf) { diff --git a/fs/btrfs/sysfs.h b/fs/btrfs/sysfs.h index e6a284c59809c9..e97d383b9ffcd4 100644 --- a/fs/btrfs/sysfs.h +++ b/fs/btrfs/sysfs.h @@ -47,5 +47,10 @@ void btrfs_sysfs_del_qgroups(struct btrfs_fs_info *fs_info); int btrfs_sysfs_add_qgroups(struct btrfs_fs_info *fs_info); void btrfs_sysfs_del_one_qgroup(struct btrfs_fs_info *fs_info, struct btrfs_qgroup *qgroup); +int btrfs_read_policy_to_enum(const char *str, s64 *value); +#ifdef CONFIG_BTRFS_EXPERIMENTAL +int __init btrfs_raid1_balancing_init(void); +char *btrfs_get_raid1_balancing(void); +#endif #endif diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c index 2025d263e73a0e..2d9d478ac03fc1 100644 --- a/fs/btrfs/volumes.c +++ b/fs/btrfs/volumes.c @@ -1328,10 +1328,13 @@ static int open_fs_devices(struct btrfs_fs_devices *fs_devices, fs_devices->latest_dev = latest_dev; fs_devices->total_rw_bytes = 0; fs_devices->chunk_alloc_policy = BTRFS_CHUNK_ALLOC_REGULAR; - fs_devices->read_policy = BTRFS_READ_POLICY_PID; #ifdef CONFIG_BTRFS_EXPERIMENTAL fs_devices->rr_min_contiguous_read = BTRFS_DEFAULT_RR_MIN_CONTIGUOUS_READ; fs_devices->read_devid = latest_dev->devid; + fs_devices->read_policy = + btrfs_read_policy_to_enum(btrfs_get_raid1_balancing(), NULL); +#else + fs_devices->read_policy = BTRFS_READ_POLICY_PID; #endif return 0;