- Redo all the ioctl compat stuff to use a standard "ioctl" interface,

and provide methods to the private softc
- Provide a function for constructing a RF_Raid_t from an RF_Config_t
- Factor out the big inline ioctl code into functions
This commit is contained in:
christos 2019-02-05 23:28:02 +00:00
parent b6d4a8b2d9
commit 728e0675b8
12 changed files with 547 additions and 641 deletions

View File

@ -1,4 +1,4 @@
/* $NetBSD: rf_compat32.c,v 1.2 2019/02/03 08:02:24 pgoyette Exp $ */
/* $NetBSD: rf_compat32.c,v 1.3 2019/02/05 23:28:02 christos Exp $ */
/*
* Copyright (c) 2017 Matthew R. Green
@ -38,6 +38,7 @@
#include <dev/raidframe/raidframevar.h>
#include "rf_raid.h"
#include "rf_kintf.h"
#include "rf_compat32.h"
#include <compat/netbsd32/netbsd32.h>
@ -77,58 +78,104 @@ typedef struct RF_Config_s32 {
indicate that configuration should not proceed without user
intervention
*/
} RF_Config_t32 ;
} RF_Config_t32;
int
rf_config_netbsd32(void *data, RF_Config_t *k_cfg)
static int
rf_config_netbsd32(struct raid_softc *rs, void *data)
{
RF_Config_t32 *u_cfg = NETBSD32PTR64(*(netbsd32_pointer_t *)data);
struct RF_Config_s32 *cfg32;
RF_Config_t32 *u_cfg32 = NETBSD32PTR64(*(netbsd32_pointer_t *)data);
RF_Config_t *k_cfg;
RF_Config_t32 *k_cfg32;
int rv;
RF_Malloc(cfg32, sizeof(RF_Config_t), (RF_Config_t32 *));
if (cfg32 == NULL)
return (ENOMEM);
RF_Malloc(k_cfg32, sizeof(RF_Config_t32), (RF_Config_t32 *));
if (k_cfg32 == NULL)
return ENOMEM;
rv = copyin(u_cfg, cfg32, sizeof(RF_Config_t32));
if (rv)
goto out;
rv = copyin(u_cfg32, k_cfg32, sizeof(RF_Config_t32));
if (rv) {
RF_Free(k_cfg32, sizeof(RF_Config_t32));
return ENOMEM;
}
k_cfg->numCol = cfg32->numCol;
k_cfg->numSpare = cfg32->numSpare;
memcpy(k_cfg->devs, cfg32->devs, sizeof(k_cfg->devs));
memcpy(k_cfg->devnames, cfg32->devnames, sizeof(k_cfg->devnames));
memcpy(k_cfg->spare_devs, cfg32->spare_devs, sizeof(k_cfg->spare_devs));
memcpy(k_cfg->spare_names, cfg32->spare_names, sizeof(k_cfg->spare_names));
k_cfg->sectPerSU = cfg32->sectPerSU;
k_cfg->SUsPerPU = cfg32->SUsPerPU;
k_cfg->SUsPerRU = cfg32->SUsPerRU;
k_cfg->parityConfig = cfg32->parityConfig;
memcpy(k_cfg->diskQueueType, cfg32->diskQueueType, sizeof(k_cfg->diskQueueType));
k_cfg->maxOutstandingDiskReqs = cfg32->maxOutstandingDiskReqs;
memcpy(k_cfg->debugVars, cfg32->debugVars, sizeof(k_cfg->debugVars));
k_cfg->layoutSpecificSize = cfg32->layoutSpecificSize;
k_cfg->layoutSpecific = NETBSD32PTR64(cfg32->layoutSpecific);
k_cfg->force = cfg32->force;
RF_Malloc(k_cfg, sizeof(RF_Config_t), (RF_Config_t *));
if (k_cfg == NULL) {
RF_Free(k_cfg32, sizeof(RF_Config_t32));
RF_Free(k_cfg, sizeof(RF_Config_t));
}
k_cfg->numCol = k_cfg32->numCol;
k_cfg->numSpare = k_cfg32->numSpare;
memcpy(k_cfg->devs, k_cfg32->devs, sizeof(k_cfg->devs));
memcpy(k_cfg->devnames, k_cfg32->devnames, sizeof(k_cfg->devnames));
memcpy(k_cfg->spare_devs, k_cfg32->spare_devs,
sizeof(k_cfg->spare_devs));
memcpy(k_cfg->spare_names, k_cfg32->spare_names,
sizeof(k_cfg->spare_names));
k_cfg->sectPerSU = k_cfg32->sectPerSU;
k_cfg->SUsPerPU = k_cfg32->SUsPerPU;
k_cfg->SUsPerRU = k_cfg32->SUsPerRU;
k_cfg->parityConfig = k_cfg32->parityConfig;
memcpy(k_cfg->diskQueueType, k_cfg32->diskQueueType,
sizeof(k_cfg->diskQueueType));
k_cfg->maxOutstandingDiskReqs = k_cfg32->maxOutstandingDiskReqs;
memcpy(k_cfg->debugVars, k_cfg32->debugVars, sizeof(k_cfg->debugVars));
k_cfg->layoutSpecificSize = k_cfg32->layoutSpecificSize;
k_cfg->layoutSpecific = NETBSD32PTR64(k_cfg32->layoutSpecific);
k_cfg->force = k_cfg32->force;
out:
RF_Free(cfg32, sizeof(RF_Config_t32));
return rv;
return rf_construct(rs, k_cfg);
}
static int
rf_get_info_netbsd32(RF_Raid_t *raidPtr, void *data)
{
int retcode;
void *ucfgp = NETBSD32PTR64(*(netbsd32_pointer_t *)data);
RF_DeviceConfig_t *d_cfg;
RF_Malloc(d_cfg, sizeof(RF_DeviceConfig_t), (RF_DeviceConfig_t *));
if (d_cfg == NULL)
return ENOMEM;
retcode = rf_get_info(raidPtr, d_cfg);
if (retcode == 0) {
retcode = copyout(d_cfg, ucfgp, sizeof(*d_cfg));
}
RF_Free(d_cfg, sizeof(RF_DeviceConfig_t));
return retcode;
}
static int
raidframe_netbsd32_ioctl(struct raid_softc *rs, u_long cmd, void *data)
{
RF_Raid_t *raidPtr = rf_get_raid(rs);
switch (cmd) {
case RAIDFRAME_GET_INFO32:
if (!rf_inited(rs) == 0)
return ENXIO;
return rf_get_info_netbsd32(raidPtr, data);
case RAIDFRAME_CONFIGURE32:
return rf_config_netbsd32(rs, data);
default:
return EPASSTHROUGH;
}
}
static void
raidframe_netbsd32_init(void)
{
MODULE_SET_HOOK(raidframe_netbsd32_config_hook, "raid32",
rf_config_netbsd32);
MODULE_SET_HOOK(raidframe_netbsd32_ioctl_hook, "raid32",
raidframe_netbsd32_ioctl);
}
static void
raidframe_netbsd32_fini(void)
{
MODULE_UNSET_HOOK(raidframe_netbsd32_config_hook);
MODULE_UNSET_HOOK(raidframe_netbsd32_ioctl_hook);
}
MODULE(MODULE_CLASS_EXEC, compat_netbsd32_raid, "raid,compat_netbsd32");

View File

