Skip to content

Commit

Permalink
btrfs: configure read policy via module parameter
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
asj authored and kdave committed Jan 3, 2025
1 parent dc9ba29 commit a2b8e25
Show file tree
Hide file tree
Showing 4 changed files with 55 additions and 2 deletions.
5 changes: 5 additions & 0 deletions fs/btrfs/super.c
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
31 changes: 30 additions & 1 deletion fs/btrfs/sysfs.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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)
{
Expand Down
6 changes: 6 additions & 0 deletions fs/btrfs/sysfs.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
15 changes: 14 additions & 1 deletion fs/btrfs/volumes.c
Original file line number Diff line number Diff line change
Expand Up @@ -1300,6 +1300,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. */
Expand Down Expand Up @@ -1334,10 +1335,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;
Expand Down

0 comments on commit a2b8e25

Please sign in to comment.