aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/md/raid1.c
diff options
context:
space:
mode:
authorNeilBrown <neilb@suse.de>2014-09-10 01:56:57 -0400
committerNeilBrown <neilb@suse.de>2014-09-21 21:26:01 -0400
commit235549605eb7f1c5a37cef8b09d12e6d412c5cd6 (patch)
tree13ea4c98190fd461cae935a0f5cf16cbc1403380 /drivers/md/raid1.c
parent2f73d3c55d09ce60647b96ad2a9b539c95a530ee (diff)
md/raid1: Don't use next_resync to determine how far resync has progressed
next_resync is (approximately) the location for the next resync request. However it does *not* reliably determine the earliest location at which resync might be happening. This is because resync requests can complete out of order, and we only limit the number of current requests, not the distance from the earliest pending request to the latest. mddev->curr_resync_completed is a reliable indicator of the earliest position at which resync could be happening. It is updated less frequently, but is actually reliable which is more important. So use it to determine if a write request is before the region being resynced and so safe from conflict. This error can allow resync IO to interfere with normal IO which could lead to data corruption. Hence: stable. Fixes: 79ef3a8aa1cb1523cc231c9a90a278333c21f761 cc: stable@vger.kernel.org (v3.13+) Signed-off-by: NeilBrown <neilb@suse.de>
Diffstat (limited to 'drivers/md/raid1.c')
-rw-r--r--drivers/md/raid1.c12
1 files changed, 5 insertions, 7 deletions
diff --git a/drivers/md/raid1.c b/drivers/md/raid1.c
index b13c218997da..3b14a495c424 100644
--- a/drivers/md/raid1.c
+++ b/drivers/md/raid1.c
@@ -875,12 +875,10 @@ static bool need_to_wait_for_sync(struct r1conf *conf, struct bio *bio)
875 if (conf->array_frozen || !bio) 875 if (conf->array_frozen || !bio)
876 wait = true; 876 wait = true;
877 else if (conf->barrier && bio_data_dir(bio) == WRITE) { 877 else if (conf->barrier && bio_data_dir(bio) == WRITE) {
878 if (conf->next_resync < RESYNC_WINDOW_SECTORS) 878 if ((conf->mddev->curr_resync_completed
879 wait = true; 879 >= bio_end_sector(bio)) ||
880 else if ((conf->next_resync - RESYNC_WINDOW_SECTORS 880 (conf->next_resync + NEXT_NORMALIO_DISTANCE
881 >= bio_end_sector(bio)) || 881 <= bio->bi_iter.bi_sector))
882 (conf->next_resync + NEXT_NORMALIO_DISTANCE
883 <= bio->bi_iter.bi_sector))
884 wait = false; 882 wait = false;
885 else 883 else
886 wait = true; 884 wait = true;
@@ -918,7 +916,7 @@ static sector_t wait_barrier(struct r1conf *conf, struct bio *bio)
918 916
919 if (bio && bio_data_dir(bio) == WRITE) { 917 if (bio && bio_data_dir(bio) == WRITE) {
920 if (bio->bi_iter.bi_sector >= 918 if (bio->bi_iter.bi_sector >=
921 conf->next_resync) { 919 conf->mddev->curr_resync_completed) {
922 if (conf->start_next_window == MaxSector) 920 if (conf->start_next_window == MaxSector)
923 conf->start_next_window = 921 conf->start_next_window =
924 conf->next_resync + 922 conf->next_resync +