Skip to content

Commit

Permalink
dm raid1: handle log failure
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Jonathan Brassow authored and Linus Torvalds committed Jul 12, 2007
1 parent f44db67 commit fc1ff95
Showing 1 changed file with 8 additions and 4 deletions.
12 changes: 8 additions & 4 deletions drivers/md/dm-raid1.c
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,7 @@ struct mirror_set {
/* recovery */
region_t nr_regions;
int in_sync;
int log_failure;

struct mirror *default_mirror; /* Default mirror */

Expand Down Expand Up @@ -589,9 +590,9 @@ static void rh_recovery_end(struct region *reg, int success)
wake(rh->ms);
}

static void rh_flush(struct region_hash *rh)
static int rh_flush(struct region_hash *rh)
{
rh->log->type->flush(rh->log);
return rh->log->type->flush(rh->log);
}

static void rh_delay(struct region_hash *rh, struct bio *bio)
Expand Down Expand Up @@ -892,12 +893,15 @@ static void do_writes(struct mirror_set *ms, struct bio_list *writes)
*/
rh_inc_pending(&ms->rh, &sync);
rh_inc_pending(&ms->rh, &nosync);
rh_flush(&ms->rh);
ms->log_failure = rh_flush(&ms->rh) ? 1 : 0;

/*
* Dispatch io.
*/
while ((bio = bio_list_pop(&sync)))
if (unlikely(ms->log_failure))
while ((bio = bio_list_pop(&sync)))
bio_endio(bio, bio->bi_size, -EIO);
else while ((bio = bio_list_pop(&sync)))
do_write(ms, bio);

while ((bio = bio_list_pop(&recover)))
Expand Down

0 comments on commit fc1ff95

Please sign in to comment.