summaryrefslogtreecommitdiff
path: root/sys/dev/raidframe
diff options
context:
space:
mode:
authoroster <oster@NetBSD.org>2002-11-14 17:11:54 +0000
committeroster <oster@NetBSD.org>2002-11-14 17:11:54 +0000
commit56f6918fef46a9dc69d9106144f4940a9f97275d (patch)
treea109c58d38c2f6f082a7e1e3716f0cb2db30f6a4 /sys/dev/raidframe
parent2388751cea96ac8a314aa7c216cebd8e18471d7d (diff)
rf_markalldirty() needs to update the mod_counter for used_spares too!
This bug appears as "incorrect Mod Counters" in 'raidctl -s'. The reason it was seen only in 'raidctl -s' is because of the conditions needed to trigger the bug: a) a raid set is configured b) no partitions on that set are mounted or are otherwise in-use c) a component is failed, and subsequently rebuilt to a hot spare d) the machine is rebooted while something (e.g. 'raidctl -s') has the device open (and, therefore, rf_markalldirty() has been called) but before the final rf_update_component_labels() is done. Needless to say, the window for this happening is *very* small, and it was only because I was testing some obscure stuff that I even noticed it.
Diffstat (limited to 'sys/dev/raidframe')
-rw-r--r--sys/dev/raidframe/rf_netbsdkintf.c73
1 files changed, 28 insertions, 45 deletions
diff --git a/sys/dev/raidframe/rf_netbsdkintf.c b/sys/dev/raidframe/rf_netbsdkintf.c
index 4ed607a67bb..60692ab8dfc 100644
--- a/sys/dev/raidframe/rf_netbsdkintf.c
+++ b/sys/dev/raidframe/rf_netbsdkintf.c
@@ -1,4 +1,4 @@
-/* $NetBSD: rf_netbsdkintf.c,v 1.145 2002/11/01 11:31:59 mrg Exp $ */
+/* $NetBSD: rf_netbsdkintf.c,v 1.146 2002/11/14 17:11:54 oster Exp $ */
/*-
* Copyright (c) 1996, 1997, 1998 The NetBSD Foundation, Inc.
* All rights reserved.
@@ -114,7 +114,7 @@
***********************************************************/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: rf_netbsdkintf.c,v 1.145 2002/11/01 11:31:59 mrg Exp $");
+__KERNEL_RCSID(0, "$NetBSD: rf_netbsdkintf.c,v 1.146 2002/11/14 17:11:54 oster Exp $");
#include <sys/param.h>
#include <sys/errno.h>
@@ -2306,7 +2306,10 @@ rf_markalldirty(raidPtr)
RF_Raid_t *raidPtr;
{
RF_ComponentLabel_t clabel;
+ int sparecol;
int r,c;
+ int i,j;
+ int srow, scol;
raidPtr->mod_counter++;
for (r = 0; r < raidPtr->numRow; r++) {
@@ -2323,33 +2326,18 @@ rf_markalldirty(raidPtr)
but whatever you do, don't
try to access it!! */
} else {
-#if 0
- clabel.status =
- raidPtr->Disks[r][c].status;
- raidwrite_component_label(
- raidPtr->Disks[r][c].dev,
- raidPtr->raid_cinfo[r][c].ci_vp,
- &clabel);
-#endif
- raidmarkdirty(
- raidPtr->Disks[r][c].dev,
- raidPtr->raid_cinfo[r][c].ci_vp,
- raidPtr->mod_counter);
+ raidmarkdirty(
+ raidPtr->Disks[r][c].dev,
+ raidPtr->raid_cinfo[r][c].ci_vp,
+ raidPtr->mod_counter);
}
}
}
}
- /* printf("Component labels marked dirty.\n"); */
-#if 0
+
for( c = 0; c < raidPtr->numSpare ; c++) {
sparecol = raidPtr->numCol + c;
- if (raidPtr->Disks[r][sparecol].status == rf_ds_used_spare) {
- /*
-
- XXX this is where we get fancy and map this spare
- into it's correct spot in the array.
-
- */
+ if (raidPtr->Disks[0][sparecol].status == rf_ds_used_spare) {
/*
we claim this disk is "optimal" if it's
@@ -2362,40 +2350,35 @@ rf_markalldirty(raidPtr)
for(i=0;i<raidPtr->numRow;i++) {
for(j=0;j<raidPtr->numCol;j++) {
if ((raidPtr->Disks[i][j].spareRow ==
- r) &&
+ 0) &&
(raidPtr->Disks[i][j].spareCol ==
sparecol)) {
- srow = r;
- scol = sparecol;
+ srow = i;
+ scol = j;
break;
}
}
}
-
+
raidread_component_label(
- raidPtr->Disks[r][sparecol].dev,
- raidPtr->raid_cinfo[r][sparecol].ci_vp,
- &clabel);
+ raidPtr->Disks[0][sparecol].dev,
+ raidPtr->raid_cinfo[0][sparecol].ci_vp,
+ &clabel);
/* make sure status is noted */
- clabel.version = RF_COMPONENT_LABEL_VERSION;
- clabel.mod_counter = raidPtr->mod_counter;
- clabel.serial_number = raidPtr->serial_number;
+
+ raid_init_component_label(raidPtr, &clabel);
+
clabel.row = srow;
clabel.column = scol;
- clabel.num_rows = raidPtr->numRow;
- clabel.num_columns = raidPtr->numCol;
- clabel.clean = RF_RAID_DIRTY; /* changed in a bit*/
- clabel.status = rf_ds_optimal;
- raidwrite_component_label(
- raidPtr->Disks[r][sparecol].dev,
- raidPtr->raid_cinfo[r][sparecol].ci_vp,
- &clabel);
- raidmarkclean( raidPtr->Disks[r][sparecol].dev,
- raidPtr->raid_cinfo[r][sparecol].ci_vp);
+ /* Note: we *don't* change status from rf_ds_used_spare
+ to rf_ds_optimal */
+ /* clabel.status = rf_ds_optimal; */
+
+ raidmarkdirty(raidPtr->Disks[0][sparecol].dev,
+ raidPtr->raid_cinfo[0][sparecol].ci_vp,
+ raidPtr->mod_counter);
}
}
-
-#endif
}