Git-commit: 30d7a4836847bdb10b32c78a4879d4aebe0f193b
From: NeilBrown <neilb@suse.de>
Date: Fri, 23 Dec 2011 09:57:00 +1100
Subject: [PATCH] md/raid5: ensure correct assessment of drives during
 degraded reshape.
Patch-mainline: 3.3
References: bcn#741289

[This patch is very different from the mainline one as the
code has changed a lot. - NB ]

While reshaping a degraded array (as when reshaping a RAID0 by first
converting it to a degraded RAID4) we currently get confused about
which devices are in_sync.  In most cases we get it right, but in the
region that is being reshaped we need to treat non-failed devices as
in-sync when we have the data but haven't actually written it out yet.

Reported-by: Adam Kwolek <adam.kwolek@intel.com>
Signed-off-by: NeilBrown <neilb@suse.de>
---
 drivers/md/raid5.c |   16 ++++++++++++++++
 1 file changed, 16 insertions(+)

--- a/drivers/md/raid5.c
+++ b/drivers/md/raid5.c
@@ -3082,6 +3082,14 @@ static void handle_stripe5(struct stripe
 			/* could be in-sync depending on recovery/reshape status */
 			if (sh->sector + STRIPE_SECTORS <= rdev->recovery_offset)
 				set_bit(R5_Insync, &dev->flags);
+			else if (test_bit(R5_UPTODATE, &dev->flags) &&
+				 test_bit(R5_Expanded, &dev->flags))
+				/* If we've reshaped into here, we assume it is
+				 * Insync.
+				 * We will shortly update recovery_offset to make
+				 * it official.
+				 */
+				set_bit(R5_Insync, &dev->flags);
 		}
 		if (!test_bit(R5_Insync, &dev->flags)) {
 			/* The ReadError flag will just be confusing now */
@@ -3377,6 +3385,14 @@ static void handle_stripe6(struct stripe
 			/* in sync if before recovery_offset */
 			if (sh->sector + STRIPE_SECTORS <= rdev->recovery_offset)
 				set_bit(R5_Insync, &dev->flags);
+			else if (test_bit(R5_UPTODATE, &dev->flags) &&
+				 test_bit(R5_Expanded, &dev->flags))
+				/* If we've reshaped into here, we assume it is
+				 * Insync.
+				 * We will shortly update recovery_offset to make
+				 * it official.
+				 */
+				set_bit(R5_Insync, &dev->flags);
 		}
 		if (!test_bit(R5_Insync, &dev->flags)) {
 			/* The ReadError flag will just be confusing now */
