aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNeilBrown <neilb@suse.de>2014-09-04 02:30:38 -0400
committerNeilBrown <neilb@suse.de>2014-09-21 21:26:01 -0400
commit669cc7ba77864e7b1ac39c9f2b2afb8730f341f4 (patch)
treec4e1f885673cd7ee7e08a0eba38a68e7badf6cca
parentc6d119cf1b5a778e9ed60a006e2a434fcc4471a2 (diff)
md/raid1: clean up request counts properly in close_sync()
If there are outstanding writes when close_sync is called, the change to ->start_next_window might cause them to decrement the wrong counter when they complete. Fix this by merging the two counters into the one that will be decremented. Having an incorrect value in a counter can cause raise_barrier() to hangs, so this is suitable for -stable. Fixes: 79ef3a8aa1cb1523cc231c9a90a278333c21f761 cc: stable@vger.kernel.org (v3.13+) Signed-off-by: NeilBrown <neilb@suse.de>
-rw-r--r--drivers/md/raid1.c5
1 files changed, 5 insertions, 0 deletions
diff --git a/drivers/md/raid1.c b/drivers/md/raid1.c
index ad0468c42d23..a31c92bbcfc9 100644
--- a/drivers/md/raid1.c
+++ b/drivers/md/raid1.c
@@ -1545,8 +1545,13 @@ static void close_sync(struct r1conf *conf)
1545 mempool_destroy(conf->r1buf_pool); 1545 mempool_destroy(conf->r1buf_pool);
1546 conf->r1buf_pool = NULL; 1546 conf->r1buf_pool = NULL;
1547 1547
1548 spin_lock_irq(&conf->resync_lock);
1548 conf->next_resync = 0; 1549 conf->next_resync = 0;
1549 conf->start_next_window = MaxSector; 1550 conf->start_next_window = MaxSector;
1551 conf->current_window_requests +=
1552 conf->next_window_requests;
1553 conf->next_window_requests = 0;
1554 spin_unlock_irq(&conf->resync_lock);
1550} 1555}
1551 1556
1552static int raid1_spare_active(struct mddev *mddev) 1557static int raid1_spare_active(struct mddev *mddev)