Skip to content

Commit a785448

Browse files
alex-bolshoyneilbrown
authored andcommitted
md: When RAID5 is dirty, force reconstruct-write instead of read-modify-write.
Signed-off-by: Alex Lyakas <[email protected]> Suggested-by: Yair Hershko <[email protected]> Signed-off-by: NeilBrown <[email protected]>
1 parent b97390a commit a785448

File tree

1 file changed

+16
-3
lines changed

1 file changed

+16
-3
lines changed

drivers/md/raid5.c

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2806,12 +2806,25 @@ static void handle_stripe_dirtying(struct r5conf *conf,
28062806
int disks)
28072807
{
28082808
int rmw = 0, rcw = 0, i;
2809-
if (conf->max_degraded == 2) {
2810-
/* RAID6 requires 'rcw' in current implementation
2811-
* Calculate the real rcw later - for now fake it
2809+
sector_t recovery_cp = conf->mddev->recovery_cp;
2810+
2811+
/* RAID6 requires 'rcw' in current implementation.
2812+
* Otherwise, check whether resync is now happening or should start.
2813+
* If yes, then the array is dirty (after unclean shutdown or
2814+
* initial creation), so parity in some stripes might be inconsistent.
2815+
* In this case, we need to always do reconstruct-write, to ensure
2816+
* that in case of drive failure or read-error correction, we
2817+
* generate correct data from the parity.
2818+
*/
2819+
if (conf->max_degraded == 2 ||
2820+
(recovery_cp < MaxSector && sh->sector >= recovery_cp)) {
2821+
/* Calculate the real rcw later - for now make it
28122822
* look like rcw is cheaper
28132823
*/
28142824
rcw = 1; rmw = 2;
2825+
pr_debug("force RCW max_degraded=%u, recovery_cp=%llu sh->sector=%llu\n",
2826+
conf->max_degraded, (unsigned long long)recovery_cp,
2827+
(unsigned long long)sh->sector);
28152828
} else for (i = disks; i--; ) {
28162829
/* would I have to read this buffer for read_modify_write */
28172830
struct r5dev *dev = &sh->dev[i];

0 commit comments

Comments
 (0)