summaryrefslogtreecommitdiff
path: root/sys/dev/raidframe
diff options
context:
space:
mode:
authoroster <oster@NetBSD.org>2009-01-11 21:58:41 +0000
committeroster <oster@NetBSD.org>2009-01-11 21:58:41 +0000
commit6d132f42c6ad2f2ef285cac380c0e2a09d73866f (patch)
treef4263efd2be9e8e1a7e833e8fc55d1c84c3e7b0a /sys/dev/raidframe
parente9f0e59ad69076ba66ddd610e0095643726fb671 (diff)
Implement DIOCCACHESYNC for RAIDframe too.
Diffstat (limited to 'sys/dev/raidframe')
-rw-r--r--sys/dev/raidframe/rf_netbsdkintf.c55
1 files changed, 52 insertions, 3 deletions
diff --git a/sys/dev/raidframe/rf_netbsdkintf.c b/sys/dev/raidframe/rf_netbsdkintf.c
index e06bdc6ff37..f1c52a8edea 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.251 2008/11/18 14:29:55 ad Exp $ */
+/* $NetBSD: rf_netbsdkintf.c,v 1.252 2009/01/11 21:58:41 oster Exp $ */
/*-
* Copyright (c) 1996, 1997, 1998, 2008 The NetBSD Foundation, Inc.
* All rights reserved.
@@ -139,7 +139,7 @@
***********************************************************/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: rf_netbsdkintf.c,v 1.251 2008/11/18 14:29:55 ad Exp $");
+__KERNEL_RCSID(0, "$NetBSD: rf_netbsdkintf.c,v 1.252 2009/01/11 21:58:41 oster Exp $");
#ifdef _KERNEL_OPT
#include "opt_raid_autoconfig.h"
@@ -321,6 +321,7 @@ void rf_release_all_vps(RF_ConfigSet_t *);
void rf_cleanup_config_set(RF_ConfigSet_t *);
int rf_have_enough_components(RF_ConfigSet_t *);
int rf_auto_config_set(RF_ConfigSet_t *, int *);
+static int rf_sync_component_caches(RF_Raid_t *raidPtr);
static int raidautoconfig = 0; /* Debugging, mostly. Set to 0 to not
allow autoconfig to take place.
@@ -1047,6 +1048,7 @@ raidioctl(dev_t dev, u_long cmd, void *data, int flag, struct lwp *l)
case DIOCAWEDGE:
case DIOCDWEDGE:
case DIOCLWEDGES:
+ case DIOCCACHESYNC:
case RAIDFRAME_SHUTDOWN:
case RAIDFRAME_REWRITEPARITY:
case RAIDFRAME_GET_INFO:
@@ -1818,7 +1820,8 @@ raidioctl(dev_t dev, u_long cmd, void *data, int flag, struct lwp *l)
case DIOCLWEDGES:
return dkwedge_list(&rs->sc_dkdev,
(struct dkwedge_list *)data, l);
-
+ case DIOCCACHESYNC:
+ return rf_sync_component_caches(raidPtr);
default:
retcode = ENOTTY;
}
@@ -3645,3 +3648,49 @@ rf_set_properties(struct raid_softc *rs, RF_Raid_t *raidPtr)
if (odisk_info)
prop_object_release(odisk_info);
}
+
+/*
+ * Implement forwarding of the DIOCCACHESYNC ioctl to each of the components.
+ * We end up returning whatever error was returned by the first cache flush
+ * that fails.
+ */
+
+static int
+rf_sync_component_caches(RF_Raid_t *raidPtr)
+{
+ int c, sparecol;
+ int e,error;
+ int force = 1;
+
+ error = 0;
+ for (c = 0; c < raidPtr->numCol; c++) {
+ if (raidPtr->Disks[c].status == rf_ds_optimal) {
+ e = VOP_IOCTL(raidPtr->raid_cinfo[c].ci_vp, DIOCCACHESYNC,
+ &force, FWRITE, NOCRED);
+ if (e) {
+ printf("raid%d: cache flush to component %s failed.\n",
+ raidPtr->raidid, raidPtr->Disks[c].devname);
+ if (error == 0) {
+ error = e;
+ }
+ }
+ }
+ }
+
+ for( c = 0; c < raidPtr->numSpare ; c++) {
+ sparecol = raidPtr->numCol + c;
+ /* Need to ensure that the reconstruct actually completed! */
+ if (raidPtr->Disks[sparecol].status == rf_ds_used_spare) {
+ e = VOP_IOCTL(raidPtr->raid_cinfo[sparecol].ci_vp,
+ DIOCCACHESYNC, &force, FWRITE, NOCRED);
+ if (e) {
+ printf("raid%d: cache flush to component %s failed.\n",
+ raidPtr->raidid, raidPtr->Disks[sparecol].devname);
+ if (error == 0) {
+ error = e;
+ }
+ }
+ }
+ }
+ return error;
+}