aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/md/raid5.c
diff options
context:
space:
mode:
authorNeilBrown <neilb@suse.de>2011-07-26 21:00:36 -0400
committerNeilBrown <neilb@suse.de>2011-07-26 21:00:36 -0400
commit8cfa7b0f67b4d899efc7f39eb7e172fd79237811 (patch)
treedf1002e5eccbf4b241dc9e948bb894de2106d6e2 /drivers/md/raid5.c
parentcbea21703b2484f83faef040ed1de30114794392 (diff)
md/raid5: Avoid BUG caused by multiple failures.
While preparing to write a stripe we keep the parity block or blocks locked (R5_LOCKED) - towards the end of schedule_reconstruction. If the array is discovered to have failed before this write completes we can leave those blocks LOCKED, and init_stripe will notice that a free stripe still has a locked block and will complain. So clear the R5_LOCKED flag in handle_failed_stripe, and demote the 'BUG' to a 'WARN_ON'. Signed-off-by: NeilBrown <neilb@suse.de>
Diffstat (limited to 'drivers/md/raid5.c')
-rw-r--r--drivers/md/raid5.c6
1 files changed, 5 insertions, 1 deletions
diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c
index a81eca6434dd..b874f42694e2 100644
--- a/drivers/md/raid5.c
+++ b/drivers/md/raid5.c
@@ -340,7 +340,7 @@ static void init_stripe(struct stripe_head *sh, sector_t sector, int previous)
340 (unsigned long long)sh->sector, i, dev->toread, 340 (unsigned long long)sh->sector, i, dev->toread,
341 dev->read, dev->towrite, dev->written, 341 dev->read, dev->towrite, dev->written,
342 test_bit(R5_LOCKED, &dev->flags)); 342 test_bit(R5_LOCKED, &dev->flags));
343 BUG(); 343 WARN_ON(1);
344 } 344 }
345 dev->flags = 0; 345 dev->flags = 0;
346 raid5_build_block(sh, i, previous); 346 raid5_build_block(sh, i, previous);
@@ -2301,6 +2301,10 @@ handle_failed_stripe(raid5_conf_t *conf, struct stripe_head *sh,
2301 if (bitmap_end) 2301 if (bitmap_end)
2302 bitmap_endwrite(conf->mddev->bitmap, sh->sector, 2302 bitmap_endwrite(conf->mddev->bitmap, sh->sector,
2303 STRIPE_SECTORS, 0, 0); 2303 STRIPE_SECTORS, 0, 0);
2304 /* If we were in the middle of a write the parity block might
2305 * still be locked - so just clear all R5_LOCKED flags
2306 */
2307 clear_bit(R5_LOCKED, &sh->dev[i].flags);
2304 } 2308 }
2305 2309
2306 if (test_and_clear_bit(STRIPE_FULL_WRITE, &sh->state)) 2310 if (test_and_clear_bit(STRIPE_FULL_WRITE, &sh->state))