Commit 7145dd24 authored by Neil Brown's avatar Neil Brown Committed by Linus Torvalds

[PATCH] md 18 of 22 - More mddev tidyup - remove recovery_sem and resync_sem

More mddev tidyup - remove recovery_sem and resync_sem

recovery_sem and resync_sem get replaced by careful use
of recovery_running protected by reconfig_sem.

As part of this, the creative:
	down(&mddev->recovery_sem);
	up(&mddev->recovery_sem);

when stopping an array gets replaced by a more obvious

	wait_event(resync_wait, mddev->recovery_running <= 0);
parent bc0eea33
...@@ -171,8 +171,6 @@ static mddev_t * mddev_find(int unit) ...@@ -171,8 +171,6 @@ static mddev_t * mddev_find(int unit)
mddev->__minor = unit; mddev->__minor = unit;
init_MUTEX(&mddev->reconfig_sem); init_MUTEX(&mddev->reconfig_sem);
init_MUTEX(&mddev->recovery_sem);
init_MUTEX(&mddev->resync_sem);
INIT_LIST_HEAD(&mddev->disks); INIT_LIST_HEAD(&mddev->disks);
INIT_LIST_HEAD(&mddev->all_mddevs); INIT_LIST_HEAD(&mddev->all_mddevs);
atomic_set(&mddev->active, 1); atomic_set(&mddev->active, 1);
...@@ -647,15 +645,6 @@ static void free_mddev(mddev_t *mddev) ...@@ -647,15 +645,6 @@ static void free_mddev(mddev_t *mddev)
export_array(mddev); export_array(mddev);
md_size[mdidx(mddev)] = 0; md_size[mdidx(mddev)] = 0;
md_hd_struct[mdidx(mddev)].nr_sects = 0; md_hd_struct[mdidx(mddev)].nr_sects = 0;
/*
* Make sure nobody else is using this mddev
* (careful, we rely on the global kernel lock here)
*/
while (atomic_read(&mddev->resync_sem.count) != 1)
schedule();
while (atomic_read(&mddev->recovery_sem.count) != 1)
schedule();
} }
#undef BAD_CSUM #undef BAD_CSUM
...@@ -1682,6 +1671,8 @@ static int restart_array(mddev_t *mddev) ...@@ -1682,6 +1671,8 @@ static int restart_array(mddev_t *mddev)
#define STILL_IN_USE \ #define STILL_IN_USE \
"md: md%d still in use.\n" "md: md%d still in use.\n"
DECLARE_WAIT_QUEUE_HEAD(resync_wait);
static int do_md_stop(mddev_t * mddev, int ro) static int do_md_stop(mddev_t * mddev, int ro)
{ {
int err = 0, resync_interrupted = 0; int err = 0, resync_interrupted = 0;
...@@ -1703,7 +1694,7 @@ static int do_md_stop(mddev_t * mddev, int ro) ...@@ -1703,7 +1694,7 @@ static int do_md_stop(mddev_t * mddev, int ro)
if (mddev->pers->stop_resync(mddev)) if (mddev->pers->stop_resync(mddev))
resync_interrupted = 1; resync_interrupted = 1;
if (mddev->recovery_running) if (mddev->recovery_running==1)
md_interrupt_thread(md_recovery_thread); md_interrupt_thread(md_recovery_thread);
/* /*
...@@ -1712,8 +1703,8 @@ static int do_md_stop(mddev_t * mddev, int ro) ...@@ -1712,8 +1703,8 @@ static int do_md_stop(mddev_t * mddev, int ro)
* hangs the process if some reconstruction has not * hangs the process if some reconstruction has not
* finished. * finished.
*/ */
down(&mddev->recovery_sem);
up(&mddev->recovery_sem); wait_event(resync_wait, mddev->recovery_running <= 0);
invalidate_device(dev, 1); invalidate_device(dev, 1);
...@@ -2900,7 +2891,7 @@ int md_error(mddev_t *mddev, struct block_device *bdev) ...@@ -2900,7 +2891,7 @@ int md_error(mddev_t *mddev, struct block_device *bdev)
*/ */
if (mddev->pers->stop_resync) if (mddev->pers->stop_resync)
mddev->pers->stop_resync(mddev); mddev->pers->stop_resync(mddev);
if (mddev->recovery_running) if (mddev->recovery_running==1)
md_interrupt_thread(md_recovery_thread); md_interrupt_thread(md_recovery_thread);
md_recover_arrays(); md_recover_arrays();
...@@ -2959,7 +2950,7 @@ static int status_resync(char * page, mddev_t * mddev) ...@@ -2959,7 +2950,7 @@ static int status_resync(char * page, mddev_t * mddev)
sz += sprintf(page + sz, "."); sz += sprintf(page + sz, ".");
sz += sprintf(page + sz, "] "); sz += sprintf(page + sz, "] ");
} }
if (!mddev->recovery_running) if (mddev->recovery_running==2)
/* /*
* true resync * true resync
*/ */
...@@ -3048,7 +3039,7 @@ static int md_status_read_proc(char *page, char **start, off_t off, ...@@ -3048,7 +3039,7 @@ static int md_status_read_proc(char *page, char **start, off_t off,
if (mddev->curr_resync) { if (mddev->curr_resync) {
sz += status_resync (page+sz, mddev); sz += status_resync (page+sz, mddev);
} else { } else {
if (atomic_read(&mddev->resync_sem.count) != 1) if (mddev->recovery_running < 0)
sz += sprintf(page + sz, " resync=DELAYED"); sz += sprintf(page + sz, " resync=DELAYED");
} }
sz += sprintf(page + sz, "\n"); sz += sprintf(page + sz, "\n");
...@@ -3153,8 +3144,6 @@ static int is_mddev_idle(mddev_t *mddev) ...@@ -3153,8 +3144,6 @@ static int is_mddev_idle(mddev_t *mddev)
return idle; return idle;
} }
DECLARE_WAIT_QUEUE_HEAD(resync_wait);
void md_done_sync(mddev_t *mddev, int blocks, int ok) void md_done_sync(mddev_t *mddev, int blocks, int ok)
{ {
/* another "blocks" (512byte) blocks have been synced */ /* another "blocks" (512byte) blocks have been synced */
...@@ -3179,10 +3168,6 @@ int md_do_sync(mddev_t *mddev, mdp_disk_t *spare) ...@@ -3179,10 +3168,6 @@ int md_do_sync(mddev_t *mddev, mdp_disk_t *spare)
unsigned long last_check; unsigned long last_check;
err = down_interruptible(&mddev->resync_sem);
if (err)
goto out_nolock;
recheck: recheck:
serialize = 0; serialize = 0;
ITERATE_MDDEV(mddev2,tmp) { ITERATE_MDDEV(mddev2,tmp) {
...@@ -3305,9 +3290,8 @@ int md_do_sync(mddev_t *mddev, mdp_disk_t *spare) ...@@ -3305,9 +3290,8 @@ int md_do_sync(mddev_t *mddev, mdp_disk_t *spare)
*/ */
out: out:
wait_event(mddev->recovery_wait, !atomic_read(&mddev->recovery_active)); wait_event(mddev->recovery_wait, !atomic_read(&mddev->recovery_active));
up(&mddev->resync_sem);
out_nolock:
mddev->curr_resync = 0; mddev->curr_resync = 0;
mddev->recovery_running = err;
wake_up(&resync_wait); wake_up(&resync_wait);
return err; return err;
} }
...@@ -3356,7 +3340,6 @@ void md_do_recovery(void *data) ...@@ -3356,7 +3340,6 @@ void md_do_recovery(void *data)
goto unlock; goto unlock;
if (mddev->pers->diskop(mddev, &spare, DISKOP_SPARE_WRITE)) if (mddev->pers->diskop(mddev, &spare, DISKOP_SPARE_WRITE))
goto unlock; goto unlock;
down(&mddev->recovery_sem);
mddev->recovery_running = 1; mddev->recovery_running = 1;
mddev_unlock(mddev); mddev_unlock(mddev);
err = md_do_sync(mddev, spare); err = md_do_sync(mddev, spare);
...@@ -3384,12 +3367,7 @@ void md_do_recovery(void *data) ...@@ -3384,12 +3367,7 @@ void md_do_recovery(void *data)
*/ */
mddev->pers->diskop(mddev, &spare, mddev->pers->diskop(mddev, &spare,
DISKOP_SPARE_INACTIVE); DISKOP_SPARE_INACTIVE);
up(&mddev->recovery_sem);
mddev->recovery_running = 0;
goto unlock; goto unlock;
} else {
mddev->recovery_running = 0;
up(&mddev->recovery_sem);
} }
if (!disk_faulty(spare)) { if (!disk_faulty(spare)) {
/* /*
...@@ -3404,6 +3382,7 @@ void md_do_recovery(void *data) ...@@ -3404,6 +3382,7 @@ void md_do_recovery(void *data)
} }
mddev->sb_dirty = 1; mddev->sb_dirty = 1;
md_update_sb(mddev); md_update_sb(mddev);
mddev->recovery_running = 0;
unlock: unlock:
mddev_unlock(mddev); mddev_unlock(mddev);
} }
......
...@@ -1125,9 +1125,8 @@ static void raid1syncd(void *data) ...@@ -1125,9 +1125,8 @@ static void raid1syncd(void *data)
if (!conf->resync_mirrors) if (!conf->resync_mirrors)
return; return;
if (conf->resync_mirrors == 2) if (mddev->recovery_running != 2)
return; return;
down(&mddev->recovery_sem);
if (!md_do_sync(mddev, NULL)) { if (!md_do_sync(mddev, NULL)) {
/* /*
* Only if everything went Ok. * Only if everything went Ok.
...@@ -1137,7 +1136,6 @@ static void raid1syncd(void *data) ...@@ -1137,7 +1136,6 @@ static void raid1syncd(void *data)
close_sync(conf); close_sync(conf);
up(&mddev->recovery_sem);
} }
static int init_resync(conf_t *conf) static int init_resync(conf_t *conf)
...@@ -1477,6 +1475,7 @@ static int run(mddev_t *mddev) ...@@ -1477,6 +1475,7 @@ static int run(mddev_t *mddev)
printk(START_RESYNC, mdidx(mddev)); printk(START_RESYNC, mdidx(mddev));
conf->resync_mirrors = 1; conf->resync_mirrors = 1;
mddev->recovery_running = 2;
md_wakeup_thread(conf->resync_thread); md_wakeup_thread(conf->resync_thread);
} }
...@@ -1524,7 +1523,6 @@ static int stop_resync(mddev_t *mddev) ...@@ -1524,7 +1523,6 @@ static int stop_resync(mddev_t *mddev)
if (conf->resync_thread) { if (conf->resync_thread) {
if (conf->resync_mirrors) { if (conf->resync_mirrors) {
conf->resync_mirrors = 2;
md_interrupt_thread(conf->resync_thread); md_interrupt_thread(conf->resync_thread);
printk(KERN_INFO "raid1: mirror resync was not fully finished, restarting next time.\n"); printk(KERN_INFO "raid1: mirror resync was not fully finished, restarting next time.\n");
...@@ -1544,7 +1542,7 @@ static int restart_resync(mddev_t *mddev) ...@@ -1544,7 +1542,7 @@ static int restart_resync(mddev_t *mddev)
MD_BUG(); MD_BUG();
return 0; return 0;
} }
conf->resync_mirrors = 1; mddev->recovery_running = 2;
md_wakeup_thread(conf->resync_thread); md_wakeup_thread(conf->resync_thread);
return 1; return 1;
} }
......
...@@ -1386,16 +1386,13 @@ static void raid5syncd (void *data) ...@@ -1386,16 +1386,13 @@ static void raid5syncd (void *data)
if (!conf->resync_parity) if (!conf->resync_parity)
return; return;
if (conf->resync_parity == 2) if (mddev->recovery_running != 2)
return; return;
down(&mddev->recovery_sem);
if (md_do_sync(mddev,NULL)) { if (md_do_sync(mddev,NULL)) {
up(&mddev->recovery_sem);
printk("raid5: resync aborted!\n"); printk("raid5: resync aborted!\n");
return; return;
} }
conf->resync_parity = 0; conf->resync_parity = 0;
up(&mddev->recovery_sem);
printk("raid5: resync finished.\n"); printk("raid5: resync finished.\n");
} }
...@@ -1615,6 +1612,7 @@ static int run (mddev_t *mddev) ...@@ -1615,6 +1612,7 @@ static int run (mddev_t *mddev)
printk("raid5: raid set md%d not clean; reconstructing parity\n", mdidx(mddev)); printk("raid5: raid set md%d not clean; reconstructing parity\n", mdidx(mddev));
conf->resync_parity = 1; conf->resync_parity = 1;
mddev->recovery_running = 2;
md_wakeup_thread(conf->resync_thread); md_wakeup_thread(conf->resync_thread);
} }
...@@ -1646,7 +1644,6 @@ static int stop_resync (mddev_t *mddev) ...@@ -1646,7 +1644,6 @@ static int stop_resync (mddev_t *mddev)
if (thread) { if (thread) {
if (conf->resync_parity) { if (conf->resync_parity) {
conf->resync_parity = 2;
md_interrupt_thread(thread); md_interrupt_thread(thread);
printk(KERN_INFO "raid5: parity resync was not fully finished, restarting next time.\n"); printk(KERN_INFO "raid5: parity resync was not fully finished, restarting next time.\n");
return 1; return 1;
...@@ -1666,7 +1663,7 @@ static int restart_resync (mddev_t *mddev) ...@@ -1666,7 +1663,7 @@ static int restart_resync (mddev_t *mddev)
return 0; return 0;
} }
printk("raid5: waking up raid5resync.\n"); printk("raid5: waking up raid5resync.\n");
conf->resync_parity = 1; mddev->recovery_running = 2;
md_wakeup_thread(conf->resync_thread); md_wakeup_thread(conf->resync_thread);
return 1; return 1;
} else } else
......
...@@ -184,10 +184,14 @@ struct mddev_s ...@@ -184,10 +184,14 @@ struct mddev_s
unsigned long curr_resync; /* blocks scheduled */ unsigned long curr_resync; /* blocks scheduled */
unsigned long resync_mark; /* a recent timestamp */ unsigned long resync_mark; /* a recent timestamp */
unsigned long resync_mark_cnt;/* blocks written at resync_mark */ unsigned long resync_mark_cnt;/* blocks written at resync_mark */
/* recovery_running is 0 for no recovery/resync,
* 1 for active recovery
* 2 for active resync
* -error for an error (e.g. -EINTR)
* it can only be set > 0 under reconfig_sem
*/
int recovery_running; int recovery_running;
struct semaphore reconfig_sem; struct semaphore reconfig_sem;
struct semaphore recovery_sem;
struct semaphore resync_sem;
atomic_t active; atomic_t active;
atomic_t recovery_active; /* blocks scheduled, but not written */ atomic_t recovery_active; /* blocks scheduled, but not written */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment