Commit 4dc4a3be authored by Naohiro Aota's avatar Naohiro Aota Committed by David Sterba
Browse files

btrfs: use READ/WRITE_ONCE for fs_devices->read_policy



Since we can read/modify the value from the sysfs interface concurrently,
it would be better to protect it from compiler optimizations.

Currently, there is only one read policy BTRFS_READ_POLICY_PID available,
so no actual problem can happen now. This is a preparation for the future
expansion.

Reviewed-by: default avatarAnand Jain <anand.jain@oracle.com>
Signed-off-by: default avatarNaohiro Aota <naohiro.aota@wdc.com>
Reviewed-by: default avatarDavid Sterba <dsterba@suse.com>
Signed-off-by: default avatarDavid Sterba <dsterba@suse.com>
parent e383e158
Loading
Loading
Loading
Loading
+4 −3
Original line number Diff line number Diff line
@@ -1228,11 +1228,12 @@ static ssize_t btrfs_read_policy_show(struct kobject *kobj,
				      struct kobj_attribute *a, char *buf)
{
	struct btrfs_fs_devices *fs_devices = to_fs_devs(kobj);
	const enum btrfs_read_policy policy = READ_ONCE(fs_devices->read_policy);
	ssize_t ret = 0;
	int i;

	for (i = 0; i < BTRFS_NR_READ_POLICY; i++) {
		if (fs_devices->read_policy == i)
		if (policy == i)
			ret += sysfs_emit_at(buf, ret, "%s[%s]",
					 (ret == 0 ? "" : " "),
					 btrfs_read_policy_name[i]);
@@ -1256,8 +1257,8 @@ static ssize_t btrfs_read_policy_store(struct kobject *kobj,

	for (i = 0; i < BTRFS_NR_READ_POLICY; i++) {
		if (sysfs_streq(buf, btrfs_read_policy_name[i])) {
			if (i != fs_devices->read_policy) {
				fs_devices->read_policy = i;
			if (i != READ_ONCE(fs_devices->read_policy)) {
				WRITE_ONCE(fs_devices->read_policy, i);
				btrfs_info(fs_devices->fs_info,
					   "read policy set to '%s'",
					   btrfs_read_policy_name[i]);
+5 −5
Original line number Diff line number Diff line
@@ -5942,6 +5942,7 @@ static int find_live_mirror(struct btrfs_fs_info *fs_info,
			    struct btrfs_chunk_map *map, int first,
			    int dev_replace_is_ongoing)
{
	const enum btrfs_read_policy policy = READ_ONCE(fs_info->fs_devices->read_policy);
	int i;
	int num_stripes;
	int preferred_mirror;
@@ -5956,13 +5957,12 @@ static int find_live_mirror(struct btrfs_fs_info *fs_info,
	else
		num_stripes = map->num_stripes;

	switch (fs_info->fs_devices->read_policy) {
	switch (policy) {
	default:
		/* Shouldn't happen, just warn and use pid instead of failing */
		btrfs_warn_rl(fs_info,
			      "unknown read_policy type %u, reset to pid",
			      fs_info->fs_devices->read_policy);
		fs_info->fs_devices->read_policy = BTRFS_READ_POLICY_PID;
		btrfs_warn_rl(fs_info, "unknown read_policy type %u, reset to pid",
			      policy);
		WRITE_ONCE(fs_info->fs_devices->read_policy, BTRFS_READ_POLICY_PID);
		fallthrough;
	case BTRFS_READ_POLICY_PID:
		preferred_mirror = first + (current->pid % num_stripes);