Skip to content

Commit 4426a9c

Browse files
committed
btrfs: add filtering by latency to btrfs_read_rr
This introduces a new parameter to btrfs_read_rr to select whether we filter for latency. In case the caller passes latency, we return -1 if no stripe qualified. Signed-off-by: Kai Krakow <[email protected]>
1 parent 0eb4c27 commit 4426a9c

File tree

1 file changed

+27
-3
lines changed

1 file changed

+27
-3
lines changed

fs/btrfs/volumes.c

Lines changed: 27 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6090,7 +6090,8 @@ static int btrfs_cmp_devid(const void *a, const void *b)
60906090
* The calculated stripe index is then used to select the corresponding device
60916091
* from the list of devices, which is ordered by devid.
60926092
*/
6093-
static int btrfs_read_rr(struct btrfs_chunk_map *map, int first, int num_stripe)
6093+
static int btrfs_read_rr(struct btrfs_chunk_map *map, int first, int num_stripes,
6094+
u64 min_latency)
60946095
{
60956096
struct stripe_mirror stripes[BTRFS_RAID1_MAX_MIRRORS] = {0};
60966097
struct btrfs_device *device = map->stripes[first].dev;
@@ -6106,11 +6107,34 @@ static int btrfs_read_rr(struct btrfs_chunk_map *map, int first, int num_stripe)
61066107
fs_info->sectorsize_bits;
61076108

61086109
index = 0;
6109-
for (int i = first; i < first + num_stripe; i++) {
6110+
for (int i = first; i < first + num_stripes; i++) {
6111+
if (min_latency > 0) {
6112+
u64 read_wait;
6113+
u64 avg_wait = 0;
6114+
unsigned long read_ios;
6115+
struct btrfs_device *device = map->stripes[index].dev;
6116+
6117+
read_wait = part_stat_read(device->bdev, nsecs[READ]);
6118+
read_ios = part_stat_read(device->bdev, ios[READ]);
6119+
6120+
if (read_wait && read_ios && read_wait >= read_ios)
6121+
avg_wait = div_u64(read_wait, read_ios);
6122+
6123+
if (min_latency < avg_wait)
6124+
continue;
6125+
}
6126+
61106127
stripes[index].devid = map->stripes[i].dev->devid;
61116128
stripes[index].num = i;
61126129
index++;
61136130
}
6131+
6132+
/* if the caller passed a minimum latency and we filtered for no
6133+
* stripes, return -1 to indicate that no stripe qualified.
6134+
*/
6135+
if (min_latency && !index)
6136+
return -1;
6137+
61146138
sort(stripes, index, sizeof(struct stripe_mirror),
61156139
btrfs_cmp_devid, NULL);
61166140

@@ -6152,7 +6176,7 @@ static int find_live_mirror(struct btrfs_fs_info *fs_info,
61526176
break;
61536177
#ifdef CONFIG_BTRFS_EXPERIMENTAL
61546178
case BTRFS_READ_POLICY_RR:
6155-
preferred_mirror = btrfs_read_rr(map, first, num_stripes);
6179+
preferred_mirror = btrfs_read_rr(map, first, num_stripes, 0);
61566180
break;
61576181
case BTRFS_READ_POLICY_DEVID:
61586182
preferred_mirror = btrfs_read_preferred(map, first, num_stripes);

0 commit comments

Comments
 (0)