summaryrefslogtreecommitdiff
path: root/sys/dev/raidframe/rf_paritymap.c
diff options
context:
space:
mode:
authoroster <oster@NetBSD.org>2010-03-03 14:23:27 +0000
committeroster <oster@NetBSD.org>2010-03-03 14:23:27 +0000
commit0134fbe7d01a48d47e3618fdddeeb3284c4cb2cf (patch)
treef6e3af921fa7629fabdc9f39fe1dcd17c3d5ce7b /sys/dev/raidframe/rf_paritymap.c
parent8a20bde1e6e24b38b857a09a0556e74f0f562ab5 (diff)
Don't attempt to read or write component label stuff from/to 'dead disks'.
Update used spares with the correct parity map bits too. Addresses PR#42904 by Louis Guillaume. Fix confirmed by submitter. Thanks!
Diffstat (limited to 'sys/dev/raidframe/rf_paritymap.c')
-rw-r--r--sys/dev/raidframe/rf_paritymap.c56
1 files changed, 52 insertions, 4 deletions
diff --git a/sys/dev/raidframe/rf_paritymap.c b/sys/dev/raidframe/rf_paritymap.c
index b4c6aaeccb4..c5e4d3966a0 100644
--- a/sys/dev/raidframe/rf_paritymap.c
+++ b/sys/dev/raidframe/rf_paritymap.c
@@ -1,4 +1,4 @@
-/* $NetBSD: rf_paritymap.c,v 1.3 2009/11/26 07:35:39 pooka Exp $ */
+/* $NetBSD: rf_paritymap.c,v 1.4 2010/03/03 14:23:27 oster Exp $ */
/*-
* Copyright (c) 2009 Jed Davis.
@@ -27,7 +27,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: rf_paritymap.c,v 1.3 2009/11/26 07:35:39 pooka Exp $");
+__KERNEL_RCSID(0, "$NetBSD: rf_paritymap.c,v 1.4 2010/03/03 14:23:27 oster Exp $");
#include <sys/param.h>
#include <sys/callout.h>
@@ -359,12 +359,31 @@ rf_paritymap_set_params(struct rf_paritymap *pm,
if (todisk) {
raidPtr = pm->raid;
for (col = 0; col < raidPtr->numCol; col++) {
+ if (RF_DEAD_DISK(raidPtr->Disks[col].status))
+ continue;
+
clabel = raidget_component_label(raidPtr, col);
clabel->parity_map_ntick = cooldown;
clabel->parity_map_tickms = tickms;
clabel->parity_map_regions = regions;
+
+ /* Don't touch the disk if it's been spared */
+ if (clabel->status == rf_ds_spared)
+ continue;
+
raidflush_component_label(raidPtr, col);
}
+
+ /* handle the spares too... */
+ for (col = 0; col < raidPtr->numSpare; col++) {
+ if (raidPtr->Disks[raidPtr->numCol+col].status == rf_ds_used_spare) {
+ clabel = raidget_component_label(raidPtr, raidPtr->numCol+col);
+ clabel->parity_map_ntick = cooldown;
+ clabel->parity_map_tickms = tickms;
+ clabel->parity_map_regions = regions;
+ raidflush_component_label(raidPtr, raidPtr->numCol+col);
+ }
+ }
}
return 0;
}
@@ -603,6 +622,8 @@ rf_paritymap_attach(RF_Raid_t *raidPtr, int force)
*/
if (!force) {
for (col = 0; col < raidPtr->numCol; col++) {
+ if (RF_DEAD_DISK(raidPtr->Disks[col].status))
+ continue;
clabel = raidget_component_label(raidPtr, col);
flags = clabel->parity_map_flags;
/* Check for use by non-parity-map kernel. */
@@ -670,6 +691,8 @@ rf_paritymap_attach(RF_Raid_t *raidPtr, int force)
/* Alter labels in-core to reflect the current view of things. */
for (col = 0; col < raidPtr->numCol; col++) {
+ if (RF_DEAD_DISK(raidPtr->Disks[col].status))
+ continue;
clabel = raidget_component_label(raidPtr, col);
if (pm_use)
@@ -683,12 +706,13 @@ rf_paritymap_attach(RF_Raid_t *raidPtr, int force)
clabel->parity_map_regions = g_regions;
raidflush_component_label(raidPtr, col);
}
+ /* Note that we're just in 'attach' here, and there won't
+ be any spare disks at this point. */
}
/*
* For initializing the parity-map fields of a component label, both on
- * initial creation and on reconstruct/copyback/etc.
- */
+ * initial creation and on reconstruct/copyback/etc. */
void
rf_paritymap_init_label(struct rf_paritymap *pm, RF_ComponentLabel_t *clabel)
{
@@ -724,10 +748,19 @@ rf_paritymap_get_disable(RF_Raid_t *raidPtr)
dis = 0;
for (col = 0; col < raidPtr->numCol; col++) {
+ if (RF_DEAD_DISK(raidPtr->Disks[col].status))
+ continue;
clabel = raidget_component_label(raidPtr, col);
if (clabel->parity_map_flags & RF_PMLABEL_DISABLE)
dis = 1;
}
+ for (col = 0; col < raidPtr->numSpare; col++) {
+ if (raidPtr->Disks[raidPtr->numCol+col].status != rf_ds_used_spare)
+ continue;
+ clabel = raidget_component_label(raidPtr, raidPtr->numCol+col);
+ if (clabel->parity_map_flags & RF_PMLABEL_DISABLE)
+ dis = 1;
+ }
return dis;
}
@@ -740,6 +773,8 @@ rf_paritymap_set_disable(RF_Raid_t *raidPtr, int dis)
RF_RowCol_t col;
for (col = 0; col < raidPtr->numCol; col++) {
+ if (RF_DEAD_DISK(raidPtr->Disks[col].status))
+ continue;
clabel = raidget_component_label(raidPtr, col);
if (dis)
clabel->parity_map_flags |= RF_PMLABEL_DISABLE;
@@ -747,4 +782,17 @@ rf_paritymap_set_disable(RF_Raid_t *raidPtr, int dis)
clabel->parity_map_flags &= ~RF_PMLABEL_DISABLE;
raidflush_component_label(raidPtr, col);
}
+
+ /* update any used spares as well */
+ for (col = 0; col < raidPtr->numSpare; col++) {
+ if (raidPtr->Disks[raidPtr->numCol+col].status != rf_ds_used_spare)
+ continue;
+
+ clabel = raidget_component_label(raidPtr, raidPtr->numCol+col);
+ if (dis)
+ clabel->parity_map_flags |= RF_PMLABEL_DISABLE;
+ else
+ clabel->parity_map_flags &= ~RF_PMLABEL_DISABLE;
+ raidflush_component_label(raidPtr, raidPtr->numCol+col);
+ }
}