diff options
-rw-r--r-- | drivers/md/dm-raid1.c | 12 |
1 files changed, 10 insertions, 2 deletions
diff --git a/drivers/md/dm-raid1.c b/drivers/md/dm-raid1.c index e363335e8d81..f8d7b3aa46c6 100644 --- a/drivers/md/dm-raid1.c +++ b/drivers/md/dm-raid1.c | |||
@@ -69,6 +69,7 @@ struct mirror_set { | |||
69 | region_t nr_regions; | 69 | region_t nr_regions; |
70 | int in_sync; | 70 | int in_sync; |
71 | int log_failure; | 71 | int log_failure; |
72 | int leg_failure; | ||
72 | atomic_t suspend; | 73 | atomic_t suspend; |
73 | 74 | ||
74 | atomic_t default_mirror; /* Default mirror */ | 75 | atomic_t default_mirror; /* Default mirror */ |
@@ -211,6 +212,8 @@ static void fail_mirror(struct mirror *m, enum dm_raid1_error error_type) | |||
211 | struct mirror_set *ms = m->ms; | 212 | struct mirror_set *ms = m->ms; |
212 | struct mirror *new; | 213 | struct mirror *new; |
213 | 214 | ||
215 | ms->leg_failure = 1; | ||
216 | |||
214 | /* | 217 | /* |
215 | * error_count is used for nothing more than a | 218 | * error_count is used for nothing more than a |
216 | * simple way to tell if a device has encountered | 219 | * simple way to tell if a device has encountered |
@@ -734,8 +737,12 @@ static void do_writes(struct mirror_set *ms, struct bio_list *writes) | |||
734 | dm_rh_delay(ms->rh, bio); | 737 | dm_rh_delay(ms->rh, bio); |
735 | 738 | ||
736 | while ((bio = bio_list_pop(&nosync))) { | 739 | while ((bio = bio_list_pop(&nosync))) { |
737 | map_bio(get_default_mirror(ms), bio); | 740 | if (unlikely(ms->leg_failure) && errors_handled(ms)) |
738 | generic_make_request(bio); | 741 | hold_bio(ms, bio); |
742 | else { | ||
743 | map_bio(get_default_mirror(ms), bio); | ||
744 | generic_make_request(bio); | ||
745 | } | ||
739 | } | 746 | } |
740 | } | 747 | } |
741 | 748 | ||
@@ -848,6 +855,7 @@ static struct mirror_set *alloc_context(unsigned int nr_mirrors, | |||
848 | ms->nr_regions = dm_sector_div_up(ti->len, region_size); | 855 | ms->nr_regions = dm_sector_div_up(ti->len, region_size); |
849 | ms->in_sync = 0; | 856 | ms->in_sync = 0; |
850 | ms->log_failure = 0; | 857 | ms->log_failure = 0; |
858 | ms->leg_failure = 0; | ||
851 | atomic_set(&ms->suspend, 0); | 859 | atomic_set(&ms->suspend, 0); |
852 | atomic_set(&ms->default_mirror, DEFAULT_MIRROR); | 860 | atomic_set(&ms->default_mirror, DEFAULT_MIRROR); |
853 | 861 | ||