Gitweb:     
http://git.kernel.org/git/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=fc1ff9588a6d56258ff9576a31aa34f17757c666
Commit:     fc1ff9588a6d56258ff9576a31aa34f17757c666
Parent:     f44db678edcc6f4c2779ac43f63f0b9dfa28b724
Author:     Jonathan Brassow <[EMAIL PROTECTED]>
AuthorDate: Thu Jul 12 17:29:15 2007 +0100
Committer:  Linus Torvalds <[EMAIL PROTECTED]>
CommitDate: Thu Jul 12 15:01:08 2007 -0700

    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 <[EMAIL PROTECTED]>
    Signed-off-by: Alasdair G Kergon <[EMAIL PROTECTED]>
    Signed-off-by: Linus Torvalds <[EMAIL PROTECTED]>
---
 drivers/md/dm-raid1.c |   12 ++++++++----
 1 files changed, 8 insertions(+), 4 deletions(-)

diff --git a/drivers/md/dm-raid1.c b/drivers/md/dm-raid1.c
index dee4221..1a876f9 100644
--- a/drivers/md/dm-raid1.c
+++ b/drivers/md/dm-raid1.c
@@ -134,6 +134,7 @@ struct mirror_set {
        /* recovery */
        region_t nr_regions;
        int in_sync;
+       int log_failure;
 
        struct mirror *default_mirror;  /* Default mirror */
 
@@ -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)
@@ -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)))
-
To unsubscribe from this list: send the line "unsubscribe git-commits-head" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to