|
|
|
@@ -4994,7 +4994,7 @@ static int __btrfs_map_block(struct btrfs_fs_info *fs_info, int rw,
|
|
|
|
|
* stripe_nr counts the total number of stripes we have to stride
|
|
|
|
|
* to get to this block
|
|
|
|
|
*/
|
|
|
|
|
do_div(stripe_nr, stripe_len);
|
|
|
|
|
stripe_nr = div64_u64(stripe_nr, stripe_len);
|
|
|
|
|
|
|
|
|
|
stripe_offset = stripe_nr * stripe_len;
|
|
|
|
|
BUG_ON(offset < stripe_offset);
|
|
|
|
@@ -5010,7 +5010,8 @@ static int __btrfs_map_block(struct btrfs_fs_info *fs_info, int rw,
|
|
|
|
|
/* allow a write of a full stripe, but make sure we don't
|
|
|
|
|
* allow straddling of stripes
|
|
|
|
|
*/
|
|
|
|
|
do_div(raid56_full_stripe_start, full_stripe_len);
|
|
|
|
|
raid56_full_stripe_start = div64_u64(raid56_full_stripe_start,
|
|
|
|
|
full_stripe_len);
|
|
|
|
|
raid56_full_stripe_start *= full_stripe_len;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@@ -5143,7 +5144,8 @@ static int __btrfs_map_block(struct btrfs_fs_info *fs_info, int rw,
|
|
|
|
|
if (rw & REQ_DISCARD)
|
|
|
|
|
num_stripes = min_t(u64, map->num_stripes,
|
|
|
|
|
stripe_nr_end - stripe_nr_orig);
|
|
|
|
|
stripe_index = do_div(stripe_nr, map->num_stripes);
|
|
|
|
|
stripe_nr = div_u64_rem(stripe_nr, map->num_stripes,
|
|
|
|
|
&stripe_index);
|
|
|
|
|
if (!(rw & (REQ_WRITE | REQ_DISCARD | REQ_GET_READ_MIRRORS)))
|
|
|
|
|
mirror_num = 1;
|
|
|
|
|
} else if (map->type & BTRFS_BLOCK_GROUP_RAID1) {
|
|
|
|
@@ -5171,7 +5173,7 @@ static int __btrfs_map_block(struct btrfs_fs_info *fs_info, int rw,
|
|
|
|
|
} else if (map->type & BTRFS_BLOCK_GROUP_RAID10) {
|
|
|
|
|
int factor = map->num_stripes / map->sub_stripes;
|
|
|
|
|
|
|
|
|
|
stripe_index = do_div(stripe_nr, factor);
|
|
|
|
|
stripe_nr = div_u64_rem(stripe_nr, factor, &stripe_index);
|
|
|
|
|
stripe_index *= map->sub_stripes;
|
|
|
|
|
|
|
|
|
|
if (rw & (REQ_WRITE | REQ_GET_READ_MIRRORS))
|
|
|
|
@@ -5208,32 +5210,32 @@ static int __btrfs_map_block(struct btrfs_fs_info *fs_info, int rw,
|
|
|
|
|
stripe_index = 0;
|
|
|
|
|
stripe_offset = 0;
|
|
|
|
|
} else {
|
|
|
|
|
u64 tmp;
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* Mirror #0 or #1 means the original data block.
|
|
|
|
|
* Mirror #2 is RAID5 parity block.
|
|
|
|
|
* Mirror #3 is RAID6 Q block.
|
|
|
|
|
*/
|
|
|
|
|
stripe_index = do_div(stripe_nr, nr_data_stripes(map));
|
|
|
|
|
stripe_nr = div_u64_rem(stripe_nr,
|
|
|
|
|
nr_data_stripes(map), &stripe_index);
|
|
|
|
|
if (mirror_num > 1)
|
|
|
|
|
stripe_index = nr_data_stripes(map) +
|
|
|
|
|
mirror_num - 2;
|
|
|
|
|
|
|
|
|
|
/* We distribute the parity blocks across stripes */
|
|
|
|
|
tmp = stripe_nr + stripe_index;
|
|
|
|
|
stripe_index = do_div(tmp, map->num_stripes);
|
|
|
|
|
div_u64_rem(stripe_nr + stripe_index, map->num_stripes,
|
|
|
|
|
&stripe_index);
|
|
|
|
|
if (!(rw & (REQ_WRITE | REQ_DISCARD |
|
|
|
|
|
REQ_GET_READ_MIRRORS)) && mirror_num <= 1)
|
|
|
|
|
mirror_num = 1;
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
/*
|
|
|
|
|
* after this do_div call, stripe_nr is the number of stripes
|
|
|
|
|
* on this device we have to walk to find the data, and
|
|
|
|
|
* stripe_index is the number of our device in the stripe array
|
|
|
|
|
* after this, stripe_nr is the number of stripes on this
|
|
|
|
|
* device we have to walk to find the data, and stripe_index is
|
|
|
|
|
* the number of our device in the stripe array
|
|
|
|
|
*/
|
|
|
|
|
stripe_index = do_div(stripe_nr, map->num_stripes);
|
|
|
|
|
stripe_nr = div_u64_rem(stripe_nr, map->num_stripes,
|
|
|
|
|
&stripe_index);
|
|
|
|
|
mirror_num = stripe_index + 1;
|
|
|
|
|
}
|
|
|
|
|
BUG_ON(stripe_index >= map->num_stripes);
|
|
|
|
@@ -5268,8 +5270,7 @@ static int __btrfs_map_block(struct btrfs_fs_info *fs_info, int rw,
|
|
|
|
|
sizeof(int) * tgtdev_indexes);
|
|
|
|
|
|
|
|
|
|
/* Work out the disk rotation on this stripe-set */
|
|
|
|
|
tmp = stripe_nr;
|
|
|
|
|
rot = do_div(tmp, num_stripes);
|
|
|
|
|
div_u64_rem(stripe_nr, num_stripes, &rot);
|
|
|
|
|
|
|
|
|
|
/* Fill in the logical address of each stripe */
|
|
|
|
|
tmp = stripe_nr * nr_data_stripes(map);
|
|
|
|
|