Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/dev/raidframe - Fix the FAIL_DISK handling (it would pro...
details: https://anonhg.NetBSD.org/src/rev/451106e8a6a2
branches: trunk
changeset: 448598:451106e8a6a2
user: christos <christos%NetBSD.org@localhost>
date: Tue Feb 05 17:13:37 2019 +0000
description:
- Fix the FAIL_DISK handling (it would prolly trash the wrong disk before
since the request structs are different and the row in the old struct is
the col in the new one).
- Restructure the way compat modules are loaded so that we only load them
for the ioctls that need them. Put a comment explaining why...
- Set retcode after loading compat (now that the fail disk passthrough
hack is gone), so that various ioctls don't always fail.
diffstat:
sys/dev/raidframe/rf_compat80.c | 21 +-
sys/dev/raidframe/rf_netbsd.h | 4 +-
sys/dev/raidframe/rf_netbsdkintf.c | 320 ++++++++++++++++++++----------------
3 files changed, 193 insertions(+), 152 deletions(-)
diffs (truncated from 480 to 300 lines):
diff -r a3697a04ebb8 -r 451106e8a6a2 sys/dev/raidframe/rf_compat80.c
--- a/sys/dev/raidframe/rf_compat80.c Tue Feb 05 17:03:10 2019 +0000
+++ b/sys/dev/raidframe/rf_compat80.c Tue Feb 05 17:13:37 2019 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: rf_compat80.c,v 1.8 2019/02/03 08:02:24 pgoyette Exp $ */
+/* $NetBSD: rf_compat80.c,v 1.9 2019/02/05 17:13:37 christos Exp $ */
/*
* Copyright (c) 2017 Matthew R. Green
@@ -222,6 +222,16 @@
return 0;
}
+static int
+rf_fail_disk80(RF_Raid_t *raidPtr, struct rf_recon_req80 *req80)
+{
+ struct rf_recon_req req = {
+ .col = req80.col,
+ .flags = req80.flags,
+ };
+ return rf_fail_disk(raidPtr, &req);
+}
+
int
raidframe_ioctl_80(u_long cmd, int initted, RF_Raid_t *raidPtr, int unit,
void *data, RF_Config_t **k_cfg)
@@ -238,9 +248,8 @@
return ENXIO;
break;
case RAIDFRAME_CONFIGURE80:
+ case RAIDFRAME_FAIL_DISK80:
break;
- case RAIDFRAME_FAIL_DISK80:
- return EPASSTHROUGH;
default:
return EPASSTHROUGH;
}
@@ -261,8 +270,12 @@
if (error != 0)
return error;
return EAGAIN; /* flag mainline to call generic config */
+ case RAIDFRAME_FAIL_DISK80:
+ return rf_fail_disk80(raidPtr, data);
+ default:
+ /* abort really */
+ return EPASSTHROUGH;
}
- return EPASSTHROUGH;
}
static void
diff -r a3697a04ebb8 -r 451106e8a6a2 sys/dev/raidframe/rf_netbsd.h
--- a/sys/dev/raidframe/rf_netbsd.h Tue Feb 05 17:03:10 2019 +0000
+++ b/sys/dev/raidframe/rf_netbsd.h Tue Feb 05 17:13:37 2019 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: rf_netbsd.h,v 1.30 2013/04/27 21:18:42 christos Exp $ */
+/* $NetBSD: rf_netbsd.h,v 1.31 2019/02/05 17:13:37 christos Exp $ */
/*-
* Copyright (c) 1996, 1997, 1998 The NetBSD Foundation, Inc.
@@ -103,4 +103,6 @@
struct RF_ConfigSet_s *next;
} RF_ConfigSet_t;
+int rf_fail_disk(RF_Raid_t *, struct rf_recon_req *);
+
#endif /* _RF__RF_NETBSDSTUFF_H_ */
diff -r a3697a04ebb8 -r 451106e8a6a2 sys/dev/raidframe/rf_netbsdkintf.c
--- a/sys/dev/raidframe/rf_netbsdkintf.c Tue Feb 05 17:03:10 2019 +0000
+++ b/sys/dev/raidframe/rf_netbsdkintf.c Tue Feb 05 17:13:37 2019 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: rf_netbsdkintf.c,v 1.365 2019/02/05 09:45:38 mrg Exp $ */
+/* $NetBSD: rf_netbsdkintf.c,v 1.366 2019/02/05 17:13:37 christos 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.365 2019/02/05 09:45:38 mrg Exp $");
+__KERNEL_RCSID(0, "$NetBSD: rf_netbsdkintf.c,v 1.366 2019/02/05 17:13:37 christos Exp $");
#ifdef _KERNEL_OPT
#include "opt_raid_autoconfig.h"
@@ -149,6 +149,7 @@
#include "rf_parityscan.h"
#include "rf_threadstuff.h"
+#include "rf_compat50.h"
#include "rf_compat80.h"
#ifdef COMPAT_NETBSD32
@@ -1049,6 +1050,145 @@
return 0;
}
+static bool
+rf_must_be_initialized(const struct raid_softc *rs, u_long cmd)
+{
+ switch (cmd) {
+ case RAIDFRAME_ADD_HOT_SPARE:
+ case RAIDFRAME_CHECK_COPYBACK_STATUS:
+ case RAIDFRAME_CHECK_COPYBACK_STATUS_EXT:
+ case RAIDFRAME_CHECK_COPYBACK_STATUS_EXT80:
+ case RAIDFRAME_CHECK_PARITY:
+ case RAIDFRAME_CHECK_PARITYREWRITE_STATUS:
+ case RAIDFRAME_CHECK_PARITYREWRITE_STATUS_EXT:
+ case RAIDFRAME_CHECK_PARITYREWRITE_STATUS_EXT80:
+ case RAIDFRAME_CHECK_RECON_STATUS:
+ case RAIDFRAME_CHECK_RECON_STATUS_EXT:
+ case RAIDFRAME_CHECK_RECON_STATUS_EXT80:
+ case RAIDFRAME_COPYBACK:
+ case RAIDFRAME_DELETE_COMPONENT:
+ case RAIDFRAME_FAIL_DISK:
+ case RAIDFRAME_FAIL_DISK80:
+ case RAIDFRAME_GET_ACCTOTALS:
+ case RAIDFRAME_GET_COMPONENT_LABEL:
+ case RAIDFRAME_GET_COMPONENT_LABEL80:
+ case RAIDFRAME_GET_INFO:
+#ifdef RAID_COMPAT32
+ case RAIDFRAME_GET_INFO32:
+#endif
+ case RAIDFRAME_GET_INFO50:
+ case RAIDFRAME_GET_INFO80:
+ case RAIDFRAME_GET_SIZE:
+ case RAIDFRAME_INCORPORATE_HOT_SPARE:
+ case RAIDFRAME_INIT_LABELS:
+ case RAIDFRAME_KEEP_ACCTOTALS:
+ case RAIDFRAME_PARITYMAP_GET_DISABLE:
+ case RAIDFRAME_PARITYMAP_SET_DISABLE:
+ case RAIDFRAME_PARITYMAP_SET_PARAMS:
+ case RAIDFRAME_PARITYMAP_STATUS:
+ case RAIDFRAME_REBUILD_IN_PLACE:
+ case RAIDFRAME_REMOVE_HOT_SPARE:
+ case RAIDFRAME_RESET_ACCTOTALS:
+ case RAIDFRAME_REWRITEPARITY:
+ case RAIDFRAME_SET_AUTOCONFIG:
+ case RAIDFRAME_SET_COMPONENT_LABEL:
+ case RAIDFRAME_SET_ROOT:
+ return (rs->sc_flags & RAIDF_INITED) != 0;
+ }
+ return false;
+}
+
+/*
+ * Really this should be done as part of the default in the ioctl
+ * switch like other compat code, but it is too messy to do that
+ * right now, so we list all the compat ioctls we know about,
+ * and load appropriately.
+ *
+ * XXX[1] what about combinations of compat32 and compat80 ioctls?
+ * XXX[2] what about autoloading the compat32 code? Is there a compat32
+ * ioctl module? Should there be one?
+ */
+static int
+rf_handle_compat(struct raid_softc *rs, int unit, u_long cmd, void *data,
+ RF_Config_t **k_cfg)
+{
+ RF_Raid_t *raidPtr = &rs->sc_r;
+ int retcode = EPASSTHROUGH;
+ switch (cmd) {
+ case RAIDFRAME_CHECK_COPYBACK_STATUS_EXT80:
+ case RAIDFRAME_CHECK_PARITYREWRITE_STATUS_EXT80:
+ case RAIDFRAME_CHECK_RECON_STATUS_EXT80:
+ case RAIDFRAME_CONFIGURE80:
+ case RAIDFRAME_FAIL_DISK80:
+ case RAIDFRAME_GET_COMPONENT_LABEL80:
+ case RAIDFRAME_GET_INFO80:
+ module_autoload("compat_raid_80", MODULE_CLASS_EXEC);
+ MODULE_CALL_HOOK(raidframe_ioctl_80_hook, (cmd,
+ (rs->sc_flags & RAIDF_INITED), raidPtr, unit, data, k_cfg),
+ enosys(), retcode);
+ break;
+ case RAIDFRAME_CONFIGURE50:
+ case RAIDFRAME_GET_INFO50:
+ module_autoload("compat_raid_50", MODULE_CLASS_EXEC);
+ MODULE_CALL_HOOK(raidframe_ioctl_50_hook, (cmd,
+ (rs->sc_flags & RAIDF_INITED), raidPtr, unit, data, k_cfg),
+ enosys(), retcode);
+ break;
+ default:
+ break;
+ }
+ return retcode;
+}
+
+int
+rf_fail_disk(RF_Raid_t *raidPtr, struct rf_recon_req *rr)
+{
+ struct rf_recon_req_internal *rrint;
+
+ if (raidPtr->Layout.map->faultsTolerated == 0) {
+ /* Can't do this on a RAID 0!! */
+ return EINVAL;
+ }
+
+ if (rr->col < 0 || rr->col >= raidPtr->numCol) {
+ /* bad column */
+ return EINVAL;
+ }
+
+ rf_lock_mutex2(raidPtr->mutex);
+ if (raidPtr->status == rf_rs_reconstructing) {
+ /* you can't fail a disk while we're reconstructing! */
+ /* XXX wrong for RAID6 */
+ goto out;
+ }
+ if ((raidPtr->Disks[rr->col].status == rf_ds_optimal) &&
+ (raidPtr->numFailures > 0)) {
+ /* some other component has failed. Let's not make
+ things worse. XXX wrong for RAID6 */
+ goto out;
+ }
+ if (raidPtr->Disks[rr->col].status == rf_ds_spared) {
+ /* Can't fail a spared disk! */
+ goto out;
+ }
+ rf_unlock_mutex2(raidPtr->mutex);
+
+ /* make a copy of the recon request so that we don't rely on
+ * the user's buffer */
+ RF_Malloc(rrint, sizeof(*rrint), (struct rf_recon_req_internal *));
+ if (rrint == NULL)
+ return(ENOMEM);
+ rrint->col = rr->col;
+ rrint->flags = rr->flags;
+ rrint->raidPtr = raidPtr;
+
+ return RF_CREATE_THREAD(raidPtr->recon_thread, rf_ReconThread,
+ rrint, "raid_recon");
+out:
+ rf_unlock_mutex2(raidPtr->mutex);
+ return EINVAL;
+}
+
static int
raidioctl(dev_t dev, u_long cmd, void *data, int flag, struct lwp *l)
{
@@ -1061,12 +1201,11 @@
RF_Raid_t *raidPtr;
RF_RaidDisk_t *diskPtr;
RF_AccTotals_t *totals;
- RF_DeviceConfig_t *d_cfg, *ucfgp;
+ RF_DeviceConfig_t *d_cfg, *ucfgp = data;
u_char *specific_buf;
int retcode = 0;
int column;
/* int raidid; */
- struct rf_recon_req *rr;
struct rf_recon_req_internal *rrint;
RF_ComponentLabel_t *clabel;
RF_ComponentLabel_t *ci_label;
@@ -1076,100 +1215,38 @@
if ((rs = raidget(unit, false)) == NULL)
return ENXIO;
+
dksc = &rs->sc_dksc;
raidPtr = &rs->sc_r;
db1_printf(("raidioctl: %d %d %d %lu\n", (int) dev,
- (int) DISKPART(dev), (int) unit, cmd));
+ (int) DISKPART(dev), (int) unit, cmd));
/* Must be initialized for these... */
- switch (cmd) {
- case RAIDFRAME_REWRITEPARITY:
- case RAIDFRAME_GET_INFO:
- case RAIDFRAME_RESET_ACCTOTALS:
- case RAIDFRAME_GET_ACCTOTALS:
- case RAIDFRAME_KEEP_ACCTOTALS:
- case RAIDFRAME_GET_SIZE:
- case RAIDFRAME_FAIL_DISK:
- case RAIDFRAME_COPYBACK:
- case RAIDFRAME_CHECK_RECON_STATUS:
- case RAIDFRAME_CHECK_RECON_STATUS_EXT:
- case RAIDFRAME_GET_COMPONENT_LABEL:
- case RAIDFRAME_SET_COMPONENT_LABEL:
- case RAIDFRAME_ADD_HOT_SPARE:
- case RAIDFRAME_REMOVE_HOT_SPARE:
- case RAIDFRAME_INIT_LABELS:
- case RAIDFRAME_REBUILD_IN_PLACE:
- case RAIDFRAME_CHECK_PARITY:
- case RAIDFRAME_CHECK_PARITYREWRITE_STATUS:
- case RAIDFRAME_CHECK_PARITYREWRITE_STATUS_EXT:
- case RAIDFRAME_CHECK_COPYBACK_STATUS:
- case RAIDFRAME_CHECK_COPYBACK_STATUS_EXT:
- case RAIDFRAME_SET_AUTOCONFIG:
- case RAIDFRAME_SET_ROOT:
- case RAIDFRAME_DELETE_COMPONENT:
- case RAIDFRAME_INCORPORATE_HOT_SPARE:
- case RAIDFRAME_PARITYMAP_STATUS:
- case RAIDFRAME_PARITYMAP_GET_DISABLE:
- case RAIDFRAME_PARITYMAP_SET_DISABLE:
- case RAIDFRAME_PARITYMAP_SET_PARAMS:
-#ifdef RAID_COMPAT32
- case RAIDFRAME_GET_INFO32:
-#endif
- if ((rs->sc_flags & RAIDF_INITED) == 0)
Home |
Main Index |
Thread Index |
Old Index