From: Anand Jain <anand.jain@oracle.com>
To: linux-btrfs@vger.kernel.org
Cc: dsterba@suse.com, wqu@suse.com, hrx@bupt.moe, waxhead@dirtcellar.net
Subject: [PATCH v2 3/3] btrfs: add RAID1 preferred read device
Date: Fri, 11 Oct 2024 10:49:18 +0800 [thread overview]
Message-ID: <8152126f6388d65a4a01f785caddefb796d671c2.1728608421.git.anand.jain@oracle.com> (raw)
In-Reply-To: <cover.1728608421.git.anand.jain@oracle.com>
When there's stale data on a mirrored device, this feature lets you choose
which device to read from. Mainly used for testing.
echo "devid:2" > /sys/fs/btrfs/<UUID>/read_policy
Signed-off-by: Anand Jain <anand.jain@oracle.com>
---
fs/btrfs/disk-io.c | 1 +
fs/btrfs/sysfs.c | 32 ++++++++++++++++++++++++++++++--
fs/btrfs/volumes.c | 20 ++++++++++++++++++++
fs/btrfs/volumes.h | 5 +++++
4 files changed, 56 insertions(+), 2 deletions(-)
diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c
index 5b157f407e0a..0e7b29282136 100644
--- a/fs/btrfs/disk-io.c
+++ b/fs/btrfs/disk-io.c
@@ -3322,6 +3322,7 @@ int __cold open_ctree(struct super_block *sb, struct btrfs_fs_devices *fs_device
fs_info->sectorsize = sectorsize;
#ifdef CONFIG_BTRFS_EXPERIMENTAL
fs_info->fs_devices->min_contiguous_read = sectorsize;
+ fs_info->fs_devices->read_devid = fs_info->fs_devices->latest_dev->devid;
#endif
fs_info->sectorsize_bits = ilog2(sectorsize);
fs_info->sectors_per_page = (PAGE_SIZE >> fs_info->sectorsize_bits);
diff --git a/fs/btrfs/sysfs.c b/fs/btrfs/sysfs.c
index 9f506d46a94c..aa4c9cbaa61f 100644
--- a/fs/btrfs/sysfs.c
+++ b/fs/btrfs/sysfs.c
@@ -1306,7 +1306,7 @@ static ssize_t btrfs_temp_fsid_show(struct kobject *kobj,
BTRFS_ATTR(, temp_fsid, btrfs_temp_fsid_show);
#ifdef CONFIG_BTRFS_EXPERIMENTAL
-static const char * const btrfs_read_policy_name[] = { "pid", "rotation", "latency" };
+static const char * const btrfs_read_policy_name[] = { "pid", "rotation", "latency", "devid" };
#else
static const char * const btrfs_read_policy_name[] = { "pid" };
#endif
@@ -1332,8 +1332,11 @@ static ssize_t btrfs_read_policy_show(struct kobject *kobj,
if (i == BTRFS_READ_POLICY_ROTATION)
ret += sysfs_emit_at(buf, ret, ":%d",
fs_devices->min_contiguous_read);
-#endif
+ if (i == BTRFS_READ_POLICY_DEVID)
+ ret += sysfs_emit_at(buf, ret, ":%llu",
+ fs_devices->read_devid);
+#endif
if (i == policy)
ret += sysfs_emit_at(buf, ret, "]");
}
@@ -1401,7 +1404,32 @@ static ssize_t btrfs_read_policy_store(struct kobject *kobj,
return len;
}
+
+ if (index == BTRFS_READ_POLICY_DEVID) {
+ u64 value_devid;
+ BTRFS_DEV_LOOKUP_ARGS(args);
+
+ if (value == NULL || kstrtou64(value, 10, &value_devid))
+ return -EINVAL;
+
+ args.devid = value_devid;
+ if (btrfs_find_device(fs_devices, &args) == NULL)
+ return -EINVAL;
+
+ if (index != READ_ONCE(fs_devices->read_policy) ||
+ (value_devid != READ_ONCE(fs_devices->read_devid))) {
+ WRITE_ONCE(fs_devices->read_policy, index);
+ WRITE_ONCE(fs_devices->read_devid, value_devid);
+
+ btrfs_info(fs_devices->fs_info, "read policy set to '%s:%llu'",
+ btrfs_read_policy_name[index], value_devid);
+
+ }
+
+ return len;
+ }
#endif
+
if (index != READ_ONCE(fs_devices->read_policy)) {
WRITE_ONCE(fs_devices->read_policy, index);
btrfs_info(fs_devices->fs_info, "read policy set to '%s'",
diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c
index 8912ee1d8b54..87a072fa9be4 100644
--- a/fs/btrfs/volumes.c
+++ b/fs/btrfs/volumes.c
@@ -5966,6 +5966,23 @@ unsigned long btrfs_full_stripe_len(struct btrfs_fs_info *fs_info,
}
#ifdef CONFIG_BTRFS_EXPERIMENTAL
+static int btrfs_read_preferred(struct btrfs_chunk_map *map, int first,
+ int num_stripe)
+{
+ int last = first + num_stripe;
+ int stripe_index;
+
+ for (stripe_index = first; stripe_index < last; stripe_index++) {
+ struct btrfs_device *device = map->stripes[stripe_index].dev;
+
+ if (device->devid == READ_ONCE(device->fs_devices->read_devid))
+ return stripe_index;
+ }
+
+ /* If no read-preferred device, use first stripe */
+ return first;
+}
+
static int btrfs_best_stripe(struct btrfs_fs_info *fs_info,
struct btrfs_chunk_map *map, int first,
int num_stripe)
@@ -6079,6 +6096,9 @@ static int find_live_mirror(struct btrfs_fs_info *fs_info,
preferred_mirror = btrfs_best_stripe(fs_info, map, first,
num_stripes);
break;
+ case BTRFS_READ_POLICY_DEVID:
+ preferred_mirror = btrfs_read_preferred(map, first, num_stripes);
+ break;
#endif
}
diff --git a/fs/btrfs/volumes.h b/fs/btrfs/volumes.h
index f9c744b87b61..b5ade9d41fe7 100644
--- a/fs/btrfs/volumes.h
+++ b/fs/btrfs/volumes.h
@@ -308,6 +308,8 @@ enum btrfs_read_policy {
BTRFS_READ_POLICY_ROTATION,
/* Use the lowest-latency device dynamically */
BTRFS_READ_POLICY_LATENCY,
+ /* Read from the specific device */
+ BTRFS_READ_POLICY_DEVID,
#endif
BTRFS_NR_READ_POLICY,
};
@@ -442,6 +444,9 @@ struct btrfs_fs_devices {
/* Min contiguous reads before switching to next device. */
int min_contiguous_read;
+ /* Device to be used for reading in case of RAID1. */
+ u64 read_devid;
+
/* Checksum mode - offload it or do it synchronously. */
enum btrfs_offload_csum_mode offload_csum_mode;
#endif
--
2.46.1
next prev parent reply other threads:[~2024-10-11 2:49 UTC|newest]
Thread overview: 15+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-10-11 2:49 [PATCH v2 0/3] raid1 balancing methods Anand Jain
2024-10-11 2:49 ` [PATCH v2 1/3] btrfs: introduce RAID1 round-robin read balancing Anand Jain
2024-10-11 2:49 ` [PATCH v2 2/3] btrfs: use the path with the lowest latency for RAID1 reads Anand Jain
2024-10-11 2:49 ` Anand Jain [this message]
2024-10-11 3:35 ` [PATCH v2 0/3] raid1 balancing methods Anand Jain
2024-10-11 4:59 ` Qu Wenruo
2024-10-11 6:04 ` Anand Jain
2024-10-21 14:05 ` David Sterba
2024-10-21 15:36 ` Anand Jain
2024-10-21 18:42 ` David Sterba
2024-10-22 0:31 ` Anand Jain
2024-10-21 14:32 ` waxhead
2024-10-21 15:44 ` Anand Jain
2024-10-22 7:07 ` Johannes Thumshirn
2024-10-24 4:39 ` Qu Wenruo
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=8152126f6388d65a4a01f785caddefb796d671c2.1728608421.git.anand.jain@oracle.com \
--to=anand.jain@oracle.com \
--cc=dsterba@suse.com \
--cc=hrx@bupt.moe \
--cc=linux-btrfs@vger.kernel.org \
--cc=waxhead@dirtcellar.net \
--cc=wqu@suse.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).