diff options
Diffstat (limited to 'drivers/md')
-rw-r--r-- | drivers/md/md.c | 39 | ||||
-rw-r--r-- | drivers/md/raid10.c | 2 |
2 files changed, 21 insertions, 20 deletions
diff --git a/drivers/md/md.c b/drivers/md/md.c index 52694d29663d..175c424f201f 100644 --- a/drivers/md/md.c +++ b/drivers/md/md.c | |||
@@ -371,10 +371,15 @@ static void md_end_flush(struct bio *bio, int err) | |||
371 | bio_put(bio); | 371 | bio_put(bio); |
372 | } | 372 | } |
373 | 373 | ||
374 | static void submit_flushes(mddev_t *mddev) | 374 | static void md_submit_flush_data(struct work_struct *ws); |
375 | |||
376 | static void submit_flushes(struct work_struct *ws) | ||
375 | { | 377 | { |
378 | mddev_t *mddev = container_of(ws, mddev_t, flush_work); | ||
376 | mdk_rdev_t *rdev; | 379 | mdk_rdev_t *rdev; |
377 | 380 | ||
381 | INIT_WORK(&mddev->flush_work, md_submit_flush_data); | ||
382 | atomic_set(&mddev->flush_pending, 1); | ||
378 | rcu_read_lock(); | 383 | rcu_read_lock(); |
379 | list_for_each_entry_rcu(rdev, &mddev->disks, same_set) | 384 | list_for_each_entry_rcu(rdev, &mddev->disks, same_set) |
380 | if (rdev->raid_disk >= 0 && | 385 | if (rdev->raid_disk >= 0 && |
@@ -397,6 +402,8 @@ static void submit_flushes(mddev_t *mddev) | |||
397 | rdev_dec_pending(rdev, mddev); | 402 | rdev_dec_pending(rdev, mddev); |
398 | } | 403 | } |
399 | rcu_read_unlock(); | 404 | rcu_read_unlock(); |
405 | if (atomic_dec_and_test(&mddev->flush_pending)) | ||
406 | queue_work(md_wq, &mddev->flush_work); | ||
400 | } | 407 | } |
401 | 408 | ||
402 | static void md_submit_flush_data(struct work_struct *ws) | 409 | static void md_submit_flush_data(struct work_struct *ws) |
@@ -404,8 +411,6 @@ static void md_submit_flush_data(struct work_struct *ws) | |||
404 | mddev_t *mddev = container_of(ws, mddev_t, flush_work); | 411 | mddev_t *mddev = container_of(ws, mddev_t, flush_work); |
405 | struct bio *bio = mddev->flush_bio; | 412 | struct bio *bio = mddev->flush_bio; |
406 | 413 | ||
407 | atomic_set(&mddev->flush_pending, 1); | ||
408 | |||
409 | if (bio->bi_size == 0) | 414 | if (bio->bi_size == 0) |
410 | /* an empty barrier - all done */ | 415 | /* an empty barrier - all done */ |
411 | bio_endio(bio, 0); | 416 | bio_endio(bio, 0); |
@@ -414,10 +419,9 @@ static void md_submit_flush_data(struct work_struct *ws) | |||
414 | if (mddev->pers->make_request(mddev, bio)) | 419 | if (mddev->pers->make_request(mddev, bio)) |
415 | generic_make_request(bio); | 420 | generic_make_request(bio); |
416 | } | 421 | } |
417 | if (atomic_dec_and_test(&mddev->flush_pending)) { | 422 | |
418 | mddev->flush_bio = NULL; | 423 | mddev->flush_bio = NULL; |
419 | wake_up(&mddev->sb_wait); | 424 | wake_up(&mddev->sb_wait); |
420 | } | ||
421 | } | 425 | } |
422 | 426 | ||
423 | void md_flush_request(mddev_t *mddev, struct bio *bio) | 427 | void md_flush_request(mddev_t *mddev, struct bio *bio) |
@@ -429,13 +433,8 @@ void md_flush_request(mddev_t *mddev, struct bio *bio) | |||
429 | mddev->flush_bio = bio; | 433 | mddev->flush_bio = bio; |
430 | spin_unlock_irq(&mddev->write_lock); | 434 | spin_unlock_irq(&mddev->write_lock); |
431 | 435 | ||
432 | atomic_set(&mddev->flush_pending, 1); | 436 | INIT_WORK(&mddev->flush_work, submit_flushes); |
433 | INIT_WORK(&mddev->flush_work, md_submit_flush_data); | 437 | queue_work(md_wq, &mddev->flush_work); |
434 | |||
435 | submit_flushes(mddev); | ||
436 | |||
437 | if (atomic_dec_and_test(&mddev->flush_pending)) | ||
438 | queue_work(md_wq, &mddev->flush_work); | ||
439 | } | 438 | } |
440 | EXPORT_SYMBOL(md_flush_request); | 439 | EXPORT_SYMBOL(md_flush_request); |
441 | 440 | ||
@@ -5157,7 +5156,7 @@ static int add_new_disk(mddev_t * mddev, mdu_disk_info_t *info) | |||
5157 | PTR_ERR(rdev)); | 5156 | PTR_ERR(rdev)); |
5158 | return PTR_ERR(rdev); | 5157 | return PTR_ERR(rdev); |
5159 | } | 5158 | } |
5160 | /* set save_raid_disk if appropriate */ | 5159 | /* set saved_raid_disk if appropriate */ |
5161 | if (!mddev->persistent) { | 5160 | if (!mddev->persistent) { |
5162 | if (info->state & (1<<MD_DISK_SYNC) && | 5161 | if (info->state & (1<<MD_DISK_SYNC) && |
5163 | info->raid_disk < mddev->raid_disks) | 5162 | info->raid_disk < mddev->raid_disks) |
@@ -5167,7 +5166,10 @@ static int add_new_disk(mddev_t * mddev, mdu_disk_info_t *info) | |||
5167 | } else | 5166 | } else |
5168 | super_types[mddev->major_version]. | 5167 | super_types[mddev->major_version]. |
5169 | validate_super(mddev, rdev); | 5168 | validate_super(mddev, rdev); |
5170 | rdev->saved_raid_disk = rdev->raid_disk; | 5169 | if (test_bit(In_sync, &rdev->flags)) |
5170 | rdev->saved_raid_disk = rdev->raid_disk; | ||
5171 | else | ||
5172 | rdev->saved_raid_disk = -1; | ||
5171 | 5173 | ||
5172 | clear_bit(In_sync, &rdev->flags); /* just to be sure */ | 5174 | clear_bit(In_sync, &rdev->flags); /* just to be sure */ |
5173 | if (info->state & (1<<MD_DISK_WRITEMOSTLY)) | 5175 | if (info->state & (1<<MD_DISK_WRITEMOSTLY)) |
@@ -6039,9 +6041,8 @@ static int md_thread(void * arg) | |||
6039 | || kthread_should_stop(), | 6041 | || kthread_should_stop(), |
6040 | thread->timeout); | 6042 | thread->timeout); |
6041 | 6043 | ||
6042 | clear_bit(THREAD_WAKEUP, &thread->flags); | 6044 | if (test_and_clear_bit(THREAD_WAKEUP, &thread->flags)) |
6043 | 6045 | thread->run(thread->mddev); | |
6044 | thread->run(thread->mddev); | ||
6045 | } | 6046 | } |
6046 | 6047 | ||
6047 | return 0; | 6048 | return 0; |
diff --git a/drivers/md/raid10.c b/drivers/md/raid10.c index c67aa54694ae..0641674827f0 100644 --- a/drivers/md/raid10.c +++ b/drivers/md/raid10.c | |||
@@ -2397,13 +2397,13 @@ static int run(mddev_t *mddev) | |||
2397 | return 0; | 2397 | return 0; |
2398 | 2398 | ||
2399 | out_free_conf: | 2399 | out_free_conf: |
2400 | md_unregister_thread(mddev->thread); | ||
2400 | if (conf->r10bio_pool) | 2401 | if (conf->r10bio_pool) |
2401 | mempool_destroy(conf->r10bio_pool); | 2402 | mempool_destroy(conf->r10bio_pool); |
2402 | safe_put_page(conf->tmppage); | 2403 | safe_put_page(conf->tmppage); |
2403 | kfree(conf->mirrors); | 2404 | kfree(conf->mirrors); |
2404 | kfree(conf); | 2405 | kfree(conf); |
2405 | mddev->private = NULL; | 2406 | mddev->private = NULL; |
2406 | md_unregister_thread(mddev->thread); | ||
2407 | out: | 2407 | out: |
2408 | return -EIO; | 2408 | return -EIO; |
2409 | } | 2409 | } |