diff options
| author | oster <oster@NetBSD.org> | 2009-01-11 21:58:41 +0000 |
|---|---|---|
| committer | oster <oster@NetBSD.org> | 2009-01-11 21:58:41 +0000 |
| commit | 6d132f42c6ad2f2ef285cac380c0e2a09d73866f (patch) | |
| tree | f4263efd2be9e8e1a7e833e8fc55d1c84c3e7b0a /sys/dev/raidframe | |
| parent | e9f0e59ad69076ba66ddd610e0095643726fb671 (diff) | |
Implement DIOCCACHESYNC for RAIDframe too.
Diffstat (limited to 'sys/dev/raidframe')
| -rw-r--r-- | sys/dev/raidframe/rf_netbsdkintf.c | 55 |
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; +} |
