提交 929be8fc 编写于 作者: M Mikulas Patocka 提交者: Alasdair G Kergon

dm raid1: hold all write bios when leg fails

Hold all write bios when leg fails and errors are handled

When using a userspace daemon such as dmeventd to handle errors, we must
delay completing  bios until it has done its job.
This patch prevents the following race:
  - primary leg fails
  - write "1" fail, the write is held, secondary leg is set default
  - write "2" goes straight to the secondary leg
Signed-off-by: NMikulas Patocka <mpatocka@redhat.com>
Reviewed-by: NTakahiro Yasui <tyasui@redhat.com>
Tested-by: NTakahiro Yasui <tyasui@redhat.com>
Signed-off-by: NAlasdair G Kergon <agk@redhat.com>
上级 60f355ea
...@@ -69,6 +69,7 @@ struct mirror_set { ...@@ -69,6 +69,7 @@ struct mirror_set {
region_t nr_regions; region_t nr_regions;
int in_sync; int in_sync;
int log_failure; int log_failure;
int leg_failure;
atomic_t suspend; atomic_t suspend;
atomic_t default_mirror; /* Default mirror */ atomic_t default_mirror; /* Default mirror */
...@@ -211,6 +212,8 @@ static void fail_mirror(struct mirror *m, enum dm_raid1_error error_type) ...@@ -211,6 +212,8 @@ static void fail_mirror(struct mirror *m, enum dm_raid1_error error_type)
struct mirror_set *ms = m->ms; struct mirror_set *ms = m->ms;
struct mirror *new; struct mirror *new;
ms->leg_failure = 1;
/* /*
* error_count is used for nothing more than a * error_count is used for nothing more than a
* simple way to tell if a device has encountered * 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,8 +737,12 @@ static void do_writes(struct mirror_set *ms, struct bio_list *writes)
dm_rh_delay(ms->rh, bio); dm_rh_delay(ms->rh, bio);
while ((bio = bio_list_pop(&nosync))) { while ((bio = bio_list_pop(&nosync))) {
map_bio(get_default_mirror(ms), bio); if (unlikely(ms->leg_failure) && errors_handled(ms))
generic_make_request(bio); hold_bio(ms, bio);
else {
map_bio(get_default_mirror(ms), bio);
generic_make_request(bio);
}
} }
} }
...@@ -848,6 +855,7 @@ static struct mirror_set *alloc_context(unsigned int nr_mirrors, ...@@ -848,6 +855,7 @@ static struct mirror_set *alloc_context(unsigned int nr_mirrors,
ms->nr_regions = dm_sector_div_up(ti->len, region_size); ms->nr_regions = dm_sector_div_up(ti->len, region_size);
ms->in_sync = 0; ms->in_sync = 0;
ms->log_failure = 0; ms->log_failure = 0;
ms->leg_failure = 0;
atomic_set(&ms->suspend, 0); atomic_set(&ms->suspend, 0);
atomic_set(&ms->default_mirror, DEFAULT_MIRROR); atomic_set(&ms->default_mirror, DEFAULT_MIRROR);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册