Commit 0b8c9de05c2a860fe6b02fedcb48763bcee648b3

Authored by NeilBrown
Committed by Linus Torvalds
1 parent 31b65a0d38

[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>

Showing 2 changed files with 4 additions and 7 deletions Side-by-side Diff

... ... @@ -3095,7 +3095,6 @@
3095 3095 }
3096 3096  
3097 3097 set_bit(MD_RECOVERY_NEEDED, &mddev->recovery);
3098   - md_wakeup_thread(mddev->thread);
3099 3098  
3100 3099 if (mddev->sb_dirty)
3101 3100 md_update_sb(mddev);
... ... @@ -3116,7 +3115,7 @@
3116 3115 * start recovery here. If we leave it to md_check_recovery,
3117 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 3119 struct list_head *rtmp;
3121 3120 int spares = 0;
3122 3121 ITERATE_RDEV(mddev,rdev,rtmp)
3123 3122  
... ... @@ -3137,10 +3136,11 @@
3137 3136 mdname(mddev));
3138 3137 /* leave the spares where they are, it shouldn't hurt */
3139 3138 mddev->recovery = 0;
3140   - } else
3141   - md_wakeup_thread(mddev->sync_thread);
  3139 + }
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 3145 mddev->changed = 1;
3146 3146 md_new_event(mddev);
... ... @@ -3246,9 +3246,6 @@
3246 3246 set_bit(MD_RECOVERY_RUNNING, &mddev->recovery);
3247 3247 mddev->sync_thread = md_register_thread(md_do_sync, mddev,
3248 3248 "%s_reshape");
3249   - /* FIXME if md_register_thread fails?? */
3250   - md_wakeup_thread(mddev->sync_thread);
3251   -
3252 3249 }
3253 3250  
3254 3251 /* read-ahead size must cover two whole stripes, which is