Commit b875e531 authored by NeilBrown's avatar NeilBrown Committed by Linus Torvalds

[PATCH] md: fix innocuous bug in raid6 stripe_to_pdidx

stripe_to_pdidx finds the index of the parity disk for a given stripe.  It
assumes raid5 in that it uses "disks-1" to determine the number of data disks.

This is incorrect for raid6 but fortunately the two usages cancel each other
out.  The only way that 'data_disks' affects the calculation of pd_idx in
raid5_compute_sector is when it is divided into the sector number.  But as
that sector number is calculated by multiplying in the wrong value of
'data_disks' the division produces the right value.

So it is innocuous but needs to be fixed.

Also change the calculation of raid_disks in compute_blocknr to make it
more obviously correct (it seems at first to always use disks-1 too).
Signed-off-by: default avatarNeil Brown <neilb@suse.de>
Signed-off-by: default avatarAndrew Morton <akpm@osdl.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@osdl.org>
parent 52488615
...@@ -823,7 +823,8 @@ static sector_t raid5_compute_sector(sector_t r_sector, unsigned int raid_disks, ...@@ -823,7 +823,8 @@ static sector_t raid5_compute_sector(sector_t r_sector, unsigned int raid_disks,
static sector_t compute_blocknr(struct stripe_head *sh, int i) static sector_t compute_blocknr(struct stripe_head *sh, int i)
{ {
raid5_conf_t *conf = sh->raid_conf; raid5_conf_t *conf = sh->raid_conf;
int raid_disks = sh->disks, data_disks = raid_disks - 1; int raid_disks = sh->disks;
int data_disks = raid_disks - conf->max_degraded;
sector_t new_sector = sh->sector, check; sector_t new_sector = sh->sector, check;
int sectors_per_chunk = conf->chunk_size >> 9; int sectors_per_chunk = conf->chunk_size >> 9;
sector_t stripe; sector_t stripe;
...@@ -859,7 +860,6 @@ static sector_t compute_blocknr(struct stripe_head *sh, int i) ...@@ -859,7 +860,6 @@ static sector_t compute_blocknr(struct stripe_head *sh, int i)
} }
break; break;
case 6: case 6:
data_disks = raid_disks - 2;
if (i == raid6_next_disk(sh->pd_idx, raid_disks)) if (i == raid6_next_disk(sh->pd_idx, raid_disks))
return 0; /* It is the Q disk */ return 0; /* It is the Q disk */
switch (conf->algorithm) { switch (conf->algorithm) {
...@@ -1355,8 +1355,10 @@ static int stripe_to_pdidx(sector_t stripe, raid5_conf_t *conf, int disks) ...@@ -1355,8 +1355,10 @@ static int stripe_to_pdidx(sector_t stripe, raid5_conf_t *conf, int disks)
int pd_idx, dd_idx; int pd_idx, dd_idx;
int chunk_offset = sector_div(stripe, sectors_per_chunk); int chunk_offset = sector_div(stripe, sectors_per_chunk);
raid5_compute_sector(stripe*(disks-1)*sectors_per_chunk raid5_compute_sector(stripe * (disks - conf->max_degraded)
+ chunk_offset, disks, disks-1, &dd_idx, &pd_idx, conf); *sectors_per_chunk + chunk_offset,
disks, disks - conf->max_degraded,
&dd_idx, &pd_idx, conf);
return pd_idx; return pd_idx;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment