dm raid1: handle recovery failures
authorJonathan Brassow <jbrassow@redhat.com>
Fri, 8 Feb 2008 02:11:32 +0000 (02:11 +0000)
committerAlasdair G Kergon <agk@redhat.com>
Fri, 8 Feb 2008 02:11:32 +0000 (02:11 +0000)
This patch adds the calls to 'fail_mirror' if an error occurs during
mirror recovery (aka resynchronization).  'fail_mirror' is responsible
for recording the type of error by mirror device and ensuring an event
gets raised for the purpose of notifying userspace.

Signed-off-by: Jonathan Brassow <jbrassow@redhat.com>
Signed-off-by: Alasdair G Kergon <agk@redhat.com>
drivers/md/dm-raid1.c

index 4e1e04dbc4ab2684113ad03f2f21737aea5af45e..9978b9f07fe99db1e9d53dc2605c1d915f5d2206 100644 (file)
@@ -737,15 +737,32 @@ out:
 static void recovery_complete(int read_err, unsigned int write_err,
                              void *context)
 {
-       struct region *reg = (struct region *) context;
+       struct region *reg = (struct region *)context;
+       struct mirror_set *ms = reg->rh->ms;
+       int m, bit = 0;
 
-       if (read_err)
+       if (read_err) {
                /* Read error means the failure of default mirror. */
                DMERR_LIMIT("Unable to read primary mirror during recovery");
+               fail_mirror(get_default_mirror(ms), DM_RAID1_SYNC_ERROR);
+       }
 
-       if (write_err)
+       if (write_err) {
                DMERR_LIMIT("Write error during recovery (error = 0x%x)",
                            write_err);
+               /*
+                * Bits correspond to devices (excluding default mirror).
+                * The default mirror cannot change during recovery.
+                */
+               for (m = 0; m < ms->nr_mirrors; m++) {
+                       if (&ms->mirror[m] == get_default_mirror(ms))
+                               continue;
+                       if (test_bit(bit, &write_err))
+                               fail_mirror(ms->mirror + m,
+                                           DM_RAID1_SYNC_ERROR);
+                       bit++;
+               }
+       }
 
        rh_recovery_end(reg, !(read_err || write_err));
 }