@@ -916,7 +916,8 @@ static bool strmatch(const char *buffer, const char *string)
}
/* Must follow the order as in enum btrfs_read_policy */
-static const char * const btrfs_read_policy_name[] = { "pid", "latency" };
+static const char * const btrfs_read_policy_name[] = { "pid", "latency",
+ "device" };
static ssize_t btrfs_read_policy_show(struct kobject *kobj,
struct kobj_attribute *a, char *buf)
@@ -5524,6 +5524,25 @@ static int btrfs_find_best_stripe(struct btrfs_fs_info *fs_info,
return best_stripe;
}
+static int btrfs_find_read_preferred(struct map_lookup *map, int first, int num_stripe)
+{
+ int stripe_index;
+ int last = first + num_stripe;
+
+ /*
+ * If there are more than one read preferred devices, then just pick the
+ * first found read preferred device as of now.
+ */
+ for (stripe_index = first; stripe_index < last; stripe_index++) {
+ if (test_bit(BTRFS_DEV_STATE_READ_PREFERRED,
+ &map->stripes[stripe_index].dev->dev_state))
+ return stripe_index;
+ }
+
+ /* If there is no read preferred device then just use the first stripe */
+ return first;
+}
+
static int find_live_mirror(struct btrfs_fs_info *fs_info,
struct map_lookup *map, int first,
int dev_replace_is_ongoing)
@@ -5557,6 +5576,9 @@ static int find_live_mirror(struct btrfs_fs_info *fs_info,
preferred_mirror = btrfs_find_best_stripe(fs_info, map, first,
num_stripes);
break;
+ case BTRFS_READ_POLICY_DEVICE:
+ preferred_mirror = btrfs_find_read_preferred(map, first, num_stripes);
+ break;
}
if (dev_replace_is_ongoing &&
@@ -225,6 +225,8 @@ enum btrfs_read_policy {
BTRFS_READ_POLICY_PID,
/* Find and use device with the lowest latency */
BTRFS_READ_POLICY_LATENCY,
+ /* Use the device marked with READ_PREFERRED state */
+ BTRFS_READ_POLICY_DEVICE,
BTRFS_NR_READ_POLICY,
};