diff options
-rw-r--r-- | drivers/md/raid5.c | 24 | ||||
-rw-r--r-- | drivers/md/raid5.h | 3 |
2 files changed, 26 insertions, 1 deletions
diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c index 214dcca0d7f8..4195064460d0 100644 --- a/drivers/md/raid5.c +++ b/drivers/md/raid5.c | |||
@@ -2513,6 +2513,7 @@ static void error(struct mddev *mddev, struct md_rdev *rdev) | |||
2513 | set_bit(Blocked, &rdev->flags); | 2513 | set_bit(Blocked, &rdev->flags); |
2514 | set_bit(Faulty, &rdev->flags); | 2514 | set_bit(Faulty, &rdev->flags); |
2515 | set_bit(MD_CHANGE_DEVS, &mddev->flags); | 2515 | set_bit(MD_CHANGE_DEVS, &mddev->flags); |
2516 | set_bit(MD_CHANGE_PENDING, &mddev->flags); | ||
2516 | printk(KERN_ALERT | 2517 | printk(KERN_ALERT |
2517 | "md/raid:%s: Disk failure on %s, disabling device.\n" | 2518 | "md/raid:%s: Disk failure on %s, disabling device.\n" |
2518 | "md/raid:%s: Operation continuing on %d devices.\n", | 2519 | "md/raid:%s: Operation continuing on %d devices.\n", |
@@ -4601,7 +4602,15 @@ finish: | |||
4601 | md_wakeup_thread(conf->mddev->thread); | 4602 | md_wakeup_thread(conf->mddev->thread); |
4602 | } | 4603 | } |
4603 | 4604 | ||
4604 | return_io(&s.return_bi); | 4605 | if (!bio_list_empty(&s.return_bi)) { |
4606 | if (test_bit(MD_CHANGE_PENDING, &conf->mddev->flags)) { | ||
4607 | spin_lock_irq(&conf->device_lock); | ||
4608 | bio_list_merge(&conf->return_bi, &s.return_bi); | ||
4609 | spin_unlock_irq(&conf->device_lock); | ||
4610 | md_wakeup_thread(conf->mddev->thread); | ||
4611 | } else | ||
4612 | return_io(&s.return_bi); | ||
4613 | } | ||
4605 | 4614 | ||
4606 | clear_bit_unlock(STRIPE_ACTIVE, &sh->state); | 4615 | clear_bit_unlock(STRIPE_ACTIVE, &sh->state); |
4607 | } | 4616 | } |
@@ -5817,6 +5826,18 @@ static void raid5d(struct md_thread *thread) | |||
5817 | 5826 | ||
5818 | md_check_recovery(mddev); | 5827 | md_check_recovery(mddev); |
5819 | 5828 | ||
5829 | if (!bio_list_empty(&conf->return_bi) && | ||
5830 | !test_bit(MD_CHANGE_PENDING, &mddev->flags)) { | ||
5831 | struct bio_list tmp = BIO_EMPTY_LIST; | ||
5832 | spin_lock_irq(&conf->device_lock); | ||
5833 | if (!test_bit(MD_CHANGE_PENDING, &mddev->flags)) { | ||
5834 | bio_list_merge(&tmp, &conf->return_bi); | ||
5835 | bio_list_init(&conf->return_bi); | ||
5836 | } | ||
5837 | spin_unlock_irq(&conf->device_lock); | ||
5838 | return_io(&tmp); | ||
5839 | } | ||
5840 | |||
5820 | blk_start_plug(&plug); | 5841 | blk_start_plug(&plug); |
5821 | handled = 0; | 5842 | handled = 0; |
5822 | spin_lock_irq(&conf->device_lock); | 5843 | spin_lock_irq(&conf->device_lock); |
@@ -6476,6 +6497,7 @@ static struct r5conf *setup_conf(struct mddev *mddev) | |||
6476 | INIT_LIST_HEAD(&conf->hold_list); | 6497 | INIT_LIST_HEAD(&conf->hold_list); |
6477 | INIT_LIST_HEAD(&conf->delayed_list); | 6498 | INIT_LIST_HEAD(&conf->delayed_list); |
6478 | INIT_LIST_HEAD(&conf->bitmap_list); | 6499 | INIT_LIST_HEAD(&conf->bitmap_list); |
6500 | bio_list_init(&conf->return_bi); | ||
6479 | init_llist_head(&conf->released_stripes); | 6501 | init_llist_head(&conf->released_stripes); |
6480 | atomic_set(&conf->active_stripes, 0); | 6502 | atomic_set(&conf->active_stripes, 0); |
6481 | atomic_set(&conf->preread_active_stripes, 0); | 6503 | atomic_set(&conf->preread_active_stripes, 0); |
diff --git a/drivers/md/raid5.h b/drivers/md/raid5.h index 1de82a6e4c23..828c2925e68f 100644 --- a/drivers/md/raid5.h +++ b/drivers/md/raid5.h | |||
@@ -476,6 +476,9 @@ struct r5conf { | |||
476 | int skip_copy; /* Don't copy data from bio to stripe cache */ | 476 | int skip_copy; /* Don't copy data from bio to stripe cache */ |
477 | struct list_head *last_hold; /* detect hold_list promotions */ | 477 | struct list_head *last_hold; /* detect hold_list promotions */ |
478 | 478 | ||
479 | /* bios to have bi_end_io called after metadata is synced */ | ||
480 | struct bio_list return_bi; | ||
481 | |||
479 | atomic_t reshape_stripes; /* stripes with pending writes for reshape */ | 482 | atomic_t reshape_stripes; /* stripes with pending writes for reshape */ |
480 | /* unfortunately we need two cache names as we temporarily have | 483 | /* unfortunately we need two cache names as we temporarily have |
481 | * two caches. | 484 | * two caches. |