md: fix data corruption when a degraded raid5 array is reshaped
authorDan Williams <dan.j.williams@intel.com>
Tue, 8 Jan 2008 23:32:53 +0000 (15:32 -0800)
committerLinus Torvalds <torvalds@woody.linux-foundation.org>
Wed, 9 Jan 2008 00:10:35 +0000 (16:10 -0800)
We currently do not wait for the block from the missing device to be
computed from parity before copying data to the new stripe layout.

The change in the raid6 code is not techincally needed as we don't delay
data block recovery in the same way for raid6 yet.  But making the change
now is safer long-term.

This bug exists in 2.6.23 and 2.6.24-rc

Cc: <stable@kernel.org>
Signed-off-by: Dan Williams <dan.j.williams@intel.com>
Acked-by: Neil Brown <neilb@suse.de>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
drivers/md/raid5.c

index a5aad8cad84332a138e741d56ed49bbcf58e1c6c..e8c8157b02fcb5e99a09786b977e30226e56ed95 100644 (file)
@@ -2865,7 +2865,8 @@ static void handle_stripe5(struct stripe_head *sh)
                md_done_sync(conf->mddev, STRIPE_SECTORS, 1);
        }
 
-       if (s.expanding && s.locked == 0)
+       if (s.expanding && s.locked == 0 &&
+           !test_bit(STRIPE_OP_COMPUTE_BLK, &sh->ops.pending))
                handle_stripe_expansion(conf, sh, NULL);
 
        if (sh->ops.count)
@@ -3067,7 +3068,8 @@ static void handle_stripe6(struct stripe_head *sh, struct page *tmp_page)
                md_done_sync(conf->mddev, STRIPE_SECTORS, 1);
        }
 
-       if (s.expanding && s.locked == 0)
+       if (s.expanding && s.locked == 0 &&
+           !test_bit(STRIPE_OP_COMPUTE_BLK, &sh->ops.pending))
                handle_stripe_expansion(conf, sh, &r6s);
 
        spin_unlock(&sh->lock);