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