summaryrefslogtreecommitdiffstats
path: root/drivers/md/dm-raid1.c
diff options
context:
space:
mode:
authorJonathan Brassow <jbrassow@redhat.com>2008-02-08 03:11:32 +0100
committerAlasdair G Kergon <agk@redhat.com>2008-02-08 03:11:32 +0100
commit8f0205b798f926e2745de5fdebf0a8605c621de6 (patch)
tree3b0efdd8b666e507c2c7987ce6477064c2d4cc56 /drivers/md/dm-raid1.c
parentdm raid1: handle write failures (diff)
downloadlinux-8f0205b798f926e2745de5fdebf0a8605c621de6.tar.xz
linux-8f0205b798f926e2745de5fdebf0a8605c621de6.zip
dm raid1: handle recovery failures
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>
Diffstat (limited to 'drivers/md/dm-raid1.c')
-rw-r--r--drivers/md/dm-raid1.c23
1 files changed, 20 insertions, 3 deletions
diff --git a/drivers/md/dm-raid1.c b/drivers/md/dm-raid1.c
index 4e1e04dbc4ab..9978b9f07fe9 100644
--- a/drivers/md/dm-raid1.c
+++ b/drivers/md/dm-raid1.c
@@ -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));
}