diff options
Diffstat (limited to 'drivers/md/raid5.c')
-rw-r--r-- | drivers/md/raid5.c | 15 |
1 files changed, 14 insertions, 1 deletions
diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c index bb16ac231a40..8eded08411f3 100644 --- a/drivers/md/raid5.c +++ b/drivers/md/raid5.c | |||
@@ -1768,6 +1768,14 @@ static int make_request(request_queue_t *q, struct bio * bi) | |||
1768 | if (likely(conf->expand_progress == MaxSector)) | 1768 | if (likely(conf->expand_progress == MaxSector)) |
1769 | disks = conf->raid_disks; | 1769 | disks = conf->raid_disks; |
1770 | else { | 1770 | else { |
1771 | /* spinlock is needed as expand_progress may be | ||
1772 | * 64bit on a 32bit platform, and so it might be | ||
1773 | * possible to see a half-updated value | ||
1774 | * Ofcourse expand_progress could change after | ||
1775 | * the lock is dropped, so once we get a reference | ||
1776 | * to the stripe that we think it is, we will have | ||
1777 | * to check again. | ||
1778 | */ | ||
1771 | spin_lock_irq(&conf->device_lock); | 1779 | spin_lock_irq(&conf->device_lock); |
1772 | disks = conf->raid_disks; | 1780 | disks = conf->raid_disks; |
1773 | if (logical_sector >= conf->expand_progress) | 1781 | if (logical_sector >= conf->expand_progress) |
@@ -1791,7 +1799,12 @@ static int make_request(request_queue_t *q, struct bio * bi) | |||
1791 | if (sh) { | 1799 | if (sh) { |
1792 | if (unlikely(conf->expand_progress != MaxSector)) { | 1800 | if (unlikely(conf->expand_progress != MaxSector)) { |
1793 | /* expansion might have moved on while waiting for a | 1801 | /* expansion might have moved on while waiting for a |
1794 | * stripe, so we much do the range check again. | 1802 | * stripe, so we must do the range check again. |
1803 | * Expansion could still move past after this | ||
1804 | * test, but as we are holding a reference to | ||
1805 | * 'sh', we know that if that happens, | ||
1806 | * STRIPE_EXPANDING will get set and the expansion | ||
1807 | * won't proceed until we finish with the stripe. | ||
1795 | */ | 1808 | */ |
1796 | int must_retry = 0; | 1809 | int must_retry = 0; |
1797 | spin_lock_irq(&conf->device_lock); | 1810 | spin_lock_irq(&conf->device_lock); |