@ -1,4 +1,4 @@
/* $NetBSD: rf_compat32.h,v 1.2 2018/01/20 01:32:45 mrg Exp $ */
/* $NetBSD: rf_compat32.h,v 1.3 2019/02/05 23:28:02 christos Exp $ */
/*
* Copyright (c) 2017 Matthew R. Green
@ -36,6 +36,4 @@
#define RAIDFRAME_CONFIGURE32 _IOW ('r', 43, netbsd32_pointer_t) /* configure the driver */
#define RAIDFRAME_GET_INFO32 _IOWR('r', 42, netbsd32_pointer_t) /* get configuration */
int rf_config_netbsd32(void *data, RF_Config_t *k_cfg);
#endif /* _RF_NETBSD32_H_ */

View File

@ -1,4 +1,4 @@
/* $NetBSD: rf_compat50.c,v 1.7 2019/02/03 08:02:24 pgoyette Exp $ */
/* $NetBSD: rf_compat50.c,v 1.8 2019/02/05 23:28:02 christos Exp $ */
/*-
* Copyright (c) 2009 The NetBSD Foundation, Inc.
@ -48,7 +48,6 @@
#include "rf_raid.h"
#include "rf_compat50.h"
#include "rf_compat50_mod.h"
#include "rf_debugMem.h"
typedef struct RF_Config50_s {
@ -105,17 +104,18 @@ rf_disk_to_disk50(RF_RaidDisk50_t *d50, const RF_RaidDisk_t *d)
d50->dev = d->dev;
}
int
rf_config50(RF_Raid_t *raidPtr, int unit, void *data, RF_Config_t **k_cfgp)
static int
rf_config50(struct raid_softc *rs, void *data)
{
RF_Config50_t *u50_cfg, *k50_cfg;
RF_Config_t *k_cfg;
RF_Raid_t *raidPtr = rf_get_raid(rs);
size_t i, j;
int error;
if (raidPtr->valid) {
/* There is a valid RAID set running on this unit! */
printf("raid%d: Device already configured!\n", unit);
printf("raid%d: Device already configured!\n", rf_get_unit(rs));
return EINVAL;
}
@ -172,11 +172,10 @@ rf_config50(RF_Raid_t *raidPtr, int unit, void *data, RF_Config_t **k_cfgp)
k_cfg->force = k50_cfg->force;
RF_Free(k50_cfg, sizeof(RF_Config50_t));
*k_cfgp = k_cfg;
return 0;
return rf_construct(rs, k_cfg);
}
int
static int
rf_get_info50(RF_Raid_t *raidPtr, void *data)
{
RF_DeviceConfig50_t **ucfgp = data, *d_cfg;
@ -219,25 +218,22 @@ out:
return error;
}
int
raidframe_ioctl_50(u_long cmd, int initted, RF_Raid_t *raidPtr, int unit,
void *data, RF_Config_t **k_cfg)
static int
raidframe_ioctl_50(struct raid_softc *rs, u_long cmd, void *data)
{
int error;
RF_Raid_t *raidPtr = rf_get_raid(rs);
switch (cmd) {
case RAIDFRAME_GET_INFO50:
if (initted == 0)
if (!rf_inited(rs))
return ENXIO;
return rf_get_info50(raidPtr, data);
case RAIDFRAME_CONFIGURE50:
error = rf_config50(raidPtr, unit, data, k_cfg);
if (error != 0)
return error;
return EAGAIN; /* flag mainline to call generic config */
return rf_config50(rs, data);
default:
return EPASSTHROUGH;
}
return EPASSTHROUGH;
}
static void

View File

@ -1,4 +1,4 @@
/* $NetBSD: rf_compat50.h,v 1.4 2019/01/31 12:31:50 christos Exp $ */
/* $NetBSD: rf_compat50.h,v 1.5 2019/02/05 23:28:02 christos Exp $ */
/*-
* Copyright (c) 2009 The NetBSD Foundation, Inc.
@ -44,7 +44,4 @@
#define RAIDFRAME_CONFIGURE50 _IOW ('r', 1, void *)
#define RAIDFRAME_GET_INFO50 _IOWR('r', 15, void *)
int rf_config50(RF_Raid_t *, int, void *, RF_Config_t **);
int rf_get_info50(RF_Raid_t *, void *);
#endif /* _RF_COMPAT50_H_ */

View File

@ -1,38 +0,0 @@
/* $NetBSD: rf_compat50_mod.h,v 1.4 2019/02/03 08:02:24 pgoyette Exp $ */
/*-
* Copyright (c) 2018 The NetBSD Foundation, Inc.
* All rights reserved.
*
* This code is derived from software contributed to The NetBSD Foundation
* by Paul Goyette
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef _RF_COMPAT50_MOD_H_
#define _RF_COMPAT50_MOD_H_
int raidframe_ioctl_50(u_long, int, RF_Raid_t *, int, void *, RF_Config_t **);
#endif /* _RF_COMPAT50_MOD_H_ */

View File

