diff options
Diffstat (limited to 'drivers/md')
-rw-r--r-- | drivers/md/dm-raid1.c | 4 | ||||
-rw-r--r-- | drivers/md/md.c | 13 | ||||
-rw-r--r-- | drivers/md/raid1.c | 7 |
3 files changed, 20 insertions, 4 deletions
diff --git a/drivers/md/dm-raid1.c b/drivers/md/dm-raid1.c index be48cedf986b..c54de989eb00 100644 --- a/drivers/md/dm-raid1.c +++ b/drivers/md/dm-raid1.c | |||
@@ -255,7 +255,9 @@ static struct region *__rh_alloc(struct region_hash *rh, region_t region) | |||
255 | struct region *reg, *nreg; | 255 | struct region *reg, *nreg; |
256 | 256 | ||
257 | read_unlock(&rh->hash_lock); | 257 | read_unlock(&rh->hash_lock); |
258 | nreg = mempool_alloc(rh->region_pool, GFP_NOIO); | 258 | nreg = mempool_alloc(rh->region_pool, GFP_ATOMIC); |
259 | if (unlikely(!nreg)) | ||
260 | nreg = kmalloc(sizeof(struct region), GFP_NOIO); | ||
259 | nreg->state = rh->log->type->in_sync(rh->log, region, 1) ? | 261 | nreg->state = rh->log->type->in_sync(rh->log, region, 1) ? |
260 | RH_CLEAN : RH_NOSYNC; | 262 | RH_CLEAN : RH_NOSYNC; |
261 | nreg->rh = rh; | 263 | nreg->rh = rh; |
diff --git a/drivers/md/md.c b/drivers/md/md.c index b6d16022a53e..8dbab2ef3885 100644 --- a/drivers/md/md.c +++ b/drivers/md/md.c | |||
@@ -1597,6 +1597,19 @@ void md_update_sb(mddev_t * mddev) | |||
1597 | 1597 | ||
1598 | repeat: | 1598 | repeat: |
1599 | spin_lock_irq(&mddev->write_lock); | 1599 | spin_lock_irq(&mddev->write_lock); |
1600 | |||
1601 | if (mddev->degraded && mddev->sb_dirty == 3) | ||
1602 | /* If the array is degraded, then skipping spares is both | ||
1603 | * dangerous and fairly pointless. | ||
1604 | * Dangerous because a device that was removed from the array | ||
1605 | * might have a event_count that still looks up-to-date, | ||
1606 | * so it can be re-added without a resync. | ||
1607 | * Pointless because if there are any spares to skip, | ||
1608 | * then a recovery will happen and soon that array won't | ||
1609 | * be degraded any more and the spare can go back to sleep then. | ||
1610 | */ | ||
1611 | mddev->sb_dirty = 1; | ||
1612 | |||
1600 | sync_req = mddev->in_sync; | 1613 | sync_req = mddev->in_sync; |
1601 | mddev->utime = get_seconds(); | 1614 | mddev->utime = get_seconds(); |
1602 | if (mddev->sb_dirty == 3) | 1615 | if (mddev->sb_dirty == 3) |
diff --git a/drivers/md/raid1.c b/drivers/md/raid1.c index 1efe22a2d041..87bfe9e7d8ca 100644 --- a/drivers/md/raid1.c +++ b/drivers/md/raid1.c | |||
@@ -1625,15 +1625,16 @@ static sector_t sync_request(mddev_t *mddev, sector_t sector_nr, int *skipped, i | |||
1625 | return 0; | 1625 | return 0; |
1626 | } | 1626 | } |
1627 | 1627 | ||
1628 | /* before building a request, check if we can skip these blocks.. | ||
1629 | * This call the bitmap_start_sync doesn't actually record anything | ||
1630 | */ | ||
1631 | if (mddev->bitmap == NULL && | 1628 | if (mddev->bitmap == NULL && |
1632 | mddev->recovery_cp == MaxSector && | 1629 | mddev->recovery_cp == MaxSector && |
1630 | !test_bit(MD_RECOVERY_REQUESTED, &mddev->recovery) && | ||
1633 | conf->fullsync == 0) { | 1631 | conf->fullsync == 0) { |
1634 | *skipped = 1; | 1632 | *skipped = 1; |
1635 | return max_sector - sector_nr; | 1633 | return max_sector - sector_nr; |
1636 | } | 1634 | } |
1635 | /* before building a request, check if we can skip these blocks.. | ||
1636 | * This call the bitmap_start_sync doesn't actually record anything | ||
1637 | */ | ||
1637 | if (!bitmap_start_sync(mddev->bitmap, sector_nr, &sync_blocks, 1) && | 1638 | if (!bitmap_start_sync(mddev->bitmap, sector_nr, &sync_blocks, 1) && |
1638 | !conf->fullsync && !test_bit(MD_RECOVERY_REQUESTED, &mddev->recovery)) { | 1639 | !conf->fullsync && !test_bit(MD_RECOVERY_REQUESTED, &mddev->recovery)) { |
1639 | /* We can skip this block, and probably several more */ | 1640 | /* We can skip this block, and probably several more */ |