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)
mddev->__minor = unit;
init_MUTEX(&mddev->reconfig_sem);
init_MUTEX(&mddev->recovery_sem);
init_MUTEX(&mddev->resync_sem);
INIT_LIST_HEAD(&mddev->disks);
INIT_LIST_HEAD(&mddev->all_mddevs);
atomic_set(&mddev->active, 1);
......@@ -647,15 +645,6 @@ static void free_mddev(mddev_t *mddev)
export_array(mddev);
md_size[mdidx(mddev)] = 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
......@@ -1682,6 +1671,8 @@ static int restart_array(mddev_t *mddev)
#define STILL_IN_USE \
"md: md%d still in use.\n"
DECLARE_WAIT_QUEUE_HEAD(resync_wait);
static int do_md_stop(mddev_t * mddev, int ro)
{
int err = 0, resync_interrupted = 0;
......@@ -1703,7 +1694,7 @@ static int do_md_stop(mddev_t * mddev, int ro)
if (mddev->pers->stop_resync(mddev))
resync_interrupted = 1;
if (mddev->recovery_running)
if (mddev->recovery_running==1)
md_interrupt_thread(md_recovery_thread);
/*
......@@ -1712,8 +1703,8 @@ static int do_md_stop(mddev_t * mddev, int ro)
* hangs the process if some reconstruction has not
* finished.
*/
down(&mddev->recovery_sem);
up(&mddev->recovery_sem);
wait_event(resync_wait, mddev->recovery_running <= 0);
invalidate_device(dev, 1);
......@@ -2900,7 +2891,7 @@ int md_error(mddev_t *mddev, struct block_device *bdev)
*/
if (mddev->pers->stop_resync)
mddev->pers->stop_resync(mddev);
if (mddev->recovery_running)
if (mddev->recovery_running==1)
md_interrupt_thread(md_recovery_thread);
md_recover_arrays();
......@@ -2959,7 +2950,7 @@ static int status_resync(char * page, mddev_t * mddev)
sz += sprintf(page + sz, ".");
sz += sprintf(page + sz, "] ");
}
if (!mddev->recovery_running)
if (mddev->recovery_running==2)
/*
* true resync
*/
......@@ -3048,7 +3039,7 @@ static int md_status_read_proc(char *page, char **start, off_t off,
if (mddev->curr_resync) {
sz += status_resync (page+sz, mddev);
} else {
if (atomic_read(&mddev->resync_sem.count) != 1)
if (mddev->recovery_running < 0)
sz += sprintf(page + sz, " resync=DELAYED");
}
sz += sprintf(page + sz, "\n");
......@@ -3153,8 +3144,6 @@ static int is_mddev_idle(mddev_t *mddev)
return idle;
}
DECLARE_WAIT_QUEUE_HEAD(resync_wait);
void md_done_sync(mddev_t *mddev, int blocks, int ok)
{
/* another "blocks" (512byte) blocks have been synced */
......@@ -3179,10 +3168,6 @@ int md_do_sync(mddev_t *mddev, mdp_disk_t *spare)
unsigned long last_check;
err = down_interruptible(&mddev->resync_sem);
if (err)
goto out_nolock;
recheck:
serialize = 0;
ITERATE_MDDEV(mddev2,tmp) {
......@@ -3305,9 +3290,8 @@ int md_do_sync(mddev_t *mddev, mdp_disk_t *spare)
*/
out:
wait_event(mddev->recovery_wait, !atomic_read(&mddev->recovery_active));
up(&mddev->resync_sem);
out_nolock:
mddev->curr_resync = 0;
mddev->recovery_running = err;
wake_up(&resync_wait);
return err;
}
......@@ -3356,7 +3340,6 @@ void md_do_recovery(void *data)
goto unlock;
if (mddev->pers->diskop(mddev, &spare, DISKOP_SPARE_WRITE))
goto unlock;
down(&mddev->recovery_sem);
mddev->recovery_running = 1;
mddev_unlock(mddev);
err = md_do_sync(mddev, spare);
......@@ -3384,12 +3367,7 @@ void md_do_recovery(void *data)
*/
mddev->pers->diskop(mddev, &spare,
DISKOP_SPARE_INACTIVE);
up(&mddev->recovery_sem);
mddev->recovery_running = 0;
goto unlock;
} else {
mddev->recovery_running = 0;
up(&mddev->recovery_sem);
}
if (!disk_faulty(spare)) {
/*
......@@ -3404,6 +3382,7 @@ void md_do_recovery(void *data)
}
mddev->sb_dirty = 1;
md_update_sb(mddev);
mddev->recovery_running = 0;
unlock:
mddev_unlock(mddev);
}
......
......@@ -1125,9 +1125,8 @@ static void raid1syncd(void *data)
if (!conf->resync_mirrors)
return;
if (conf->resync_mirrors == 2)
if (mddev->recovery_running != 2)
return;
down(&mddev->recovery_sem);
if (!md_do_sync(mddev, NULL)) {
/*
* Only if everything went Ok.
......@@ -1137,7 +1136,6 @@ static void raid1syncd(void *data)
close_sync(conf);
up(&mddev->recovery_sem);
}
static int init_resync(conf_t *conf)
......@@ -1477,6 +1475,7 @@ static int run(mddev_t *mddev)
printk(START_RESYNC, mdidx(mddev));
conf->resync_mirrors = 1;
mddev->recovery_running = 2;
md_wakeup_thread(conf->resync_thread);
}
......@@ -1524,7 +1523,6 @@ static int stop_resync(mddev_t *mddev)
if (conf->resync_thread) {
if (conf->resync_mirrors) {
conf->resync_mirrors = 2;
md_interrupt_thread(conf->resync_thread);
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)
MD_BUG();
return 0;
}
conf->resync_mirrors = 1;
mddev->recovery_running = 2;
md_wakeup_thread(conf->resync_thread);
return 1;
}
......
......@@ -1386,16 +1386,13 @@ static void raid5syncd (void *data)
if (!conf->resync_parity)
return;
if (conf->resync_parity == 2)
if (mddev->recovery_running != 2)
return;
down(&mddev->recovery_sem);
if (md_do_sync(mddev,NULL)) {
up(&mddev->recovery_sem);
printk("raid5: resync aborted!\n");
return;
}
conf->resync_parity = 0;
up(&mddev->recovery_sem);
printk("raid5: resync finished.\n");
}
......@@ -1615,6 +1612,7 @@ static int run (mddev_t *mddev)
printk("raid5: raid set md%d not clean; reconstructing parity\n", mdidx(mddev));
conf->resync_parity = 1;
mddev->recovery_running = 2;
md_wakeup_thread(conf->resync_thread);
}
......@@ -1646,7 +1644,6 @@ static int stop_resync (mddev_t *mddev)
if (thread) {
if (conf->resync_parity) {
conf->resync_parity = 2;
md_interrupt_thread(thread);
printk(KERN_INFO "raid5: parity resync was not fully finished, restarting next time.\n");
return 1;
......@@ -1666,7 +1663,7 @@ static int restart_resync (mddev_t *mddev)
return 0;
}
printk("raid5: waking up raid5resync.\n");
conf->resync_parity = 1;
mddev->recovery_running = 2;
md_wakeup_thread(conf->resync_thread);
return 1;
} else
......
......@@ -184,10 +184,14 @@ struct mddev_s
unsigned long curr_resync; /* blocks scheduled */
unsigned long resync_mark; /* a recent timestamp */
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;
struct semaphore reconfig_sem;
struct semaphore recovery_sem;
struct semaphore resync_sem;
atomic_t active;
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