Commit 0b8c9de05c2a860fe6b02fedcb48763bcee648b3
Committed by
Linus Torvalds
1 parent
31b65a0d38
Exists in
master
and in
4 other branches
[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
drivers/md/md.c
| ... | ... | @@ -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); |
drivers/md/raid5.c
| ... | ... | @@ -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 |