summaryrefslogtreecommitdiff
path: root/sys/dev/raidframe
diff options
context:
space:
mode:
authoroster <oster@NetBSD.org>2004-03-21 21:08:08 +0000
committeroster <oster@NetBSD.org>2004-03-21 21:08:08 +0000
commit78d093eaf5d9a402eb0dbcfc0cb6e40d5d4a957a (patch)
tree56bd534921db59871fb0e08ba465252b56aba133 /sys/dev/raidframe
parent05f998d8c67e5d4415ee053b82639df2b31442c1 (diff)
Yesterday's fix to rf_disks.c (rev 1.51) was necessary, but not
sufficient to clobber this nasty little bug. The behaviour observed was a panic when doing a 'raidctl -f' on a component when DAGs were in flight for the given RAID set. Unfortunatly, the faulty behaviour was very intermittent, and it was difficult to not only reliably reproduce the bug (nor determine when it was fixed!) but also to even figure out what might be the cause of the problem. The real issue was that ci_vp for the failed component was being set to NULL in rf_FailDisk(), but with DAGs still in flight, some of them were still expecting to use ci_vp to determine where to read to/write from! The fix is to call rf_SuspendNewRequestsAndWait() from rf_FailDisk() to make sure the RAID set is quiet and all IOs have completed before mucking with ci_vp and other data structures. rf_ResumeNewRequests() is then used to continue on as usual.
Diffstat (limited to 'sys/dev/raidframe')
-rw-r--r--sys/dev/raidframe/rf_driver.c15
1 files changed, 13 insertions, 2 deletions
diff --git a/sys/dev/raidframe/rf_driver.c b/sys/dev/raidframe/rf_driver.c
index 7de64e881ae..c341d232d0e 100644
--- a/sys/dev/raidframe/rf_driver.c
+++ b/sys/dev/raidframe/rf_driver.c
@@ -1,4 +1,4 @@
-/* $NetBSD: rf_driver.c,v 1.97 2004/03/20 04:22:05 oster Exp $ */
+/* $NetBSD: rf_driver.c,v 1.98 2004/03/21 21:08:08 oster Exp $ */
/*-
* Copyright (c) 1999 The NetBSD Foundation, Inc.
* All rights reserved.
@@ -73,7 +73,7 @@
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: rf_driver.c,v 1.97 2004/03/20 04:22:05 oster Exp $");
+__KERNEL_RCSID(0, "$NetBSD: rf_driver.c,v 1.98 2004/03/21 21:08:08 oster Exp $");
#include "opt_raid_diagnostic.h"
@@ -619,6 +619,13 @@ rf_SetReconfiguredMode(RF_Raid_t *raidPtr, int col)
int
rf_FailDisk(RF_Raid_t *raidPtr, int fcol, int initRecon)
{
+
+ /* need to suspend IO's here -- if there are DAGs in flight
+ and we pull the rug out from under ci_vp, Bad Things
+ can happen. */
+
+ rf_SuspendNewRequestsAndWait(raidPtr);
+
RF_LOCK_MUTEX(raidPtr->mutex);
if (raidPtr->Disks[fcol].status != rf_ds_failed) {
/* must be failing something that is valid, or else it's
@@ -646,6 +653,10 @@ rf_FailDisk(RF_Raid_t *raidPtr, int fcol, int initRecon)
raidPtr->Disks[fcol].auto_configured = 0;
RF_UNLOCK_MUTEX(raidPtr->mutex);
+ /* now we can allow IO to continue -- we'll be suspending it
+ again in rf_ReconstructFailedDisk() if we have to.. */
+
+ rf_ResumeNewRequests(raidPtr);
if (initRecon)
rf_ReconstructFailedDisk(raidPtr, fcol);