diff options
author | NeilBrown <neilb@suse.de> | 2006-07-10 07:44:15 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@g5.osdl.org> | 2006-07-10 16:24:16 -0400 |
commit | 0b8c9de05c2a860fe6b02fedcb48763bcee648b3 (patch) | |
tree | 893228041dfcc44a216a6887e75c2424e0a8bca9 /drivers/md/md.c | |
parent | 31b65a0d3894566191b91fbadd122c354a363b5d (diff) |
[PATCH] md: delay starting md threads until array is completely setup
When an array is started we start one or two threads (two if there is a
reshape or recovery that needs to be completed).
We currently start these *before* the array is completely set up and in
particular before queue->queuedata is set. If the thread actually starts
very quickly on another CPU, we can end up dereferencing queue->queuedata
and oops.
This patch also makes sure we don't try to start a recovery if a reshape is
being restarted.
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'drivers/md/md.c')
-rw-r--r-- | drivers/md/md.c | 8 |
1 files changed, 4 insertions, 4 deletions
diff --git a/drivers/md/md.c b/drivers/md/md.c index 9f76e0cd7805..fb50e5642c63 100644 --- a/drivers/md/md.c +++ b/drivers/md/md.c | |||
@@ -3095,7 +3095,6 @@ static int do_md_run(mddev_t * mddev) | |||
3095 | } | 3095 | } |
3096 | 3096 | ||
3097 | set_bit(MD_RECOVERY_NEEDED, &mddev->recovery); | 3097 | set_bit(MD_RECOVERY_NEEDED, &mddev->recovery); |
3098 | md_wakeup_thread(mddev->thread); | ||
3099 | 3098 | ||
3100 | if (mddev->sb_dirty) | 3099 | if (mddev->sb_dirty) |
3101 | md_update_sb(mddev); | 3100 | md_update_sb(mddev); |
@@ -3116,7 +3115,7 @@ static int do_md_run(mddev_t * mddev) | |||
3116 | * start recovery here. If we leave it to md_check_recovery, | 3115 | * start recovery here. If we leave it to md_check_recovery, |
3117 | * it will remove the drives and not do the right thing | 3116 | * it will remove the drives and not do the right thing |
3118 | */ | 3117 | */ |
3119 | if (mddev->degraded) { | 3118 | if (mddev->degraded && !mddev->sync_thread) { |
3120 | struct list_head *rtmp; | 3119 | struct list_head *rtmp; |
3121 | int spares = 0; | 3120 | int spares = 0; |
3122 | ITERATE_RDEV(mddev,rdev,rtmp) | 3121 | ITERATE_RDEV(mddev,rdev,rtmp) |
@@ -3137,10 +3136,11 @@ static int do_md_run(mddev_t * mddev) | |||
3137 | mdname(mddev)); | 3136 | mdname(mddev)); |
3138 | /* leave the spares where they are, it shouldn't hurt */ | 3137 | /* leave the spares where they are, it shouldn't hurt */ |
3139 | mddev->recovery = 0; | 3138 | mddev->recovery = 0; |
3140 | } else | 3139 | } |
3141 | md_wakeup_thread(mddev->sync_thread); | ||
3142 | } | 3140 | } |
3143 | } | 3141 | } |
3142 | md_wakeup_thread(mddev->thread); | ||
3143 | md_wakeup_thread(mddev->sync_thread); /* possibly kick off a reshape */ | ||
3144 | 3144 | ||
3145 | mddev->changed = 1; | 3145 | mddev->changed = 1; |
3146 | md_new_event(mddev); | 3146 | md_new_event(mddev); |