Commit 33fd2f71 authored by Anand Jain's avatar Anand Jain Committed by David Sterba

btrfs: create read policy framework

As of now, we use the pid method to read striped mirrored data, which
means process id determines the stripe id to read. This type of routing
typically helps in a system with many small independent processes tying
to read random data. On the other hand, the pid based read IO policy is
inefficient because if there is a single process trying to read a large
file, the overall disk bandwidth remains underutilized.

So this patch introduces a read policy framework so that we could add
more read policies, such as IO routing based on the device's wait-queue
or manual when we have a read-preferred device or a policy based on the
target storage caching.
Reviewed-by: default avatarJosef Bacik <josef@toxicpanda.com>
Signed-off-by: default avatarAnand Jain <anand.jain@oracle.com>
Reviewed-by: default avatarDavid Sterba <dsterba@suse.com>
Signed-off-by: default avatarDavid Sterba <dsterba@suse.com>
parent aaefed20
...@@ -1217,6 +1217,7 @@ static int open_fs_devices(struct btrfs_fs_devices *fs_devices, ...@@ -1217,6 +1217,7 @@ static int open_fs_devices(struct btrfs_fs_devices *fs_devices,
fs_devices->latest_bdev = latest_dev->bdev; fs_devices->latest_bdev = latest_dev->bdev;
fs_devices->total_rw_bytes = 0; fs_devices->total_rw_bytes = 0;
fs_devices->chunk_alloc_policy = BTRFS_CHUNK_ALLOC_REGULAR; fs_devices->chunk_alloc_policy = BTRFS_CHUNK_ALLOC_REGULAR;
fs_devices->read_policy = BTRFS_READ_POLICY_PID;
return 0; return 0;
} }
...@@ -5479,7 +5480,18 @@ static int find_live_mirror(struct btrfs_fs_info *fs_info, ...@@ -5479,7 +5480,18 @@ static int find_live_mirror(struct btrfs_fs_info *fs_info,
else else
num_stripes = map->num_stripes; num_stripes = map->num_stripes;
preferred_mirror = first + current->pid % num_stripes; switch (fs_info->fs_devices->read_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;
fallthrough;
case BTRFS_READ_POLICY_PID:
preferred_mirror = first + (current->pid % num_stripes);
break;
}
if (dev_replace_is_ongoing && if (dev_replace_is_ongoing &&
fs_info->dev_replace.cont_reading_from_srcdev_mode == fs_info->dev_replace.cont_reading_from_srcdev_mode ==
......
...@@ -211,6 +211,16 @@ enum btrfs_chunk_allocation_policy { ...@@ -211,6 +211,16 @@ enum btrfs_chunk_allocation_policy {
BTRFS_CHUNK_ALLOC_REGULAR, BTRFS_CHUNK_ALLOC_REGULAR,
}; };
/*
* Read policies for mirrored block group profiles, read picks the stripe based
* on these policies.
*/
enum btrfs_read_policy {
/* Use process PID to choose the stripe */
BTRFS_READ_POLICY_PID,
BTRFS_NR_READ_POLICY,
};
struct btrfs_fs_devices { struct btrfs_fs_devices {
u8 fsid[BTRFS_FSID_SIZE]; /* FS specific uuid */ u8 fsid[BTRFS_FSID_SIZE]; /* FS specific uuid */
u8 metadata_uuid[BTRFS_FSID_SIZE]; u8 metadata_uuid[BTRFS_FSID_SIZE];
...@@ -264,6 +274,9 @@ struct btrfs_fs_devices { ...@@ -264,6 +274,9 @@ struct btrfs_fs_devices {
struct completion kobj_unregister; struct completion kobj_unregister;
enum btrfs_chunk_allocation_policy chunk_alloc_policy; enum btrfs_chunk_allocation_policy chunk_alloc_policy;
/* Policy used to read the mirrored stripes */
enum btrfs_read_policy read_policy;
}; };
#define BTRFS_BIO_INLINE_CSUM_SIZE 64 #define BTRFS_BIO_INLINE_CSUM_SIZE 64
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment