aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorZhao Lei <zhaolei@cn.fujitsu.com>2015-01-20 02:11:31 -0500
committerChris Mason <clm@fb.com>2015-01-21 21:06:47 -0500
commite34c330d639177bbb345bf2bde16613b00cc6e6b (patch)
treed08a3f23ae3609cba9fca83b22943c7a04032349 /fs
parentdf8d116ffa379f3ef09d7ff28da0f0c921cc9fa1 (diff)
Btrfs: fix a out-of-bound access of raid_map
We add the number of stripes on target devices into bbio->num_stripes if we are under device replacement, and we just sort the raid_map of those stripes that not on the target devices, so if when we need real raid_map, we need skip the stripes on the target devices. Signed-off-by: Zhao Lei <zhaolei@cn.fujitsu.com> Signed-off-by: Miao Xie <miaox@cn.fujitsu.com> Signed-off-by: Chris Mason <clm@fb.com>
Diffstat (limited to 'fs')
-rw-r--r--fs/btrfs/scrub.c7
1 files changed, 5 insertions, 2 deletions
diff --git a/fs/btrfs/scrub.c b/fs/btrfs/scrub.c
index 53575a45f7d1..673e32be88fa 100644
--- a/fs/btrfs/scrub.c
+++ b/fs/btrfs/scrub.c
@@ -1299,7 +1299,9 @@ out:
1299static inline int scrub_nr_raid_mirrors(struct btrfs_bio *bbio, u64 *raid_map) 1299static inline int scrub_nr_raid_mirrors(struct btrfs_bio *bbio, u64 *raid_map)
1300{ 1300{
1301 if (raid_map) { 1301 if (raid_map) {
1302 if (raid_map[bbio->num_stripes - 1] == RAID6_Q_STRIPE) 1302 int real_stripes = bbio->num_stripes - bbio->num_tgtdevs;
1303
1304 if (raid_map[real_stripes - 1] == RAID6_Q_STRIPE)
1303 return 3; 1305 return 3;
1304 else 1306 else
1305 return 2; 1307 return 2;
@@ -1420,7 +1422,8 @@ leave_nomem:
1420 1422
1421 scrub_stripe_index_and_offset(logical, raid_map, 1423 scrub_stripe_index_and_offset(logical, raid_map,
1422 mapped_length, 1424 mapped_length,
1423 bbio->num_stripes, 1425 bbio->num_stripes -
1426 bbio->num_tgtdevs,
1424 mirror_index, 1427 mirror_index,
1425 &stripe_index, 1428 &stripe_index,
1426 &stripe_offset); 1429 &stripe_offset);