]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
btrfs: configure read policy via module parameter
authorAnand Jain <anand.jain@oracle.com>
Wed, 1 Jan 2025 18:06:38 +0000 (02:06 +0800)
committerDavid Sterba <dsterba@suse.com>
Mon, 13 Jan 2025 13:53:21 +0000 (14:53 +0100)
For testing purposes allow to configure the read policy via module
parameter from the beginning. Available only with CONFIG_BTRFS_EXPERIMENTAL

Examples:

- Set the RAID1 balancing method to round-robin with a custom
  min_contig_read of 4k:
  $ modprobe btrfs read_policy=round-robin:4096

- Set the round-robin balancing method with the default
  min_contiguous_read:
  $ modprobe btrfs read_policy=round-robin

- Set the "devid" balancing method, defaulting to the latest device:
  $ modprobe btrfs read_policy=devid

Signed-off-by: Anand Jain <anand.jain@oracle.com>
Signed-off-by: David Sterba <dsterba@suse.com>
fs/btrfs/super.c
fs/btrfs/sysfs.c
fs/btrfs/sysfs.h
fs/btrfs/volumes.c

index 5157037a00483760cfa64420ed36153f475dcd0c..f310cfa0b5b45b85c64408303fc10a4c43af4aac 100644 (file)
@@ -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_read_policy_init,
+               .exit_func = NULL,
+#endif
        }, {
                .init_func = ordered_data_init,
                .exit_func = ordered_data_exit,
index 5211d13d73f8aa4ddd051b557363ffe78c300215..53b846d99ecea8dbd7b87378c6c495927e62c8e9 100644 (file)
@@ -1313,7 +1313,22 @@ static const char *btrfs_read_policy_name[] = {
 #endif
 };
 
-static int btrfs_read_policy_to_enum(const char *str, s64 *value_ret)
+#ifdef CONFIG_BTRFS_EXPERIMENTAL
+
+/* Global module configuration parameters. */
+static char *read_policy;
+char *btrfs_get_mod_read_policy(void)
+{
+       return read_policy;
+}
+
+/* Set perms to 0, disable /sys/module/btrfs/parameter/read_policy interface. */
+module_param(read_policy, charp, 0);
+MODULE_PARM_DESC(read_policy,
+"Global read policy: pid (default), round-robin[:<min_contig_read>], devid[:<devid>]");
+#endif
+
+int btrfs_read_policy_to_enum(const char *str, s64 *value_ret)
 {
        char param[32] = { 0 };
        char __maybe_unused *value_str;
@@ -1344,6 +1359,20 @@ static int btrfs_read_policy_to_enum(const char *str, s64 *value_ret)
        return sysfs_match_string(btrfs_read_policy_name, param);
 }
 
+#ifdef CONFIG_BTRFS_EXPERIMENTAL
+int __init btrfs_read_policy_init(void)
+{
+       s64 value;
+
+       if (btrfs_read_policy_to_enum(read_policy, &value) == -EINVAL) {
+               btrfs_err(NULL, "invalid read policy or value %s", read_policy);
+               return -EINVAL;
+       }
+
+       return 0;
+}
+#endif
+
 static ssize_t btrfs_read_policy_show(struct kobject *kobj,
                                      struct kobj_attribute *a, char *buf)
 {
index e6a284c59809c9696eb1fa8cb1e2f29c800acf37..3fc5c6f90dc42dd464290f2e7602b1acd0ffd3e5 100644 (file)
@@ -47,5 +47,11 @@ 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_read_policy_init(void);
+char *btrfs_get_mod_read_policy(void);
+#endif
 
 #endif
index b5fd1aa45c4c838dbd84fbcd09bb685a0032e62f..a594f66daedf0a162f04899c2ffe4160aca279fc 100644 (file)
@@ -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;
 
        list_for_each_entry_safe(device, tmp_device, &fs_devices->devices,
@@ -1328,10 +1329,22 @@ 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_contig_read = BTRFS_DEFAULT_RR_MIN_CONTIG_READ;
        fs_devices->read_devid = latest_dev->devid;
+       fs_devices->read_policy = btrfs_read_policy_to_enum(btrfs_get_mod_read_policy(),
+                                                           &value);
+       if (fs_devices->read_policy == BTRFS_READ_POLICY_RR)
+               fs_devices->collect_fs_stats = true;
+
+       if (value) {
+               if (fs_devices->read_policy == BTRFS_READ_POLICY_RR)
+                       fs_devices->rr_min_contig_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;