mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-09-06 10:57:46 +00:00
md/raid1: fix: IO can block resync indefinitely
While performing a resync/recovery, raid1 divides the array space into three regions: - before the resync - at or shortly after the resync point - much further ahead of the resync point. Write requests to the first or third do not need to wait. Write requests to the middle region do need to wait if resync requests are pending. If there are any active write requests in the middle region, resync will wait for them. Due to an accounting error, there is a small range of addresses, between conf->next_resync and conf->start_next_window, where write requests will *not* be blocked, but *will* be counted in the middle region. This can effectively block resync indefinitely if filesystem writes happen repeatedly to this region. As ->next_window_requests is incremented when the sector is after conf->start_next_window + NEXT_NORMALIO_DISTANCE the same boundary should be used for determining when write requests should wait. Signed-off-by: NeilBrown <neilb@suse.com> Signed-off-by: Shaohua Li <shli@fb.com>
This commit is contained in:
parent
85c9ccd4f0
commit
f2c771a655
1 changed files with 1 additions and 1 deletions
|
@ -834,7 +834,7 @@ static bool need_to_wait_for_sync(struct r1conf *conf, struct bio *bio)
|
||||||
else if (conf->barrier && bio_data_dir(bio) == WRITE) {
|
else if (conf->barrier && bio_data_dir(bio) == WRITE) {
|
||||||
if ((conf->mddev->curr_resync_completed
|
if ((conf->mddev->curr_resync_completed
|
||||||
>= bio_end_sector(bio)) ||
|
>= bio_end_sector(bio)) ||
|
||||||
(conf->next_resync + NEXT_NORMALIO_DISTANCE
|
(conf->start_next_window + NEXT_NORMALIO_DISTANCE
|
||||||
<= bio->bi_iter.bi_sector))
|
<= bio->bi_iter.bi_sector))
|
||||||
wait = false;
|
wait = false;
|
||||||
else
|
else
|
||||||
|
|
Loading…
Reference in a new issue