]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
btrfs: create read policy framework
authorAnand Jain <anand.jain@oracle.com>
Wed, 28 Oct 2020 13:14:46 +0000 (21:14 +0800)
committerDavid Sterba <dsterba@suse.com>
Tue, 8 Dec 2020 14:53:44 +0000 (15:53 +0100)
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: Josef Bacik <josef@toxicpanda.com>
Signed-off-by: Anand Jain <anand.jain@oracle.com>
Reviewed-by: David Sterba <dsterba@suse.com>
Signed-off-by: David Sterba <dsterba@suse.com>
fs/btrfs/volumes.c
fs/btrfs/volumes.h

index 07c6b0c853396867b88ab147e4c3b34f5d7e113d..ed4163b54f756221cdc19d6be21c8b84e1b9cda7 100644 (file)
@@ -1217,6 +1217,7 @@ static int open_fs_devices(struct btrfs_fs_devices *fs_devices,
        fs_devices->latest_bdev = latest_dev->bdev;
        fs_devices->total_rw_bytes = 0;
        fs_devices->chunk_alloc_policy = BTRFS_CHUNK_ALLOC_REGULAR;
+       fs_devices->read_policy = BTRFS_READ_POLICY_PID;
 
        return 0;
 }
@@ -5479,7 +5480,18 @@ static int find_live_mirror(struct btrfs_fs_info *fs_info,
        else
                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 &&
            fs_info->dev_replace.cont_reading_from_srcdev_mode ==
index 232f02bd214fc44e013574357c1e3cd926c6e77f..34fd440fd30b37fd865602073ed74a3a61ed66e7 100644 (file)
@@ -211,6 +211,16 @@ enum btrfs_chunk_allocation_policy {
        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 {
        u8 fsid[BTRFS_FSID_SIZE]; /* FS specific uuid */
        u8 metadata_uuid[BTRFS_FSID_SIZE];
@@ -264,6 +274,9 @@ struct btrfs_fs_devices {
        struct completion kobj_unregister;
 
        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