aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/md/raid5.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/md/raid5.c')
-rw-r--r--drivers/md/raid5.c15
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);