aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/md
diff options
context:
space:
mode:
authorJonathan Brassow <jbrassow@redhat.com>2007-07-12 12:29:15 -0400
committerLinus Torvalds <torvalds@woody.linux-foundation.org>2007-07-12 18:01:08 -0400
commitfc1ff9588a6d56258ff9576a31aa34f17757c666 (patch)
tree071fe0a07269c656448dc5dbe453eaa8e6f1a24a /drivers/md
parentf44db678edcc6f4c2779ac43f63f0b9dfa28b724 (diff)
dm raid1: handle log failure
When writing to a mirror, the log must be updated first. Failure to update the log could result in the log not properly reflecting the state of the mirror if the machine should crash. We change the return type of the rh_flush function to give us the ability to check if a log write was successful. If the log write was unsuccessful, we fail the writes to avoid the case where the log does not properly reflect the state of the mirror. A follow-up patch - which is dependent on the ability to requeue I/O's to core device-mapper - will requeue the I/O's for retry (allowing the mirror to be reconfigured.) Signed-off-by: Jonathan Brassow <jbrassow@redhat.com> Signed-off-by: Alasdair G Kergon <agk@redhat.com> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'drivers/md')
-rw-r--r--drivers/md/dm-raid1.c12
1 files changed, 8 insertions, 4 deletions
diff --git a/drivers/md/dm-raid1.c b/drivers/md/dm-raid1.c
index dee4221caa73..1a876f9965e0 100644
--- a/drivers/md/dm-raid1.c
+++ b/drivers/md/dm-raid1.c
@@ -134,6 +134,7 @@ struct mirror_set {
134 /* recovery */ 134 /* recovery */
135 region_t nr_regions; 135 region_t nr_regions;
136 int in_sync; 136 int in_sync;
137 int log_failure;
137 138
138 struct mirror *default_mirror; /* Default mirror */ 139 struct mirror *default_mirror; /* Default mirror */
139 140
@@ -589,9 +590,9 @@ static void rh_recovery_end(struct region *reg, int success)
589 wake(rh->ms); 590 wake(rh->ms);
590} 591}
591 592
592static void rh_flush(struct region_hash *rh) 593static int rh_flush(struct region_hash *rh)
593{ 594{
594 rh->log->type->flush(rh->log); 595 return rh->log->type->flush(rh->log);
595} 596}
596 597
597static void rh_delay(struct region_hash *rh, struct bio *bio) 598static void rh_delay(struct region_hash *rh, struct bio *bio)
@@ -892,12 +893,15 @@ static void do_writes(struct mirror_set *ms, struct bio_list *writes)
892 */ 893 */
893 rh_inc_pending(&ms->rh, &sync); 894 rh_inc_pending(&ms->rh, &sync);
894 rh_inc_pending(&ms->rh, &nosync); 895 rh_inc_pending(&ms->rh, &nosync);
895 rh_flush(&ms->rh); 896 ms->log_failure = rh_flush(&ms->rh) ? 1 : 0;
896 897
897 /* 898 /*
898 * Dispatch io. 899 * Dispatch io.
899 */ 900 */
900 while ((bio = bio_list_pop(&sync))) 901 if (unlikely(ms->log_failure))
902 while ((bio = bio_list_pop(&sync)))
903 bio_endio(bio, bio->bi_size, -EIO);
904 else while ((bio = bio_list_pop(&sync)))
901 do_write(ms, bio); 905 do_write(ms, bio);
902 906
903 while ((bio = bio_list_pop(&recover))) 907 while ((bio = bio_list_pop(&recover)))