diff options
Diffstat (limited to 'drivers/md/raid6main.c')
-rw-r--r-- | drivers/md/raid6main.c | 27 |
1 files changed, 23 insertions, 4 deletions
diff --git a/drivers/md/raid6main.c b/drivers/md/raid6main.c index eae5a35629c5..0000d162d198 100644 --- a/drivers/md/raid6main.c +++ b/drivers/md/raid6main.c | |||
@@ -1702,6 +1702,8 @@ static sector_t sync_request(mddev_t *mddev, sector_t sector_nr, int *skipped, i | |||
1702 | int data_disks = raid_disks - 2; | 1702 | int data_disks = raid_disks - 2; |
1703 | sector_t max_sector = mddev->size << 1; | 1703 | sector_t max_sector = mddev->size << 1; |
1704 | int sync_blocks; | 1704 | int sync_blocks; |
1705 | int still_degraded = 0; | ||
1706 | int i; | ||
1705 | 1707 | ||
1706 | if (sector_nr >= max_sector) { | 1708 | if (sector_nr >= max_sector) { |
1707 | /* just being told to finish up .. nothing much to do */ | 1709 | /* just being told to finish up .. nothing much to do */ |
@@ -1710,7 +1712,7 @@ static sector_t sync_request(mddev_t *mddev, sector_t sector_nr, int *skipped, i | |||
1710 | if (mddev->curr_resync < max_sector) /* aborted */ | 1712 | if (mddev->curr_resync < max_sector) /* aborted */ |
1711 | bitmap_end_sync(mddev->bitmap, mddev->curr_resync, | 1713 | bitmap_end_sync(mddev->bitmap, mddev->curr_resync, |
1712 | &sync_blocks, 1); | 1714 | &sync_blocks, 1); |
1713 | else /* compelted sync */ | 1715 | else /* completed sync */ |
1714 | conf->fullsync = 0; | 1716 | conf->fullsync = 0; |
1715 | bitmap_close_sync(mddev->bitmap); | 1717 | bitmap_close_sync(mddev->bitmap); |
1716 | 1718 | ||
@@ -1748,7 +1750,16 @@ static sector_t sync_request(mddev_t *mddev, sector_t sector_nr, int *skipped, i | |||
1748 | */ | 1750 | */ |
1749 | schedule_timeout_uninterruptible(1); | 1751 | schedule_timeout_uninterruptible(1); |
1750 | } | 1752 | } |
1751 | bitmap_start_sync(mddev->bitmap, sector_nr, &sync_blocks, 0); | 1753 | /* Need to check if array will still be degraded after recovery/resync |
1754 | * We don't need to check the 'failed' flag as when that gets set, | ||
1755 | * recovery aborts. | ||
1756 | */ | ||
1757 | for (i=0; i<mddev->raid_disks; i++) | ||
1758 | if (conf->disks[i].rdev == NULL) | ||
1759 | still_degraded = 1; | ||
1760 | |||
1761 | bitmap_start_sync(mddev->bitmap, sector_nr, &sync_blocks, still_degraded); | ||
1762 | |||
1752 | spin_lock(&sh->lock); | 1763 | spin_lock(&sh->lock); |
1753 | set_bit(STRIPE_SYNCING, &sh->state); | 1764 | set_bit(STRIPE_SYNCING, &sh->state); |
1754 | clear_bit(STRIPE_INSYNC, &sh->state); | 1765 | clear_bit(STRIPE_INSYNC, &sh->state); |
@@ -1784,7 +1795,9 @@ static void raid6d (mddev_t *mddev) | |||
1784 | 1795 | ||
1785 | if (conf->seq_flush - conf->seq_write > 0) { | 1796 | if (conf->seq_flush - conf->seq_write > 0) { |
1786 | int seq = conf->seq_flush; | 1797 | int seq = conf->seq_flush; |
1798 | spin_unlock_irq(&conf->device_lock); | ||
1787 | bitmap_unplug(mddev->bitmap); | 1799 | bitmap_unplug(mddev->bitmap); |
1800 | spin_lock_irq(&conf->device_lock); | ||
1788 | conf->seq_write = seq; | 1801 | conf->seq_write = seq; |
1789 | activate_bit_delay(conf); | 1802 | activate_bit_delay(conf); |
1790 | } | 1803 | } |
@@ -2145,9 +2158,15 @@ static int raid6_add_disk(mddev_t *mddev, mdk_rdev_t *rdev) | |||
2145 | /* no point adding a device */ | 2158 | /* no point adding a device */ |
2146 | return 0; | 2159 | return 0; |
2147 | /* | 2160 | /* |
2148 | * find the disk ... | 2161 | * find the disk ... but prefer rdev->saved_raid_disk |
2162 | * if possible. | ||
2149 | */ | 2163 | */ |
2150 | for (disk=0; disk < mddev->raid_disks; disk++) | 2164 | if (rdev->saved_raid_disk >= 0 && |
2165 | conf->disks[rdev->saved_raid_disk].rdev == NULL) | ||
2166 | disk = rdev->saved_raid_disk; | ||
2167 | else | ||
2168 | disk = 0; | ||
2169 | for ( ; disk < mddev->raid_disks; disk++) | ||
2151 | if ((p=conf->disks + disk)->rdev == NULL) { | 2170 | if ((p=conf->disks + disk)->rdev == NULL) { |
2152 | clear_bit(In_sync, &rdev->flags); | 2171 | clear_bit(In_sync, &rdev->flags); |
2153 | rdev->raid_disk = disk; | 2172 | rdev->raid_disk = disk; |