@@ -2538,6 +2538,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,
@@ -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;
@@ -1336,6 +1350,20 @@ static int btrfs_read_policy_to_enum(const char *str, s64 *value)
return sysfs_match_string(btrfs_read_policy_name, param);
}
+#ifdef CONFIG_BTRFS_EXPERIMENTAL
+int __init btrfs_raid1_balancing_init(void)
+{
+ s64 value;
+
+ if (btrfs_read_policy_to_enum(raid1_balancing, &value) == -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)
{
@@ -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
@@ -1299,6 +1299,7 @@ static int open_fs_devices(struct btrfs_fs_devices *fs_devices,
struct btrfs_device *device;
struct btrfs_device *latest_dev = NULL;
struct btrfs_device *tmp_device;
+ s64 __maybe_unused value = 0;
int ret = 0;
/* Initialize the in-memory record of filesystem read count */
@@ -1333,10 +1334,21 @@ 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(), &value);
+ if (fs_devices->read_policy == BTRFS_READ_POLICY_RR)
+ fs_devices->fs_stats = true;
+ if (value) {
+ if (fs_devices->read_policy == BTRFS_READ_POLICY_RR)
+ fs_devices->rr_min_contiguous_read = value;
+ if (fs_devices->read_policy == BTRFS_READ_POLICY_DEVID)
+ fs_devices->read_devid = value;
+ }
+#else
+ fs_devices->read_policy = BTRFS_READ_POLICY_PID;
#endif
return 0;
This update allows configuring the `raid1-balancing` methods using a modprobe parameter when experimental mode CONFIG_BTRFS_EXPERIMENTAL is enabled. Examples: - Set the RAID1 balancing method to round-robin with a custom `min_contiguous_read` of 4k: $ modprobe btrfs raid1-balancing=round-robin:4096 - Set the round-robin balancing method with the default `min_contiguous_read`: $ modprobe btrfs raid1-balancing=round-robin - Set the `devid` balancing method, defaulting to the latest device: $ modprobe btrfs raid1-balancing=devid Signed-off-by: Anand Jain <anand.jain@oracle.com> --- fs/btrfs/super.c | 5 +++++ fs/btrfs/sysfs.c | 30 +++++++++++++++++++++++++++++- fs/btrfs/sysfs.h | 5 +++++ fs/btrfs/volumes.c | 14 +++++++++++++- 4 files changed, 52 insertions(+), 2 deletions(-)