aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorNeilBrown <neilb@suse.de>2011-12-22 17:57:48 -0500
committerNeilBrown <neilb@suse.de>2011-12-22 17:57:48 -0500
commit961902c0f8240175729274cd14198872f42072b7 (patch)
tree808b47d32174e970465dc00cea9150ff978bfc95 /drivers
parent60fc13702a1b35118c1548e9c257fa038cecb658 (diff)
md/bitmap: It is OK to clear bits during recovery.
commit d0a4bb492772ce5c4bdfba3744a99ed6f6fb238f introduced a regression which is annoying but fairly harmless. When writing to an array that is undergoing recovery (a spare in being integrated into the array), writing to the array will set bits in the bitmap, but they will not be cleared when the write completes. For bits covering areas that have not been recovered yet this is not a problem as the recovery will clear the bits. However bits set in already-recovered region will stay set and never be cleared. This doesn't risk data integrity. The only negatives are: - next time there is a crash, more resyncing than necessary will be done. - the bitmap doesn't look clean, which is confusing. While an array is recovering we don't want to update the 'events_cleared' setting in the bitmap but we do still want to clear bits that have very recently been set - providing they were written to the recovering device. So split those two needs - which previously both depended on 'success' and always clear the bit of the write went to all devices. Signed-off-by: NeilBrown <neilb@suse.de>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/md/bitmap.c5
1 files changed, 1 insertions, 4 deletions
diff --git a/drivers/md/bitmap.c b/drivers/md/bitmap.c
index b6907118283a..6d03774b176e 100644
--- a/drivers/md/bitmap.c
+++ b/drivers/md/bitmap.c
@@ -1393,9 +1393,6 @@ void bitmap_endwrite(struct bitmap *bitmap, sector_t offset, unsigned long secto
1393 atomic_read(&bitmap->behind_writes), 1393 atomic_read(&bitmap->behind_writes),
1394 bitmap->mddev->bitmap_info.max_write_behind); 1394 bitmap->mddev->bitmap_info.max_write_behind);
1395 } 1395 }
1396 if (bitmap->mddev->degraded)
1397 /* Never clear bits or update events_cleared when degraded */
1398 success = 0;
1399 1396
1400 while (sectors) { 1397 while (sectors) {
1401 sector_t blocks; 1398 sector_t blocks;
@@ -1409,7 +1406,7 @@ void bitmap_endwrite(struct bitmap *bitmap, sector_t offset, unsigned long secto
1409 return; 1406 return;
1410 } 1407 }
1411 1408
1412 if (success && 1409 if (success && !bitmap->mddev->degraded &&
1413 bitmap->events_cleared < bitmap->mddev->events) { 1410 bitmap->events_cleared < bitmap->mddev->events) {
1414 bitmap->events_cleared = bitmap->mddev->events; 1411 bitmap->events_cleared = bitmap->mddev->events;
1415 bitmap->need_sync = 1; 1412 bitmap->need_sync = 1;