diff options
| author | jdolecek <jdolecek@NetBSD.org> | 2017-04-05 19:40:26 +0000 |
|---|---|---|
| committer | jdolecek <jdolecek@NetBSD.org> | 2017-04-05 19:40:26 +0000 |
| commit | cc023536cfc218717969f339a6fd93f2f1ac8c5c (patch) | |
| tree | 67058d28d38f0330cab3e866eb1bfdf2617425d9 /sys/dev/raidframe | |
| parent | be1b8f2ff6527c5f2847bcdce62371a14d0b2156 (diff) | |
add support for DIOCGCACHE; contrary to DIOCCACHESYNC, query any non-dead
disk in the set, even currently reconstring one
Diffstat (limited to 'sys/dev/raidframe')
| -rw-r--r-- | sys/dev/raidframe/rf_netbsdkintf.c | 53 |
1 files changed, 51 insertions, 2 deletions
diff --git a/sys/dev/raidframe/rf_netbsdkintf.c b/sys/dev/raidframe/rf_netbsdkintf.c index b6651b7df7c..e9149880914 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.347 2016/09/19 23:37:10 jdolecek Exp $ */ +/* $NetBSD: rf_netbsdkintf.c,v 1.348 2017/04/05 19:40:26 jdolecek Exp $ */ /*- * Copyright (c) 1996, 1997, 1998, 2008-2011 The NetBSD Foundation, Inc. @@ -101,7 +101,7 @@ ***********************************************************/ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: rf_netbsdkintf.c,v 1.347 2016/09/19 23:37:10 jdolecek Exp $"); +__KERNEL_RCSID(0, "$NetBSD: rf_netbsdkintf.c,v 1.348 2017/04/05 19:40:26 jdolecek Exp $"); #ifdef _KERNEL_OPT #include "opt_compat_netbsd.h" @@ -188,6 +188,7 @@ static void InitBP(struct buf *, struct vnode *, unsigned, struct raid_softc; static void raidinit(struct raid_softc *); static int raiddoaccess(RF_Raid_t *raidPtr, struct buf *bp); +static int rf_get_component_caches(RF_Raid_t *raidPtr, int *); static int raid_match(device_t, cfdata_t, void *); static void raid_attach(device_t, device_t, void *); @@ -1787,6 +1788,10 @@ raidioctl(dev_t dev, u_long cmd, void *data, int flag, struct lwp *l) */ switch (cmd) { + case DIOCGCACHE: + retcode = rf_get_component_caches(raidPtr, (int *)data); + break; + case DIOCCACHESYNC: retcode = rf_sync_component_caches(raidPtr); break; @@ -3679,6 +3684,50 @@ rf_set_geometry(struct raid_softc *rs, RF_Raid_t *raidPtr) disk_set_info(dksc->sc_dev, &dksc->sc_dkdev, NULL); } +/* + * Get cache info for all the components (including spares). + * Returns intersection of all the cache flags of all disks, or first + * error if any encountered. + * XXXfua feature flags can change as spares are added - lock down somehow + */ +static int +rf_get_component_caches(RF_Raid_t *raidPtr, int *data) +{ + int c; + int error; + int dkwhole = 0, dkpart; + + for (c = 0; c < raidPtr->numCol + raidPtr->numSpare; c++) { + /* + * Check any non-dead disk, even when currently being + * reconstructed. + */ + if (!RF_DEAD_DISK(raidPtr->Disks[c].status) + || raidPtr->Disks[c].status == rf_ds_reconstructing) { + error = VOP_IOCTL(raidPtr->raid_cinfo[c].ci_vp, + DIOCGCACHE, &dkpart, FREAD, NOCRED); + if (error) { + if (error != ENODEV) { + printf("raid%d: get cache for component %s failed\n", + raidPtr->raidid, + raidPtr->Disks[c].devname); + } + + return error; + } + + if (c == 0) + dkwhole = dkpart; + else + dkwhole = DKCACHE_COMBINE(dkwhole, dkpart); + } + } + + *data = (dkwhole >= 0) ? dkwhole : 0; + + return 0; +} + /* * Implement forwarding of the DIOCCACHESYNC ioctl to each of the components. * We end up returning whatever error was returned by the first cache flush |
