[PATCH] md: fix rdev->pending counts in raid1

When we do a user-requested check/repair, we lose count of the outstanding
requests...

Also make sure that when anything is written to md/sync_action, the
RECOVERY_NEEDED flag is set and the thread is woken up so any changes take
effect.

Signed-off-by: Neil Brown <neilb@suse.de>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
This commit is contained in:
NeilBrown 2006-01-06 00:20:46 -08:00 committed by Linus Torvalds
parent c708443c00
commit 03c902e17f
2 changed files with 10 additions and 11 deletions

View File

@ -1826,13 +1826,10 @@ action_store(mddev_t *mddev, const char *page, size_t len)
mddev->sync_thread = NULL; mddev->sync_thread = NULL;
mddev->recovery = 0; mddev->recovery = 0;
} }
return len; } else if (test_bit(MD_RECOVERY_RUNNING, &mddev->recovery) ||
}
if (test_bit(MD_RECOVERY_RUNNING, &mddev->recovery) ||
test_bit(MD_RECOVERY_NEEDED, &mddev->recovery)) test_bit(MD_RECOVERY_NEEDED, &mddev->recovery))
return -EBUSY; return -EBUSY;
if (cmd_match(page, "resync") || cmd_match(page, "recover")) else if (cmd_match(page, "resync") || cmd_match(page, "recover"))
set_bit(MD_RECOVERY_NEEDED, &mddev->recovery); set_bit(MD_RECOVERY_NEEDED, &mddev->recovery);
else { else {
if (cmd_match(page, "check")) if (cmd_match(page, "check"))
@ -1841,8 +1838,8 @@ action_store(mddev_t *mddev, const char *page, size_t len)
return -EINVAL; return -EINVAL;
set_bit(MD_RECOVERY_REQUESTED, &mddev->recovery); set_bit(MD_RECOVERY_REQUESTED, &mddev->recovery);
set_bit(MD_RECOVERY_SYNC, &mddev->recovery); set_bit(MD_RECOVERY_SYNC, &mddev->recovery);
set_bit(MD_RECOVERY_NEEDED, &mddev->recovery);
} }
set_bit(MD_RECOVERY_NEEDED, &mddev->recovery);
md_wakeup_thread(mddev->thread); md_wakeup_thread(mddev->thread);
return len; return len;
} }

View File

@ -527,7 +527,7 @@ static int read_balance(conf_t *conf, r1bio_t *r1_bio)
/* cannot risk returning a device that failed /* cannot risk returning a device that failed
* before we inc'ed nr_pending * before we inc'ed nr_pending
*/ */
atomic_dec(&rdev->nr_pending); rdev_dec_pending(rdev, conf->mddev);
goto retry; goto retry;
} }
conf->next_seq_sect = this_sector + sectors; conf->next_seq_sect = this_sector + sectors;
@ -830,7 +830,7 @@ static int make_request(request_queue_t *q, struct bio * bio)
!test_bit(Faulty, &rdev->flags)) { !test_bit(Faulty, &rdev->flags)) {
atomic_inc(&rdev->nr_pending); atomic_inc(&rdev->nr_pending);
if (test_bit(Faulty, &rdev->flags)) { if (test_bit(Faulty, &rdev->flags)) {
atomic_dec(&rdev->nr_pending); rdev_dec_pending(rdev, mddev);
r1_bio->bios[i] = NULL; r1_bio->bios[i] = NULL;
} else } else
r1_bio->bios[i] = bio; r1_bio->bios[i] = bio;
@ -1176,6 +1176,7 @@ static void sync_request_write(mddev_t *mddev, r1bio_t *r1_bio)
if (r1_bio->bios[primary]->bi_end_io == end_sync_read && if (r1_bio->bios[primary]->bi_end_io == end_sync_read &&
test_bit(BIO_UPTODATE, &r1_bio->bios[primary]->bi_flags)) { test_bit(BIO_UPTODATE, &r1_bio->bios[primary]->bi_flags)) {
r1_bio->bios[primary]->bi_end_io = NULL; r1_bio->bios[primary]->bi_end_io = NULL;
rdev_dec_pending(conf->mirrors[primary].rdev, mddev);
break; break;
} }
r1_bio->read_disk = primary; r1_bio->read_disk = primary;
@ -1193,9 +1194,10 @@ static void sync_request_write(mddev_t *mddev, r1bio_t *r1_bio)
break; break;
if (j >= 0) if (j >= 0)
mddev->resync_mismatches += r1_bio->sectors; mddev->resync_mismatches += r1_bio->sectors;
if (j < 0 || test_bit(MD_RECOVERY_CHECK, &mddev->recovery)) if (j < 0 || test_bit(MD_RECOVERY_CHECK, &mddev->recovery)) {
sbio->bi_end_io = NULL; sbio->bi_end_io = NULL;
else { rdev_dec_pending(conf->mirrors[i].rdev, mddev);
} else {
/* fixup the bio for reuse */ /* fixup the bio for reuse */
sbio->bi_vcnt = vcnt; sbio->bi_vcnt = vcnt;
sbio->bi_size = r1_bio->sectors << 9; sbio->bi_size = r1_bio->sectors << 9;