Commit 45a4d8fd authored by ChangSyun Peng's avatar ChangSyun Peng Committed by Song Liu

md/raid5: Allow degraded raid6 to do rmw

Degraded raid6 always do reconstruct-write now. With raid6 xor supported,
we can do rmw in degraded raid6. This patch can reduce many read IOs to
improve performance.

If the failed disk is P, Q or the disk we want to write to, we may need to
do reconstruct-write in max degraded raid6. In this situation we can not
read enough data from handle_stripe_dirtying() so we have to set force_rcw
in handle_stripe_fill() to read all data.
Reviewed-by: default avatarAlex Wu <alexwu@synology.com>
Reviewed-by: default avatarBingJing Chang <bingjingc@synology.com>
Reviewed-by: default avatarDanny Shih <dannyshih@synology.com>
Signed-off-by: default avatarChangSyun Peng <allenpeng@synology.com>
Signed-off-by: default avatarSong Liu <songliubraving@fb.com>
parent a1c6ae3d
...@@ -3557,6 +3557,7 @@ static int need_this_block(struct stripe_head *sh, struct stripe_head_state *s, ...@@ -3557,6 +3557,7 @@ static int need_this_block(struct stripe_head *sh, struct stripe_head_state *s,
struct r5dev *fdev[2] = { &sh->dev[s->failed_num[0]], struct r5dev *fdev[2] = { &sh->dev[s->failed_num[0]],
&sh->dev[s->failed_num[1]] }; &sh->dev[s->failed_num[1]] };
int i; int i;
bool force_rcw = (sh->raid_conf->rmw_level == PARITY_DISABLE_RMW);
if (test_bit(R5_LOCKED, &dev->flags) || if (test_bit(R5_LOCKED, &dev->flags) ||
...@@ -3615,18 +3616,27 @@ static int need_this_block(struct stripe_head *sh, struct stripe_head_state *s, ...@@ -3615,18 +3616,27 @@ static int need_this_block(struct stripe_head *sh, struct stripe_head_state *s,
* devices must be read. * devices must be read.
*/ */
return 1; return 1;
if (s->failed >= 2 &&
(fdev[i]->towrite ||
s->failed_num[i] == sh->pd_idx ||
s->failed_num[i] == sh->qd_idx) &&
!test_bit(R5_UPTODATE, &fdev[i]->flags))
/* In max degraded raid6, If the failed disk is P, Q,
* or we want to read the failed disk, we need to do
* reconstruct-write.
*/
force_rcw = true;
} }
/* If we are forced to do a reconstruct-write, either because /* If we are forced to do a reconstruct-write, because parity
* the current RAID6 implementation only supports that, or * cannot be trusted and we are currently recovering it, there
* because parity cannot be trusted and we are currently * is extra need to be careful.
* recovering it, there is extra need to be careful.
* If one of the devices that we would need to read, because * If one of the devices that we would need to read, because
* it is not being overwritten (and maybe not written at all) * it is not being overwritten (and maybe not written at all)
* is missing/faulty, then we need to read everything we can. * is missing/faulty, then we need to read everything we can.
*/ */
if (sh->raid_conf->level != 6 && if (!force_rcw &&
sh->raid_conf->rmw_level != PARITY_DISABLE_RMW &&
sh->sector < sh->raid_conf->mddev->recovery_cp) sh->sector < sh->raid_conf->mddev->recovery_cp)
/* reconstruct-write isn't being forced */ /* reconstruct-write isn't being forced */
return 0; return 0;
......
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