@ -1,4 +1,4 @@
/* $NetBSD: rf_compat80.c,v 1.10 2019/02/05 19:42:31 christos Exp $ */
/* $NetBSD: rf_compat80.c,v 1.11 2019/02/05 23:28:02 christos Exp $ */
/*
* Copyright (c) 2017 Matthew R. Green
@ -40,10 +40,80 @@
#include "rf_raid.h"
#include "rf_compat80.h"
#include "rf_compat80_mod.h"
#include "rf_kintf.h"
int
/* NetBSD 8.99.x removed the row, raidPtr and next members */
struct rf_recon_req80 {
RF_RowCol_t row, col;
RF_ReconReqFlags_t flags;
void *raidPtr; /* used internally; need not be set at ioctl
* time */
struct rf_recon_req *next; /* used internally; need not be set at
* ioctl time */
};
/* NetBSD 8.99.x made this structure alignment neutral */
typedef struct RF_RaidDisk_s80 {
char devname[56]; /* name of device file */
RF_DiskStatus_t status; /* whether it is up or down */
RF_RowCol_t spareRow; /* if in status "spared", this identifies the
* spare disk */
RF_RowCol_t spareCol; /* if in status "spared", this identifies the
* spare disk */
RF_SectorCount_t numBlocks; /* number of blocks, obtained via READ
* CAPACITY */
int blockSize;
RF_SectorCount_t partitionSize; /* The *actual* and *full* size of
the partition, from the disklabel */
int auto_configured;/* 1 if this component was autoconfigured.
0 otherwise. */
dev_t dev;
} RF_RaidDisk_t80;
typedef struct RF_DeviceConfig_s80 {
u_int rows;
u_int cols;
u_int maxqdepth;
int ndevs;
RF_RaidDisk_t80 devs[RF_MAX_DISKS];
int nspares;
RF_RaidDisk_t80 spares[RF_MAX_DISKS];
} RF_DeviceConfig_t80;
typedef struct RF_Config_s80 {
RF_RowCol_t numRow, numCol, numSpare; /* number of rows, columns,
* and spare disks */
dev_t devs[RF_MAXROW][RF_MAXCOL]; /* device numbers for disks
* comprising array */
char devnames[RF_MAXROW][RF_MAXCOL][50]; /* device names */
dev_t spare_devs[RF_MAXSPARE]; /* device numbers for spare
* disks */
char spare_names[RF_MAXSPARE][50]; /* device names */
RF_SectorNum_t sectPerSU; /* sectors per stripe unit */
RF_StripeNum_t SUsPerPU;/* stripe units per parity unit */
RF_StripeNum_t SUsPerRU;/* stripe units per reconstruction unit */
RF_ParityConfig_t parityConfig; /* identifies the RAID architecture to
* be used */
RF_DiskQueueType_t diskQueueType; /* 'f' = fifo, 'c' = cvscan,
* not used in kernel */
char maxOutstandingDiskReqs; /* # concurrent reqs to be sent to a
* disk. not used in kernel. */
char debugVars[RF_MAXDBGV][50]; /* space for specifying debug
* variables & their values */
unsigned int layoutSpecificSize; /* size in bytes of
* layout-specific info */
void *layoutSpecific; /* a pointer to a layout-specific structure to
* be copied in */
int force; /* if !0, ignore many fatal
configuration conditions */
/*
"force" is used to override cases where the component labels would
indicate that configuration should not proceed without user
intervention
*/
} RF_Config_t80;
static int
rf_check_recon_status_ext80(RF_Raid_t *raidPtr, void *data)
{
RF_ProgressInfo_t info, **infoPtr = data;
@ -52,7 +122,7 @@ rf_check_recon_status_ext80(RF_Raid_t *raidPtr, void *data)
return copyout(&info, *infoPtr, sizeof info);
}
int
static int
rf_check_parityrewrite_status_ext80(RF_Raid_t *raidPtr, void *data)
{
RF_ProgressInfo_t info, **infoPtr = data;
@ -61,7 +131,7 @@ rf_check_parityrewrite_status_ext80(RF_Raid_t *raidPtr, void *data)
return copyout(&info, *infoPtr, sizeof info);
}
int
static int
rf_check_copyback_status_ext80(RF_Raid_t *raidPtr, void *data)
{
RF_ProgressInfo_t info, **infoPtr = data;
@ -87,7 +157,7 @@ rf_copy_raiddisk80(RF_RaidDisk_t *disk, RF_RaidDisk_t80 *disk80)
disk80->dev = disk->dev;
}
int
static int
rf_get_info80(RF_Raid_t *raidPtr, void *data)
{
RF_DeviceConfig_t *config;
@ -124,7 +194,7 @@ rf_get_info80(RF_Raid_t *raidPtr, void *data)
return rv;
}
int
static int
rf_get_component_label80(RF_Raid_t *raidPtr, void *data)
{
RF_ComponentLabel_t **clabel_ptr = (RF_ComponentLabel_t **)data;
@ -151,17 +221,18 @@ rf_get_component_label80(RF_Raid_t *raidPtr, void *data)
return retcode;
}
int
rf_config80(RF_Raid_t *raidPtr, int unit, void *data, RF_Config_t **k_cfgp)
static int
rf_config80(struct raid_softc *rs, void *data)
{
RF_Config_t80 *u80_cfg, *k80_cfg;
RF_Config_t *k_cfg;
RF_Raid_t *raidPtr = rf_get_raid(rs);
size_t i, j;
int error;
if (raidPtr->valid) {
/* There is a valid RAID set running on this unit! */
printf("raid%d: Device already configured!\n", unit);
printf("raid%d: Device already configured!\n", rf_get_unit(rs));
return EINVAL;
}
@ -218,8 +289,7 @@ rf_config80(RF_Raid_t *raidPtr, int unit, void *data, RF_Config_t **k_cfgp)
k_cfg->force = k80_cfg->force;
RF_Free(k80_cfg, sizeof(RF_Config_t80));
*k_cfgp = k_cfg;
return 0;
return rf_construct(rs, k_cfg);
}
static int
@ -232,11 +302,10 @@ rf_fail_disk80(RF_Raid_t *raidPtr, struct rf_recon_req80 *req80)
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)
static int
raidframe_ioctl_80(struct raid_softc *rs, u_long cmd, void *data)
{
int error;
RF_Raid_t *raidPtr = rf_get_raid(rs);
switch (cmd) {
case RAIDFRAME_CHECK_RECON_STATUS_EXT80:
@ -244,7 +313,7 @@ raidframe_ioctl_80(u_long cmd, int initted, RF_Raid_t *raidPtr, int unit,
case RAIDFRAME_CHECK_COPYBACK_STATUS_EXT80:
case RAIDFRAME_GET_INFO80:
case RAIDFRAME_GET_COMPONENT_LABEL80:
if (initted == 0)
if (!rf_inited(rs))
return ENXIO;
break;
case RAIDFRAME_CONFIGURE80:
@ -266,10 +335,7 @@ raidframe_ioctl_80(u_long cmd, int initted, RF_Raid_t *raidPtr, int unit,
case RAIDFRAME_GET_COMPONENT_LABEL80:
return rf_get_component_label80(raidPtr, data);
case RAIDFRAME_CONFIGURE80:
error = rf_config80(raidPtr, unit, data, k_cfg);
if (error != 0)
return error;
return EAGAIN; /* flag mainline to call generic config */
return rf_config80(rs, data);
case RAIDFRAME_FAIL_DISK80:
return rf_fail_disk80(raidPtr, data);
default:

View File

@ -1,4 +1,4 @@
/* $NetBSD: rf_compat80.h,v 1.2 2018/01/20 01:32:45 mrg Exp $ */
/* $NetBSD: rf_compat80.h,v 1.3 2019/02/05 23:28:02 christos Exp $ */
/*
* Copyright (c) 2017 Matthew R. Green
@ -33,77 +33,6 @@
#include <sys/ioccom.h>
/* NetBSD 8.99.x removed the row, raidPtr and next members */
struct rf_recon_req80 {
RF_RowCol_t row, col;
RF_ReconReqFlags_t flags;
void *raidPtr; /* used internally; need not be set at ioctl
* time */
struct rf_recon_req *next; /* used internally; need not be set at
* ioctl time */
};
/* NetBSD 8.99.x made this structure alignment neutral */
typedef struct RF_RaidDisk_s80 {
char devname[56]; /* name of device file */
RF_DiskStatus_t status; /* whether it is up or down */
RF_RowCol_t spareRow; /* if in status "spared", this identifies the
* spare disk */
RF_RowCol_t spareCol; /* if in status "spared", this identifies the
* spare disk */
RF_SectorCount_t numBlocks; /* number of blocks, obtained via READ
* CAPACITY */
int blockSize;
RF_SectorCount_t partitionSize; /* The *actual* and *full* size of
the partition, from the disklabel */
int auto_configured;/* 1 if this component was autoconfigured.
0 otherwise. */
dev_t dev;
} RF_RaidDisk_t80;
typedef struct RF_DeviceConfig_s80 {
u_int rows;
u_int cols;
u_int maxqdepth;
int ndevs;
RF_RaidDisk_t80 devs[RF_MAX_DISKS];
int nspares;
RF_RaidDisk_t80 spares[RF_MAX_DISKS];
} RF_DeviceConfig_t80;
typedef struct RF_Config_s80 {
RF_RowCol_t numRow, numCol, numSpare; /* number of rows, columns,
* and spare disks */
dev_t devs[RF_MAXROW][RF_MAXCOL]; /* device numbers for disks
* comprising array */
char devnames[RF_MAXROW][RF_MAXCOL][50]; /* device names */
dev_t spare_devs[RF_MAXSPARE]; /* device numbers for spare
* disks */
char spare_names[RF_MAXSPARE][50]; /* device names */
RF_SectorNum_t sectPerSU; /* sectors per stripe unit */
RF_StripeNum_t SUsPerPU;/* stripe units per parity unit */
RF_StripeNum_t SUsPerRU;/* stripe units per reconstruction unit */
RF_ParityConfig_t parityConfig; /* identifies the RAID architecture to
* be used */
RF_DiskQueueType_t diskQueueType; /* 'f' = fifo, 'c' = cvscan,
* not used in kernel */
char maxOutstandingDiskReqs; /* # concurrent reqs to be sent to a
* disk. not used in kernel. */
char debugVars[RF_MAXDBGV][50]; /* space for specifying debug
* variables & their values */
unsigned int layoutSpecificSize; /* size in bytes of
* layout-specific info */
void *layoutSpecific; /* a pointer to a layout-specific structure to
* be copied in */
int force; /* if !0, ignore many fatal
configuration conditions */
/*
"force" is used to override cases where the component labels would
indicate that configuration should not proceed without user
intervention
*/
} RF_Config_t80;
/*
* These ioctls were versioned after NetBSD 8.x.
*
@ -125,11 +54,4 @@ typedef struct RF_Config_s80 {
#define RAIDFRAME_GET_INFO80 _IOWR('r', 36, RF_DeviceConfig_t80 *)
#define RAIDFRAME_CONFIGURE80 _IOW ('r', 35, void *)
int rf_check_recon_status_ext80(RF_Raid_t *, void *);
int rf_check_parityrewrite_status_ext80(RF_Raid_t *, void *);
int rf_check_copyback_status_ext80(RF_Raid_t *, void *);
int rf_get_info80(RF_Raid_t *, void *);
int rf_get_component_label80(RF_Raid_t *, void *);
int rf_config80(RF_Raid_t *, int, void *, RF_Config_t **);
#endif /* _RF_COMPAT80_H_ */

View File

@ -1,41 +0,0 @@
/* $NetBSD: rf_compat80_mod.h,v 1.4 2019/02/03 08:02:24 pgoyette Exp $ */
/*-
* Copyright (c) 2018 The NetBSD Foundation, Inc.
* All rights reserved.
*
* This code is derived from software contributed to The NetBSD Foundation
* by Paul Goyette
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef _RF_COMPAT80_MOD_H_
#define _RF_COMPAT80_MOD_H_
struct RF_Raid_s;
struct RF_Config_s;
int raidframe_ioctl_80(u_long, int, struct RF_Raid_s *, int, void *,
struct RF_Config_s **);
#endif /* _RF_COMPAT80_MOD_H_ */

View File

@ -1,4 +1,4 @@
/* $NetBSD: rf_netbsd.h,v 1.31 2019/02/05 17:13:37 christos Exp $ */
/* $NetBSD: rf_netbsd.h,v 1.32 2019/02/05 23:28:02 christos Exp $ */
/*-
* Copyright (c) 1996, 1997, 1998 The NetBSD Foundation, Inc.
@ -105,4 +105,9 @@ typedef struct RF_ConfigSet_s {
int rf_fail_disk(RF_Raid_t *, struct rf_recon_req *);
int rf_inited(const struct raid_softc *);
int rf_get_unit(const struct raid_softc *);
RF_Raid_t *rf_get_raid(struct raid_softc *);
int rf_construct(struct raid_softc *, RF_Config_t *);
#endif /* _RF__RF_NETBSDSTUFF_H_ */

View File

@ -1,4 +1,4 @@
/* $NetBSD: rf_netbsdkintf.c,v 1.366 2019/02/05 17:13:37 christos Exp $ */
/* $NetBSD: rf_netbsdkintf.c,v 1.367 2019/02/05 23:28:02 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.366 2019/02/05 17:13:37 christos Exp $");
__KERNEL_RCSID(0, "$NetBSD: rf_netbsdkintf.c,v 1.367 2019/02/05 23:28:02 christos Exp $");
#ifdef _KERNEL_OPT
#include "opt_raid_autoconfig.h"
@ -149,16 +149,6 @@ __KERNEL_RCSID(0, "$NetBSD: rf_netbsdkintf.c,v 1.366 2019/02/05 17:13:37 christo
#include "rf_parityscan.h"
#include "rf_threadstuff.h"
#include "rf_compat50.h"
#include "rf_compat80.h"
#ifdef COMPAT_NETBSD32
#ifdef _LP64
#include "rf_compat32.h"
#define RAID_COMPAT32
#endif
#endif
#include "ioconf.h"
#ifdef DEBUG
@ -465,6 +455,16 @@ rf_autoconfig(device_t self)
return 1;
}
int
rf_inited(const struct raid_softc *rs) {
return (rs->sc_flags & RAIDF_INITED) != 0;
}
int
rf_get_unit(const struct raid_softc *rs) {
return rs->sc_unit;
}
static int
rf_containsboot(RF_Raid_t *r, device_t bdv) {
const char *bootname;
@ -1057,27 +1057,17 @@ rf_must_be_initialized(const struct raid_softc *rs, u_long 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:
@ -1098,48 +1088,6 @@ rf_must_be_initialized(const struct raid_softc *rs, u_long cmd)
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)
{
@ -1189,28 +1137,289 @@ out:
return EINVAL;
}
static int
rf_copyinspecificbuf(RF_Config_t *k_cfg)
{
/* allocate a buffer for the layout-specific data, and copy it in */
if (k_cfg->layoutSpecificSize == 0)
return 0;
if (k_cfg->layoutSpecificSize > 10000) {
/* sanity check */
return EINVAL;
}
u_char *specific_buf;
RF_Malloc(specific_buf, k_cfg->layoutSpecificSize, (u_char *));
if (specific_buf == NULL)
return ENOMEM;
int retcode = copyin(k_cfg->layoutSpecific, specific_buf,
k_cfg->layoutSpecificSize);
if (retcode) {
RF_Free(specific_buf, k_cfg->layoutSpecificSize);
db1_printf(("%s: retcode=%d copyin.2\n", __func__, retcode));
return retcode;
}
k_cfg->layoutSpecific = specific_buf;
return 0;
}
static int
rf_getConfiguration(struct raid_softc *rs, void *data, RF_Config_t **k_cfg)
{
if (rs->sc_r.valid) {
/* There is a valid RAID set running on this unit! */
printf("raid%d: Device already configured!\n", rs->sc_unit);
return EINVAL;
}
/* copy-in the configuration information */
/* data points to a pointer to the configuration structure */
RF_Malloc(*k_cfg, sizeof(RF_Config_t), (RF_Config_t *));
if (*k_cfg == NULL) {
return ENOMEM;
}
int retcode = copyin(data, k_cfg, sizeof(RF_Config_t));
if (retcode == 0)
return 0;
RF_Free(*k_cfg, sizeof(RF_Config_t));
db1_printf(("%s: retcode=%d copyin.1\n", __func__, retcode));
rs->sc_flags |= RAIDF_SHUTDOWN;
return retcode;
}
int
rf_construct(struct raid_softc *rs, RF_Config_t *k_cfg)
{
int retcode;
RF_Raid_t *raidPtr = &rs->sc_r;
rs->sc_flags &= ~RAIDF_SHUTDOWN;
if ((retcode = rf_copyinspecificbuf(k_cfg)) != 0)
goto out;
/* should do some kind of sanity check on the configuration.
* Store the sum of all the bytes in the last byte? */
/* configure the system */
/*
* Clear the entire RAID descriptor, just to make sure
* there is no stale data left in the case of a
* reconfiguration
*/
memset(raidPtr, 0, sizeof(*raidPtr));
raidPtr->softc = rs;
raidPtr->raidid = rs->sc_unit;
retcode = rf_Configure(raidPtr, k_cfg, NULL);
if (retcode == 0) {
/* allow this many simultaneous IO's to
this RAID device */
raidPtr->openings = RAIDOUTSTANDING;
raidinit(rs);
raid_wakeup(raidPtr);
rf_markalldirty(raidPtr);
}
/* free the buffers. No return code here. */
if (k_cfg->layoutSpecificSize) {
RF_Free(k_cfg->layoutSpecific, k_cfg->layoutSpecificSize);
}
out:
RF_Free(k_cfg, sizeof(RF_Config_t));
if (retcode) {
/*
* If configuration failed, set sc_flags so that we
* will detach the device when we close it.
*/
rs->sc_flags |= RAIDF_SHUTDOWN;
}
return retcode;
}
#if RF_DISABLED
static int
rf_set_component_label(RF_Raid_t *raidPtr, RF_ComponentLabel_t *clabel)
{
/* XXX check the label for valid stuff... */
/* Note that some things *should not* get modified --
the user should be re-initing the labels instead of
trying to patch things.
*/
#ifdef DEBUG
int raidid = raidPtr->raidid;
printf("raid%d: Got component label:\n", raidid);
printf("raid%d: Version: %d\n", raidid, clabel->version);
printf("raid%d: Serial Number: %d\n", raidid, clabel->serial_number);
printf("raid%d: Mod counter: %d\n", raidid, clabel->mod_counter);
printf("raid%d: Column: %d\n", raidid, clabel->column);
printf("raid%d: Num Columns: %d\n", raidid, clabel->num_columns);
printf("raid%d: Clean: %d\n", raidid, clabel->clean);
printf("raid%d: Status: %d\n", raidid, clabel->status);
#endif /* DEBUG */
clabel->row = 0;
int column = clabel->column;
if ((column < 0) || (column >= raidPtr->numCol)) {
return(EINVAL);
}
/* XXX this isn't allowed to do anything for now :-) */
/* XXX and before it is, we need to fill in the rest
of the fields!?!?!?! */
memcpy(raidget_component_label(raidPtr, column),
clabel, sizeof(*clabel));
raidflush_component_label(raidPtr, column);
return 0;
}
#endif
static int
rf_init_component_label(RF_Raid_t *raidPtr, RF_ComponentLabel_t *clabel)
{
/*
we only want the serial number from
the above. We get all the rest of the information
from the config that was used to create this RAID
set.
*/
raidPtr->serial_number = clabel->serial_number;
for (int column = 0; column < raidPtr->numCol; column++) {
RF_RaidDisk_t *diskPtr = &raidPtr->Disks[column];
if (RF_DEAD_DISK(diskPtr->status))
continue;
RF_ComponentLabel_t *ci_label = raidget_component_label(
raidPtr, column);
/* Zeroing this is important. */
memset(ci_label, 0, sizeof(*ci_label));
raid_init_component_label(raidPtr, ci_label);
ci_label->serial_number = raidPtr->serial_number;
ci_label->row = 0; /* we dont' pretend to support more */
rf_component_label_set_partitionsize(ci_label,
diskPtr->partitionSize);
ci_label->column = column;
raidflush_component_label(raidPtr, column);
/* XXXjld what about the spares? */
}
return 0;
}
static int
rf_rebuild_in_place(RF_Raid_t *raidPtr, RF_SingleComponent_t *componentPtr)
{
if (raidPtr->Layout.map->faultsTolerated == 0) {
/* Can't do this on a RAID 0!! */
return EINVAL;
}
if (raidPtr->recon_in_progress == 1) {
/* a reconstruct is already in progress! */
return EINVAL;
}
RF_SingleComponent_t component;
memcpy(&component, componentPtr, sizeof(RF_SingleComponent_t));
component.row = 0; /* we don't support any more */
int column = component.column;
if ((column < 0) || (column >= raidPtr->numCol)) {
return EINVAL;
}
rf_lock_mutex2(raidPtr->mutex);
if ((raidPtr->Disks[column].status == rf_ds_optimal) &&
(raidPtr->numFailures > 0)) {
/* XXX 0 above shouldn't be constant!!! */
/* some component other than this has failed.
Let's not make things worse than they already
are... */
printf("raid%d: Unable to reconstruct to disk at:\n",
raidPtr->raidid);
printf("raid%d: Col: %d Too many failures.\n",
raidPtr->raidid, column);
rf_unlock_mutex2(raidPtr->mutex);
return EINVAL;
}
if (raidPtr->Disks[column].status == rf_ds_reconstructing) {
printf("raid%d: Unable to reconstruct to disk at:\n",
raidPtr->raidid);
printf("raid%d: Col: %d "
"Reconstruction already occurring!\n",
raidPtr->raidid, column);
rf_unlock_mutex2(raidPtr->mutex);
return EINVAL;
}
if (raidPtr->Disks[column].status == rf_ds_spared) {
rf_unlock_mutex2(raidPtr->mutex);
return EINVAL;
}
rf_unlock_mutex2(raidPtr->mutex);
struct rf_recon_req_internal *rrint;
RF_Malloc(rrint, sizeof(*rrint), (struct rf_recon_req_internal *));
if (rrint == NULL)
return ENOMEM;
rrint->col = column;
rrint->raidPtr = raidPtr;
return RF_CREATE_THREAD(raidPtr->recon_thread,
rf_ReconstructInPlaceThread, rrint, "raid_reconip");
}
static int
rf_check_recon_status(RF_Raid_t *raidPtr, int *data)
{
/*
* This makes no sense on a RAID 0, or if we are not reconstructing
* so tell the user it's done.
*/
if (raidPtr->Layout.map->faultsTolerated == 0 ||
raidPtr->status != rf_rs_reconstructing) {
*data = 100;
return 0;
}
if (raidPtr->reconControl->numRUsTotal == 0) {
*data = 0;
return 0;
}
*data = (raidPtr->reconControl->numRUsComplete * 100
/ raidPtr->reconControl->numRUsTotal);
return 0;
}
static int
raidioctl(dev_t dev, u_long cmd, void *data, int flag, struct lwp *l)
{
int unit = raidunit(dev);
int error = 0;
int part, pmask;
struct raid_softc *rs;
struct dk_softc *dksc;
RF_Config_t *k_cfg, *u_cfg;
RF_Config_t *k_cfg;
RF_Raid_t *raidPtr;
RF_RaidDisk_t *diskPtr;
RF_AccTotals_t *totals;
RF_SingleComponent_t component;
RF_DeviceConfig_t *d_cfg, *ucfgp = data;
u_char *specific_buf;
int retcode = 0;
int column;
/* int raidid; */
struct rf_recon_req_internal *rrint;
RF_ComponentLabel_t *clabel;
RF_ComponentLabel_t *ci_label;
RF_SingleComponent_t *sparePtr,*componentPtr;
RF_SingleComponent_t component;
int d;
if ((rs = raidget(unit, false)) == NULL)
@ -1226,128 +1435,12 @@ raidioctl(dev_t dev, u_long cmd, void *data, int flag, struct lwp *l)
if (rf_must_be_initialized(rs, cmd))
return ENXIO;
switch (retcode = rf_handle_compat(rs, unit, cmd, data, &k_cfg)) {
case EPASSTHROUGH:
/* Not compat, keep going */
retcode = 0;
break;
case EAGAIN:
goto config;
default:
/* compat but could not handle it or load the module */
return retcode;
}
switch (cmd) {
/* configure the system */
case RAIDFRAME_CONFIGURE:
#ifdef RAID_COMPAT32
case RAIDFRAME_CONFIGURE32:
#endif
if (raidPtr->valid) {
/* There is a valid RAID set running on this unit! */
printf("raid%d: Device already configured!\n", unit);
return(EINVAL);
}
/* copy-in the configuration information */
/* data points to a pointer to the configuration structure */
RF_Malloc(k_cfg, sizeof(RF_Config_t), (RF_Config_t *));
if (k_cfg == NULL) {
return (ENOMEM);
}
#ifdef RAID_COMPAT32
if (cmd == RAIDFRAME_CONFIGURE32 &&
(l->l_proc->p_flag & PK_32) != 0)
MODULE_CALL_HOOK(raidframe_netbsd32_config_hook,
(data, k_cfg), enosys(), retcode);
else
#endif
{
u_cfg = *((RF_Config_t **) data);
retcode = copyin(u_cfg, k_cfg, sizeof(RF_Config_t));
}
if (retcode) {
RF_Free(k_cfg, sizeof(RF_Config_t));
db1_printf(("rf_ioctl: retcode=%d copyin.1\n",
retcode));
goto no_config;
}
goto config;
config:
rs->sc_flags &= ~RAIDF_SHUTDOWN;
/* allocate a buffer for the layout-specific data, and copy it
* in */
if (k_cfg->layoutSpecificSize) {
if (k_cfg->layoutSpecificSize > 10000) {
/* sanity check */
RF_Free(k_cfg, sizeof(RF_Config_t));
retcode = EINVAL;
goto no_config;
}
RF_Malloc(specific_buf, k_cfg->layoutSpecificSize,
(u_char *));
if (specific_buf == NULL) {
RF_Free(k_cfg, sizeof(RF_Config_t));
retcode = ENOMEM;
goto no_config;
}
retcode = copyin(k_cfg->layoutSpecific, specific_buf,
k_cfg->layoutSpecificSize);
if (retcode) {
RF_Free(k_cfg, sizeof(RF_Config_t));
RF_Free(specific_buf,
k_cfg->layoutSpecificSize);
db1_printf(("rf_ioctl: retcode=%d copyin.2\n",
retcode));
goto no_config;
}
} else
specific_buf = NULL;
k_cfg->layoutSpecific = specific_buf;
/* should do some kind of sanity check on the configuration.
* Store the sum of all the bytes in the last byte? */
/* configure the system */
/*
* Clear the entire RAID descriptor, just to make sure
* there is no stale data left in the case of a
* reconfiguration
*/
memset(raidPtr, 0, sizeof(*raidPtr));
raidPtr->softc = rs;
raidPtr->raidid = unit;
retcode = rf_Configure(raidPtr, k_cfg, NULL);
if (retcode == 0) {
/* allow this many simultaneous IO's to
this RAID device */
raidPtr->openings = RAIDOUTSTANDING;
raidinit(rs);
raid_wakeup(raidPtr);
rf_markalldirty(raidPtr);
}
/* free the buffers. No return code here. */
if (k_cfg->layoutSpecificSize) {
RF_Free(specific_buf, k_cfg->layoutSpecificSize);
}
RF_Free(k_cfg, sizeof(RF_Config_t));
no_config:
/*
* If configuration failed, set sc_flags so that we
* will detach the device when we close it.
*/
if (retcode != 0)
rs->sc_flags |= RAIDF_SHUTDOWN;
return (retcode);
if ((retcode = rf_getConfiguration(rs, data, &k_cfg)) != 0)
return retcode;
return rf_construct(rs, k_cfg);
/* shutdown the system */
case RAIDFRAME_SHUTDOWN:
@ -1355,8 +1448,8 @@ raidioctl(dev_t dev, u_long cmd, void *data, int flag, struct lwp *l)
part = DISKPART(dev);
pmask = (1 << part);
if ((error = raidlock(rs)) != 0)
return (error);
if ((retcode = raidlock(rs)) != 0)
return retcode;
if (DK_BUSY(dksc, pmask) ||
raidPtr->recon_in_progress != 0 ||
@ -1371,92 +1464,31 @@ raidioctl(dev_t dev, u_long cmd, void *data, int flag, struct lwp *l)
raidunlock(rs);
return (retcode);
return retcode;
case RAIDFRAME_GET_COMPONENT_LABEL:
return rf_get_component_label(raidPtr, data);
#if 0
#if RF_DISABLED
case RAIDFRAME_SET_COMPONENT_LABEL:
clabel = (RF_ComponentLabel_t *) data;
/* XXX check the label for valid stuff... */
/* Note that some things *should not* get modified --
the user should be re-initing the labels instead of
trying to patch things.
*/
raidid = raidPtr->raidid;
#ifdef DEBUG
printf("raid%d: Got component label:\n", raidid);
printf("raid%d: Version: %d\n", raidid, clabel->version);
printf("raid%d: Serial Number: %d\n", raidid, clabel->serial_number);
printf("raid%d: Mod counter: %d\n", raidid, clabel->mod_counter);
printf("raid%d: Column: %d\n", raidid, clabel->column);
printf("raid%d: Num Columns: %d\n", raidid, clabel->num_columns);
printf("raid%d: Clean: %d\n", raidid, clabel->clean);
printf("raid%d: Status: %d\n", raidid, clabel->status);
#endif /* DEBUG */
clabel->row = 0;
column = clabel->column;
if ((column < 0) || (column >= raidPtr->numCol)) {
return(EINVAL);
}
/* XXX this isn't allowed to do anything for now :-) */
/* XXX and before it is, we need to fill in the rest
of the fields!?!?!?! */
memcpy(raidget_component_label(raidPtr, column),
clabel, sizeof(*clabel));
raidflush_component_label(raidPtr, column);
return (0);
#endif /* 0 */
return rf_set_component_label(raidPtr, data);
#endif
case RAIDFRAME_INIT_LABELS:
clabel = (RF_ComponentLabel_t *) data;
/*
we only want the serial number from
the above. We get all the rest of the information
from the config that was used to create this RAID
set.
*/
return rf_init_component_label(raidPtr, data);
raidPtr->serial_number = clabel->serial_number;
for(column=0;column<raidPtr->numCol;column++) {
diskPtr = &raidPtr->Disks[column];
if (!RF_DEAD_DISK(diskPtr->status)) {
ci_label = raidget_component_label(raidPtr,
column);
/* Zeroing this is important. */
memset(ci_label, 0, sizeof(*ci_label));
raid_init_component_label(raidPtr, ci_label);
ci_label->serial_number =
raidPtr->serial_number;
ci_label->row = 0; /* we dont' pretend to support more */
rf_component_label_set_partitionsize(ci_label,
diskPtr->partitionSize);
ci_label->column = column;
raidflush_component_label(raidPtr, column);
}
/* XXXjld what about the spares? */
}
return (retcode);
case RAIDFRAME_SET_AUTOCONFIG:
d = rf_set_autoconfig(raidPtr, *(int *) data);
printf("raid%d: New autoconfig value is: %d\n",
raidPtr->raidid, d);
*(int *) data = d;
return (retcode);
return retcode;
case RAIDFRAME_SET_ROOT:
d = rf_set_rootpartition(raidPtr, *(int *) data);
printf("raid%d: New rootpartition value is: %d\n",
raidPtr->raidid, d);
*(int *) data = d;
return (retcode);
return retcode;
/* initialize all parity */
case RAIDFRAME_REWRITEPARITY:
@ -1464,113 +1496,38 @@ raidioctl(dev_t dev, u_long cmd, void *data, int flag, struct lwp *l)
if (raidPtr->Layout.map->faultsTolerated == 0) {
/* Parity for RAID 0 is trivially correct */
raidPtr->parity_good = RF_RAID_CLEAN;
return(0);
return 0;
}
if (raidPtr->parity_rewrite_in_progress == 1) {
/* Re-write is already in progress! */
return(EINVAL);
return EINVAL;
}
retcode = RF_CREATE_THREAD(raidPtr->parity_rewrite_thread,
rf_RewriteParityThread,
raidPtr,"raid_parity");
return (retcode);
return RF_CREATE_THREAD(raidPtr->parity_rewrite_thread,
rf_RewriteParityThread, raidPtr,"raid_parity");
case RAIDFRAME_ADD_HOT_SPARE:
sparePtr = (RF_SingleComponent_t *) data;
memcpy( &component, sparePtr, sizeof(RF_SingleComponent_t));
retcode = rf_add_hot_spare(raidPtr, &component);
return(retcode);
memcpy(&component, sparePtr, sizeof(RF_SingleComponent_t));
return rf_add_hot_spare(raidPtr, &component);
case RAIDFRAME_REMOVE_HOT_SPARE:
return(retcode);
return retcode;
case RAIDFRAME_DELETE_COMPONENT:
componentPtr = (RF_SingleComponent_t *)data;
memcpy( &component, componentPtr,
sizeof(RF_SingleComponent_t));
retcode = rf_delete_component(raidPtr, &component);
return(retcode);
memcpy(&component, componentPtr, sizeof(RF_SingleComponent_t));
return rf_delete_component(raidPtr, &component);
case RAIDFRAME_INCORPORATE_HOT_SPARE:
componentPtr = (RF_SingleComponent_t *)data;
memcpy( &component, componentPtr,
sizeof(RF_SingleComponent_t));
retcode = rf_incorporate_hot_spare(raidPtr, &component);
return(retcode);
memcpy(&component, componentPtr, sizeof(RF_SingleComponent_t));
return rf_incorporate_hot_spare(raidPtr, &component);
case RAIDFRAME_REBUILD_IN_PLACE:
return rf_rebuild_in_place(raidPtr, data);
if (raidPtr->Layout.map->faultsTolerated == 0) {
/* Can't do this on a RAID 0!! */
return(EINVAL);
}
if (raidPtr->recon_in_progress == 1) {
/* a reconstruct is already in progress! */
return(EINVAL);
}
componentPtr = (RF_SingleComponent_t *) data;
memcpy( &component, componentPtr,
sizeof(RF_SingleComponent_t));
component.row = 0; /* we don't support any more */
column = component.column;
if ((column < 0) || (column >= raidPtr->numCol)) {
return(EINVAL);
}
rf_lock_mutex2(raidPtr->mutex);
if ((raidPtr->Disks[column].status == rf_ds_optimal) &&
(raidPtr->numFailures > 0)) {
/* XXX 0 above shouldn't be constant!!! */
/* some component other than this has failed.
Let's not make things worse than they already
are... */
printf("raid%d: Unable to reconstruct to disk at:\n",
raidPtr->raidid);
printf("raid%d: Col: %d Too many failures.\n",
raidPtr->raidid, column);
rf_unlock_mutex2(raidPtr->mutex);
return (EINVAL);
}
if (raidPtr->Disks[column].status ==
rf_ds_reconstructing) {
printf("raid%d: Unable to reconstruct to disk at:\n",
raidPtr->raidid);
printf("raid%d: Col: %d Reconstruction already occurring!\n", raidPtr->raidid, column);
rf_unlock_mutex2(raidPtr->mutex);
return (EINVAL);
}
if (raidPtr->Disks[column].status == rf_ds_spared) {
rf_unlock_mutex2(raidPtr->mutex);
return (EINVAL);
}
rf_unlock_mutex2(raidPtr->mutex);
RF_Malloc(rrint, sizeof(*rrint), (struct rf_recon_req_internal *));
if (rrint == NULL)
return(ENOMEM);
rrint->col = column;
rrint->raidPtr = raidPtr;
retcode = RF_CREATE_THREAD(raidPtr->recon_thread,
rf_ReconstructInPlaceThread,
rrint, "raid_reconip");
return(retcode);
#ifdef RAID_COMPAT32
case RAIDFRAME_GET_INFO32:
if (!raidframe_netbsd32_config_hook.hooked)
return ENOSYS;
ucfgp = NETBSD32PTR64(*(netbsd32_pointer_t *)data);
/*FALLTHROUGH*/
#endif
case RAIDFRAME_GET_INFO:
RF_Malloc(d_cfg, sizeof(RF_DeviceConfig_t),
(RF_DeviceConfig_t *));
@ -1581,18 +1538,16 @@ raidioctl(dev_t dev, u_long cmd, void *data, int flag, struct lwp *l)
retcode = copyout(d_cfg, ucfgp, sizeof(*d_cfg));
}
RF_Free(d_cfg, sizeof(RF_DeviceConfig_t));
return retcode;
case RAIDFRAME_CHECK_PARITY:
*(int *) data = raidPtr->parity_good;
return (0);
return 0;
case RAIDFRAME_PARITYMAP_STATUS:
if (rf_paritymap_ineligible(raidPtr))
return EINVAL;
rf_paritymap_status(raidPtr->parity_map,
(struct rf_pmstat *)data);
rf_paritymap_status(raidPtr->parity_map, data);
return 0;
case RAIDFRAME_PARITYMAP_SET_PARAMS:
@ -1600,8 +1555,7 @@ raidioctl(dev_t dev, u_long cmd, void *data, int flag, struct lwp *l)
return EINVAL;
if (raidPtr->parity_map == NULL)
return ENOENT; /* ??? */
if (0 != rf_paritymap_set_params(raidPtr->parity_map,
(struct rf_pmparams *)data, 1))
if (rf_paritymap_set_params(raidPtr->parity_map, data, 1) != 0)
return EINVAL;
return 0;
@ -1620,7 +1574,7 @@ raidioctl(dev_t dev, u_long cmd, void *data, int flag, struct lwp *l)
case RAIDFRAME_RESET_ACCTOTALS:
memset(&raidPtr->acc_totals, 0, sizeof(raidPtr->acc_totals));
return (0);
return 0;
case RAIDFRAME_GET_ACCTOTALS:
totals = (RF_AccTotals_t *) data;
@ -1644,47 +1598,31 @@ raidioctl(dev_t dev, u_long cmd, void *data, int flag, struct lwp *l)
if (raidPtr->Layout.map->faultsTolerated == 0) {
/* This makes no sense on a RAID 0!! */
return(EINVAL);
return EINVAL;
}
if (raidPtr->copyback_in_progress == 1) {
/* Copyback is already in progress! */
return(EINVAL);
return EINVAL;
}
retcode = RF_CREATE_THREAD(raidPtr->copyback_thread,
rf_CopybackThread,
raidPtr,"raid_copyback");
return (retcode);
return RF_CREATE_THREAD(raidPtr->copyback_thread,
rf_CopybackThread, raidPtr, "raid_copyback");
/* return the percentage completion of reconstruction */
case RAIDFRAME_CHECK_RECON_STATUS:
if (raidPtr->Layout.map->faultsTolerated == 0) {
/* This makes no sense on a RAID 0, so tell the
user it's done. */
*(int *) data = 100;
return(0);
}
if (raidPtr->status != rf_rs_reconstructing)
*(int *) data = 100;
else {
if (raidPtr->reconControl->numRUsTotal > 0) {
*(int *) data = (raidPtr->reconControl->numRUsComplete * 100 / raidPtr->reconControl->numRUsTotal);
} else {
*(int *) data = 0;
}
}
return (0);
return rf_check_recon_status(raidPtr, data);
case RAIDFRAME_CHECK_RECON_STATUS_EXT:
rf_check_recon_status_ext(raidPtr, data);
return (0);
return 0;
case RAIDFRAME_CHECK_PARITYREWRITE_STATUS:
if (raidPtr->Layout.map->faultsTolerated == 0) {
/* This makes no sense on a RAID 0, so tell the
user it's done. */
*(int *) data = 100;
return(0);
return 0;
}
if (raidPtr->parity_rewrite_in_progress == 1) {
*(int *) data = 100 *
@ -1693,17 +1631,17 @@ raidioctl(dev_t dev, u_long cmd, void *data, int flag, struct lwp *l)
} else {
*(int *) data = 100;
}
return (0);
return 0;
case RAIDFRAME_CHECK_PARITYREWRITE_STATUS_EXT:
rf_check_parityrewrite_status_ext(raidPtr, data);
return (0);
return 0;
case RAIDFRAME_CHECK_COPYBACK_STATUS:
if (raidPtr->Layout.map->faultsTolerated == 0) {
/* This makes no sense on a RAID 0 */
*(int *) data = 100;
return(0);
return 0;
}
if (raidPtr->copyback_in_progress == 1) {
*(int *) data = 100 * raidPtr->copyback_stripes_done /
@ -1711,7 +1649,7 @@ raidioctl(dev_t dev, u_long cmd, void *data, int flag, struct lwp *l)
} else {
*(int *) data = 100;
}
return (0);
return 0;
case RAIDFRAME_CHECK_COPYBACK_STATUS_EXT:
rf_check_copyback_status_ext(raidPtr, data);
@ -1737,12 +1675,12 @@ raidioctl(dev_t dev, u_long cmd, void *data, int flag, struct lwp *l)
* -- I should either compute the spare table in the kernel,
* or have a different -- XXX XXX -- interface (a different
* character device) for delivering the table -- XXX */
#if 0
#if RF_DISABLED
case RAIDFRAME_SPARET_WAIT:
rf_lock_mutex2(rf_sparet_wait_mutex);
while (!rf_sparet_wait_queue)
rf_wait_cond2(rf_sparet_wait_cv, rf_sparet_wait_mutex);
waitreq = rf_sparet_wait_queue;
RF_SparetWait_t *waitreq = rf_sparet_wait_queue;
rf_sparet_wait_queue = rf_sparet_wait_queue->next;
rf_unlock_mutex2(rf_sparet_wait_mutex);
@ -1750,7 +1688,7 @@ raidioctl(dev_t dev, u_long cmd, void *data, int flag, struct lwp *l)
*((RF_SparetWait_t *) data) = *waitreq;
RF_Free(waitreq, sizeof(*waitreq));
return (0);
return 0;
/* wakes up a process waiting on SPARET_WAIT and puts an error
* code in it that will cause the dameon to exit */
@ -1760,9 +1698,9 @@ raidioctl(dev_t dev, u_long cmd, void *data, int flag, struct lwp *l)
rf_lock_mutex2(rf_sparet_wait_mutex);
waitreq->next = rf_sparet_wait_queue;
rf_sparet_wait_queue = waitreq;
rf_broadcast_conf2(rf_sparet_wait_cv);
rf_broadcast_cond2(rf_sparet_wait_cv);
rf_unlock_mutex2(rf_sparet_wait_mutex);
return (0);
return 0;
/* used by the spare table daemon to deliver a spare table
* into the kernel */
@ -1781,10 +1719,30 @@ raidioctl(dev_t dev, u_long cmd, void *data, int flag, struct lwp *l)
rf_broadcast_cond2(rf_sparet_resp_cv);
rf_unlock_mutex2(rf_sparet_wait_mutex);
return (retcode);
return retcode;
#endif
default:
#ifdef _LP64
if ((l->l_proc->p_flag & PK_32) != 0) {
module_autoload("compat_netbsd32_raid",
MODULE_CLASS_EXEC);
MODULE_CALL_HOOK(raidframe_netbsd32_ioctl_hook,
(rs, cmd, data), enosys(), retcode);
if (retcode != EPASSTHROUGH)
return retcode;
}
#endif
module_autoload("compat_raid_80", MODULE_CLASS_EXEC);
MODULE_CALL_HOOK(raidframe_ioctl_80_hook,
(rs, cmd, data), enosys(), retcode);
if (retcode != EPASSTHROUGH)
return retcode;
module_autoload("compat_raid_50", MODULE_CLASS_EXEC);
MODULE_CALL_HOOK(raidframe_ioctl_50_hook,
(rs, cmd, data), enosys(), retcode);
if (retcode != EPASSTHROUGH)
return retcode;
break; /* fall through to the os-specific code below */
}

View File

@ -1,4 +1,4 @@
/* $NetBSD: compat_stub.c,v 1.7 2019/02/03 08:02:24 pgoyette Exp $ */
/* $NetBSD: compat_stub.c,v 1.8 2019/02/05 23:28:02 christos Exp $ */
/*-
* Copyright (c) 2018 The NetBSD Foundation, Inc.
@ -114,7 +114,7 @@ struct ocryptof_50_hook_t ocryptof_50_hook;
*/
struct raidframe_ioctl_50_hook_t raidframe_ioctl_50_hook;
struct raidframe_ioctl_80_hook_t raidframe_ioctl_80_hook;
struct raidframe_netbsd32_config_hook_t raidframe_netbsd32_config_hook;
struct raidframe_netbsd32_ioctl_hook_t raidframe_netbsd32_ioctl_hook;
/*
* puffs compatability

View File

@ -1,4 +1,4 @@
/* $NetBSD: compat_stub.h,v 1.10 2019/02/03 08:02:25 pgoyette Exp $ */
/* $NetBSD: compat_stub.h,v 1.11 2019/02/05 23:28:02 christos Exp $ */
/*-
* Copyright (c) 2018 The NetBSD Foundation, Inc.
@ -127,17 +127,13 @@ MODULE_HOOK(ocryptof_50_hook, int, (struct file *, u_long, void *));
/*
* raidframe compatibility
*/
struct RF_Config_s;
struct RF_Raid_s;
struct RF_Config_s;
struct raid_softc;
MODULE_HOOK(raidframe_ioctl_50_hook, int,
(u_long, int, struct RF_Raid_s *, int, void *, struct RF_Config_s **));
(struct raid_softc *, u_long, void *));
MODULE_HOOK(raidframe_ioctl_80_hook, int,
(u_long, int, struct RF_Raid_s *, int, void *, struct RF_Config_s **));
MODULE_HOOK(raidframe_netbsd32_config_hook, int,
(void *, struct RF_Config_s *));
(struct raid_softc *, u_long, void *));
MODULE_HOOK(raidframe_netbsd32_ioctl_hook, int,
(struct raid_softc *, u_long, void *));
/*
* puffs compatibility