version 1.356.4.4, 2020/04/21 18:42:37 |
version 1.357, 2019/01/08 07:18:18 |
|
|
__KERNEL_RCSID(0, "$NetBSD$"); |
__KERNEL_RCSID(0, "$NetBSD$"); |
|
|
#ifdef _KERNEL_OPT |
#ifdef _KERNEL_OPT |
#include "opt_raid_autoconfig.h" |
#include "opt_compat_netbsd.h" |
#include "opt_compat_netbsd32.h" |
#include "opt_compat_netbsd32.h" |
|
#include "opt_raid_autoconfig.h" |
#endif |
#endif |
|
|
#include <sys/param.h> |
#include <sys/param.h> |
Line 127 __KERNEL_RCSID(0, "$NetBSD$"); |
|
Line 128 __KERNEL_RCSID(0, "$NetBSD$"); |
|
#include <sys/reboot.h> |
#include <sys/reboot.h> |
#include <sys/kauth.h> |
#include <sys/kauth.h> |
#include <sys/module.h> |
#include <sys/module.h> |
#include <sys/compat_stub.h> |
|
|
|
#include <prop/proplib.h> |
#include <prop/proplib.h> |
|
|
Line 149 __KERNEL_RCSID(0, "$NetBSD$"); |
|
Line 149 __KERNEL_RCSID(0, "$NetBSD$"); |
|
#include "rf_parityscan.h" |
#include "rf_parityscan.h" |
#include "rf_threadstuff.h" |
#include "rf_threadstuff.h" |
|
|
|
#ifdef COMPAT_50 |
|
#include "rf_compat50.h" |
|
#endif |
|
|
|
#ifdef COMPAT_80 |
|
#include "rf_compat80.h" |
|
#endif |
|
|
|
#ifdef COMPAT_NETBSD32 |
|
#include "rf_compat32.h" |
|
#endif |
|
|
#include "ioconf.h" |
#include "ioconf.h" |
|
|
#ifdef DEBUG |
#ifdef DEBUG |
Line 182 static void KernelWakeupFunc(struct buf |
|
Line 194 static void KernelWakeupFunc(struct buf |
|
static void InitBP(struct buf *, struct vnode *, unsigned, |
static void InitBP(struct buf *, struct vnode *, unsigned, |
dev_t, RF_SectorNum_t, RF_SectorCount_t, void *, void (*) (struct buf *), |
dev_t, RF_SectorNum_t, RF_SectorCount_t, void *, void (*) (struct buf *), |
void *, int, struct proc *); |
void *, int, struct proc *); |
|
struct raid_softc; |
static void raidinit(struct raid_softc *); |
static void raidinit(struct raid_softc *); |
static int raiddoaccess(RF_Raid_t *raidPtr, struct buf *bp); |
static int raiddoaccess(RF_Raid_t *raidPtr, struct buf *bp); |
static int rf_get_component_caches(RF_Raid_t *raidPtr, int *); |
static int rf_get_component_caches(RF_Raid_t *raidPtr, int *); |
Line 249 static struct dkdriver rf_dkdriver = { |
|
Line 262 static struct dkdriver rf_dkdriver = { |
|
.d_minphys = minphys |
.d_minphys = minphys |
}; |
}; |
|
|
|
struct raid_softc { |
|
struct dk_softc sc_dksc; |
|
int sc_unit; |
|
int sc_flags; /* flags */ |
|
int sc_cflags; /* configuration flags */ |
|
kmutex_t sc_mutex; /* interlock mutex */ |
|
kcondvar_t sc_cv; /* and the condvar */ |
|
uint64_t sc_size; /* size of the raid device */ |
|
char sc_xname[20]; /* XXX external name */ |
|
RF_Raid_t sc_r; |
|
LIST_ENTRY(raid_softc) sc_link; |
|
}; |
|
/* sc_flags */ |
|
#define RAIDF_INITED 0x01 /* unit has been initialized */ |
|
#define RAIDF_SHUTDOWN 0x02 /* unit is being shutdown */ |
|
#define RAIDF_DETACH 0x04 /* detach after final close */ |
|
#define RAIDF_WANTED 0x08 /* someone waiting to obtain a lock */ |
|
#define RAIDF_LOCKED 0x10 /* unit is locked */ |
|
#define RAIDF_UNIT_CHANGED 0x20 /* unit is being changed */ |
|
|
#define raidunit(x) DISKUNIT(x) |
#define raidunit(x) DISKUNIT(x) |
#define raidsoftc(dev) (((struct raid_softc *)device_private(dev))->sc_r.softc) |
#define raidsoftc(dev) (((struct raid_softc *)device_private(dev))->sc_r.softc) |
|
|
Line 370 raidget(int unit, bool create) { |
|
Line 403 raidget(int unit, bool create) { |
|
mutex_exit(&raid_lock); |
mutex_exit(&raid_lock); |
if (!create) |
if (!create) |
return NULL; |
return NULL; |
sc = raidcreate(unit); |
if ((sc = raidcreate(unit)) == NULL) |
|
return NULL; |
mutex_enter(&raid_lock); |
mutex_enter(&raid_lock); |
LIST_INSERT_HEAD(&raids, sc, sc_link); |
LIST_INSERT_HEAD(&raids, sc, sc_link); |
mutex_exit(&raid_lock); |
mutex_exit(&raid_lock); |
Line 433 rf_autoconfig(device_t self) |
|
Line 467 rf_autoconfig(device_t self) |
|
return 1; |
return 1; |
} |
} |
|
|
int |
|
rf_inited(const struct raid_softc *rs) { |
|
return (rs->sc_flags & RAIDF_INITED) != 0; |
|
} |
|
|
|
RF_Raid_t * |
|
rf_get_raid(struct raid_softc *rs) { |
|
return &rs->sc_r; |
|
} |
|
|
|
int |
|
rf_get_unit(const struct raid_softc *rs) { |
|
return rs->sc_unit; |
|
} |
|
|
|
static int |
static int |
rf_containsboot(RF_Raid_t *r, device_t bdv) { |
rf_containsboot(RF_Raid_t *r, device_t bdv) { |
const char *bootname; |
const char *bootname = device_xname(bdv); |
size_t len; |
size_t len = strlen(bootname); |
|
|
/* if bdv is NULL, the set can't contain it. exit early. */ |
|
if (bdv == NULL) |
|
return 0; |
|
|
|
bootname = device_xname(bdv); |
|
len = strlen(bootname); |
|
|
|
for (int col = 0; col < r->numCol; col++) { |
for (int col = 0; col < r->numCol; col++) { |
const char *devname = r->Disks[col].devname; |
const char *devname = r->Disks[col].devname; |
Line 486 rf_buildroothack(RF_ConfigSet_t *config_ |
|
Line 498 rf_buildroothack(RF_ConfigSet_t *config_ |
|
RF_ConfigSet_t *next_cset; |
RF_ConfigSet_t *next_cset; |
int num_root; |
int num_root; |
struct raid_softc *sc, *rsc; |
struct raid_softc *sc, *rsc; |
struct dk_softc *dksc = NULL; /* XXX gcc -Os: may be used uninit. */ |
struct dk_softc *dksc; |
|
|
sc = rsc = NULL; |
sc = rsc = NULL; |
num_root = 0; |
num_root = 0; |
Line 497 rf_buildroothack(RF_ConfigSet_t *config_ |
|
Line 509 rf_buildroothack(RF_ConfigSet_t *config_ |
|
cset->ac->clabel->autoconfigure == 1) { |
cset->ac->clabel->autoconfigure == 1) { |
sc = rf_auto_config_set(cset); |
sc = rf_auto_config_set(cset); |
if (sc != NULL) { |
if (sc != NULL) { |
aprint_debug("raid%d: configured ok, rootable %d\n", |
aprint_debug("raid%d: configured ok\n", |
sc->sc_unit, cset->rootable); |
sc->sc_unit); |
if (cset->rootable) { |
if (cset->rootable) { |
rsc = sc; |
rsc = sc; |
num_root++; |
num_root++; |
Line 517 rf_buildroothack(RF_ConfigSet_t *config_ |
|
Line 529 rf_buildroothack(RF_ConfigSet_t *config_ |
|
rf_cleanup_config_set(cset); |
rf_cleanup_config_set(cset); |
cset = next_cset; |
cset = next_cset; |
} |
} |
|
dksc = &rsc->sc_dksc; |
|
|
/* if the user has specified what the root device should be |
/* if the user has specified what the root device should be |
then we don't touch booted_device or boothowto... */ |
then we don't touch booted_device or boothowto... */ |
|
|
if (rootspec != NULL) { |
if (rootspec != NULL) |
DPRINTF("%s: rootspec %s\n", __func__, rootspec); |
|
return; |
return; |
} |
|
|
|
/* we found something bootable... */ |
/* we found something bootable... */ |
|
|
Line 541 rf_buildroothack(RF_ConfigSet_t *config_ |
|
Line 552 rf_buildroothack(RF_ConfigSet_t *config_ |
|
*/ |
*/ |
if (num_root == 1) { |
if (num_root == 1) { |
device_t candidate_root; |
device_t candidate_root; |
dksc = &rsc->sc_dksc; |
|
if (dksc->sc_dkdev.dk_nwedges != 0) { |
if (dksc->sc_dkdev.dk_nwedges != 0) { |
char cname[sizeof(cset->ac->devname)]; |
char cname[sizeof(cset->ac->devname)]; |
/* XXX: assume partition 'a' first */ |
/* XXX: assume partition 'a' first */ |
Line 567 rf_buildroothack(RF_ConfigSet_t *config_ |
|
Line 577 rf_buildroothack(RF_ConfigSet_t *config_ |
|
candidate_root = dksc->sc_dev; |
candidate_root = dksc->sc_dev; |
DPRINTF("%s: candidate root=%p\n", __func__, candidate_root); |
DPRINTF("%s: candidate root=%p\n", __func__, candidate_root); |
DPRINTF("%s: booted_device=%p root_partition=%d " |
DPRINTF("%s: booted_device=%p root_partition=%d " |
"contains_boot=%d", |
"contains_boot=%d\n", __func__, booted_device, |
__func__, booted_device, rsc->sc_r.root_partition, |
rsc->sc_r.root_partition, |
rf_containsboot(&rsc->sc_r, booted_device)); |
rf_containsboot(&rsc->sc_r, booted_device)); |
/* XXX the check for booted_device == NULL can probably be |
|
* dropped, now that rf_containsboot handles that case. |
|
*/ |
|
if (booted_device == NULL || |
if (booted_device == NULL || |
rsc->sc_r.root_partition == 1 || |
rsc->sc_r.root_partition == 1 || |
rf_containsboot(&rsc->sc_r, booted_device)) { |
rf_containsboot(&rsc->sc_r, booted_device)) { |
Line 662 raiddump(dev_t dev, daddr_t blkno, void |
|
Line 669 raiddump(dev_t dev, daddr_t blkno, void |
|
*/ |
*/ |
blkno += RF_PROTECTED_SECTORS; |
blkno += RF_PROTECTED_SECTORS; |
|
|
return dk_dump(dksc, dev, blkno, va, size, DK_DUMP_RECURSIVE); |
return dk_dump(dksc, dev, blkno, va, size); |
} |
} |
|
|
static int |
static int |
Line 1033 raid_detach_unlocked(struct raid_softc * |
|
Line 1040 raid_detach_unlocked(struct raid_softc * |
|
return 0; |
return 0; |
} |
} |
|
|
static bool |
static int |
rf_must_be_initialized(const struct raid_softc *rs, u_long cmd) |
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_Raid_t *raidPtr; |
|
RF_RaidDisk_t *diskPtr; |
|
RF_AccTotals_t *totals; |
|
RF_DeviceConfig_t *d_cfg, *ucfgp; |
|
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; |
|
RF_SingleComponent_t *sparePtr,*componentPtr; |
|
RF_SingleComponent_t component; |
|
int d; |
|
|
|
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)); |
|
|
|
/* Must be initialized for these... */ |
switch (cmd) { |
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_ADD_HOT_SPARE: |
case RAIDFRAME_CHECK_COPYBACK_STATUS: |
case RAIDFRAME_REMOVE_HOT_SPARE: |
case RAIDFRAME_CHECK_COPYBACK_STATUS_EXT: |
case RAIDFRAME_INIT_LABELS: |
|
case RAIDFRAME_REBUILD_IN_PLACE: |
case RAIDFRAME_CHECK_PARITY: |
case RAIDFRAME_CHECK_PARITY: |
case RAIDFRAME_CHECK_PARITYREWRITE_STATUS: |
case RAIDFRAME_CHECK_PARITYREWRITE_STATUS: |
case RAIDFRAME_CHECK_PARITYREWRITE_STATUS_EXT: |
case RAIDFRAME_CHECK_PARITYREWRITE_STATUS_EXT: |
case RAIDFRAME_CHECK_RECON_STATUS: |
case RAIDFRAME_CHECK_COPYBACK_STATUS: |
case RAIDFRAME_CHECK_RECON_STATUS_EXT: |
case RAIDFRAME_CHECK_COPYBACK_STATUS_EXT: |
case RAIDFRAME_COPYBACK: |
case RAIDFRAME_SET_AUTOCONFIG: |
|
case RAIDFRAME_SET_ROOT: |
case RAIDFRAME_DELETE_COMPONENT: |
case RAIDFRAME_DELETE_COMPONENT: |
case RAIDFRAME_FAIL_DISK: |
|
case RAIDFRAME_GET_ACCTOTALS: |
|
case RAIDFRAME_GET_COMPONENT_LABEL: |
|
case RAIDFRAME_GET_INFO: |
|
case RAIDFRAME_GET_SIZE: |
|
case RAIDFRAME_INCORPORATE_HOT_SPARE: |
case RAIDFRAME_INCORPORATE_HOT_SPARE: |
case RAIDFRAME_INIT_LABELS: |
case RAIDFRAME_PARITYMAP_STATUS: |
case RAIDFRAME_KEEP_ACCTOTALS: |
|
case RAIDFRAME_PARITYMAP_GET_DISABLE: |
case RAIDFRAME_PARITYMAP_GET_DISABLE: |
case RAIDFRAME_PARITYMAP_SET_DISABLE: |
case RAIDFRAME_PARITYMAP_SET_DISABLE: |
case RAIDFRAME_PARITYMAP_SET_PARAMS: |
case RAIDFRAME_PARITYMAP_SET_PARAMS: |
case RAIDFRAME_PARITYMAP_STATUS: |
#ifdef COMPAT_50 |
case RAIDFRAME_REBUILD_IN_PLACE: |
case RAIDFRAME_GET_INFO50: |
case RAIDFRAME_REMOVE_HOT_SPARE: |
#endif |
case RAIDFRAME_RESET_ACCTOTALS: |
#ifdef COMPAT_80 |
case RAIDFRAME_REWRITEPARITY: |
case RAIDFRAME_CHECK_RECON_STATUS_EXT80: |
case RAIDFRAME_SET_AUTOCONFIG: |
case RAIDFRAME_CHECK_PARITYREWRITE_STATUS_EXT80: |
case RAIDFRAME_SET_COMPONENT_LABEL: |
case RAIDFRAME_CHECK_COPYBACK_STATUS_EXT80: |
case RAIDFRAME_SET_ROOT: |
case RAIDFRAME_GET_INFO80: |
return (rs->sc_flags & RAIDF_INITED) == 0; |
case RAIDFRAME_GET_COMPONENT_LABEL80: |
} |
#endif |
return false; |
#ifdef COMPAT_NETBSD32 |
} |
#ifdef _LP64 |
|
case RAIDFRAME_GET_INFO32: |
int |
#endif |
rf_fail_disk(RF_Raid_t *raidPtr, struct rf_recon_req *rr) |
#endif |
{ |
if ((rs->sc_flags & RAIDF_INITED) == 0) |
struct rf_recon_req_internal *rrint; |
return (ENXIO); |
|
|
if (raidPtr->Layout.map->faultsTolerated == 0) { |
|
/* Can't do this on a RAID 0!! */ |
|
return EINVAL; |
|
} |
} |
|
|
if (rr->col < 0 || rr->col >= raidPtr->numCol) { |
switch (cmd) { |
/* bad column */ |
#ifdef COMPAT_50 |
return EINVAL; |
case RAIDFRAME_GET_INFO50: |
} |
return rf_get_info50(raidPtr, data); |
|
|
rf_lock_mutex2(raidPtr->mutex); |
case RAIDFRAME_CONFIGURE50: |
if (raidPtr->status == rf_rs_reconstructing) { |
if ((retcode = rf_config50(raidPtr, unit, data, &k_cfg)) != 0) |
/* you can't fail a disk while we're reconstructing! */ |
return retcode; |
/* XXX wrong for RAID6 */ |
goto config; |
goto out; |
#endif |
} |
|
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 |
#ifdef COMPAT_80 |
* the user's buffer */ |
case RAIDFRAME_CHECK_RECON_STATUS_EXT80: |
rrint = RF_Malloc(sizeof(*rrint)); |
return rf_check_recon_status_ext80(raidPtr, data); |
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, |
case RAIDFRAME_CHECK_PARITYREWRITE_STATUS_EXT80: |
rrint, "raid_recon"); |
return rf_check_parityrewrite_status_ext80(raidPtr, data); |
out: |
|
rf_unlock_mutex2(raidPtr->mutex); |
|
return EINVAL; |
|
} |
|
|
|
static int |
case RAIDFRAME_CHECK_COPYBACK_STATUS_EXT80: |
rf_copyinspecificbuf(RF_Config_t *k_cfg) |
return rf_check_copyback_status_ext80(raidPtr, data); |
{ |
|
/* allocate a buffer for the layout-specific data, and copy it in */ |
|
if (k_cfg->layoutSpecificSize == 0) |
|
return 0; |
|
|
|
if (k_cfg->layoutSpecificSize > 10000) { |
case RAIDFRAME_GET_INFO80: |
/* sanity check */ |
return rf_get_info80(raidPtr, data); |
return EINVAL; |
|
} |
|
|
|
u_char *specific_buf; |
case RAIDFRAME_GET_COMPONENT_LABEL80: |
specific_buf = RF_Malloc(k_cfg->layoutSpecificSize); |
return rf_get_component_label80(raidPtr, data); |
if (specific_buf == NULL) |
|
return ENOMEM; |
|
|
|
int retcode = copyin(k_cfg->layoutSpecific, specific_buf, |
case RAIDFRAME_CONFIGURE80: |
k_cfg->layoutSpecificSize); |
if ((retcode = rf_config80(raidPtr, unit, data, &k_cfg)) != 0) |
if (retcode) { |
return retcode; |
RF_Free(specific_buf, k_cfg->layoutSpecificSize); |
goto config; |
db1_printf(("%s: retcode=%d copyin.2\n", __func__, retcode)); |
#endif |
return retcode; |
|
} |
|
|
|
k_cfg->layoutSpecific = specific_buf; |
/* configure the system */ |
return 0; |
case RAIDFRAME_CONFIGURE: |
} |
#ifdef COMPAT_NETBSD32 |
|
#ifdef _LP64 |
|
case RAIDFRAME_CONFIGURE32: |
|
#endif |
|
#endif |
|
|
static int |
if (raidPtr->valid) { |
rf_getConfiguration(struct raid_softc *rs, void *data, RF_Config_t **k_cfg) |
/* There is a valid RAID set running on this unit! */ |
{ |
printf("raid%d: Device already configured!\n",unit); |
RF_Config_t *u_cfg = *((RF_Config_t **) data); |
return(EINVAL); |
|
} |
|
|
if (rs->sc_r.valid) { |
/* copy-in the configuration information */ |
/* There is a valid RAID set running on this unit! */ |
/* data points to a pointer to the configuration structure */ |
printf("raid%d: Device already configured!\n", rs->sc_unit); |
|
return EINVAL; |
|
} |
|
|
|
/* copy-in the configuration information */ |
RF_Malloc(k_cfg, sizeof(RF_Config_t), (RF_Config_t *)); |
/* data points to a pointer to the configuration structure */ |
if (k_cfg == NULL) { |
*k_cfg = RF_Malloc(sizeof(**k_cfg)); |
return (ENOMEM); |
if (*k_cfg == NULL) { |
} |
return ENOMEM; |
#ifdef COMPAT_NETBSD32 |
} |
#ifdef _LP64 |
int retcode = copyin(u_cfg, *k_cfg, sizeof(RF_Config_t)); |
if (cmd == RAIDFRAME_CONFIGURE32 && |
if (retcode == 0) |
(l->l_proc->p_flag & PK_32) != 0) |
return 0; |
retcode = rf_config_netbsd32(data, k_cfg); |
RF_Free(*k_cfg, sizeof(RF_Config_t)); |
else |
db1_printf(("%s: retcode=%d copyin.1\n", __func__, retcode)); |
#endif |
rs->sc_flags |= RAIDF_SHUTDOWN; |
#endif |
return retcode; |
{ |
} |
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; |
|
|
int |
/* should do some kind of sanity check on the configuration. |
rf_construct(struct raid_softc *rs, RF_Config_t *k_cfg) |
* Store the sum of all the bytes in the last byte? */ |
{ |
|
int retcode; |
|
RF_Raid_t *raidPtr = &rs->sc_r; |
|
|
|
rs->sc_flags &= ~RAIDF_SHUTDOWN; |
/* configure the system */ |
|
|
if ((retcode = rf_copyinspecificbuf(k_cfg)) != 0) |
/* |
goto out; |
* 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; |
|
|
/* should do some kind of sanity check on the configuration. |
retcode = rf_Configure(raidPtr, k_cfg, NULL); |
* Store the sum of all the bytes in the last byte? */ |
|
|
|
/* configure the system */ |
if (retcode == 0) { |
|
|
/* |
/* allow this many simultaneous IO's to |
* Clear the entire RAID descriptor, just to make sure |
this RAID device */ |
* there is no stale data left in the case of a |
raidPtr->openings = RAIDOUTSTANDING; |
* 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); |
raidinit(rs); |
raid_wakeup(raidPtr); |
raid_wakeup(raidPtr); |
rf_markalldirty(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)); |
|
|
/* free the buffers. No return code here. */ |
no_config: |
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 |
* If configuration failed, set sc_flags so that we |
* will detach the device when we close it. |
* will detach the device when we close it. |
*/ |
*/ |
rs->sc_flags |= RAIDF_SHUTDOWN; |
if (retcode != 0) |
} |
rs->sc_flags |= RAIDF_SHUTDOWN; |
return retcode; |
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; |
|
rrint = RF_Malloc(sizeof(*rrint)); |
|
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 part, pmask; |
|
struct raid_softc *rs; |
|
struct dk_softc *dksc; |
|
RF_Config_t *k_cfg; |
|
RF_Raid_t *raidPtr; |
|
RF_AccTotals_t *totals; |
|
RF_SingleComponent_t component; |
|
RF_DeviceConfig_t *d_cfg, *ucfgp; |
|
int retcode = 0; |
|
int column; |
|
RF_ComponentLabel_t *clabel; |
|
RF_SingleComponent_t *sparePtr,*componentPtr; |
|
int d; |
|
|
|
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)); |
|
|
|
/* Must be initialized for these... */ |
|
if (rf_must_be_initialized(rs, cmd)) |
|
return ENXIO; |
|
|
|
switch (cmd) { |
|
/* configure the system */ |
|
case RAIDFRAME_CONFIGURE: |
|
if ((retcode = rf_getConfiguration(rs, data, &k_cfg)) != 0) |
|
return retcode; |
|
return rf_construct(rs, k_cfg); |
|
|
|
/* shutdown the system */ |
/* shutdown the system */ |
case RAIDFRAME_SHUTDOWN: |
case RAIDFRAME_SHUTDOWN: |
Line 1433 raidioctl(dev_t dev, u_long cmd, void *d |
|
Line 1276 raidioctl(dev_t dev, u_long cmd, void *d |
|
part = DISKPART(dev); |
part = DISKPART(dev); |
pmask = (1 << part); |
pmask = (1 << part); |
|
|
if ((retcode = raidlock(rs)) != 0) |
if ((error = raidlock(rs)) != 0) |
return retcode; |
return (error); |
|
|
if (DK_BUSY(dksc, pmask) || |
if (DK_BUSY(dksc, pmask) || |
raidPtr->recon_in_progress != 0 || |
raidPtr->recon_in_progress != 0 || |
Line 1449 raidioctl(dev_t dev, u_long cmd, void *d |
|
Line 1292 raidioctl(dev_t dev, u_long cmd, void *d |
|
|
|
raidunlock(rs); |
raidunlock(rs); |
|
|
return retcode; |
return (retcode); |
case RAIDFRAME_GET_COMPONENT_LABEL: |
case RAIDFRAME_GET_COMPONENT_LABEL: |
return rf_get_component_label(raidPtr, data); |
return rf_get_component_label(raidPtr, data); |
|
|
#if RF_DISABLED |
#if 0 |
case RAIDFRAME_SET_COMPONENT_LABEL: |
case RAIDFRAME_SET_COMPONENT_LABEL: |
return rf_set_component_label(raidPtr, data); |
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 |
|
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 |
#endif |
|
|
case RAIDFRAME_INIT_LABELS: |
case RAIDFRAME_INIT_LABELS: |
return rf_init_component_label(raidPtr, data); |
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. |
|
*/ |
|
|
|
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: |
case RAIDFRAME_SET_AUTOCONFIG: |
d = rf_set_autoconfig(raidPtr, *(int *) data); |
d = rf_set_autoconfig(raidPtr, *(int *) data); |
printf("raid%d: New autoconfig value is: %d\n", |
printf("raid%d: New autoconfig value is: %d\n", |
raidPtr->raidid, d); |
raidPtr->raidid, d); |
*(int *) data = d; |
*(int *) data = d; |
return retcode; |
return (retcode); |
|
|
case RAIDFRAME_SET_ROOT: |
case RAIDFRAME_SET_ROOT: |
d = rf_set_rootpartition(raidPtr, *(int *) data); |
d = rf_set_rootpartition(raidPtr, *(int *) data); |
printf("raid%d: New rootpartition value is: %d\n", |
printf("raid%d: New rootpartition value is: %d\n", |
raidPtr->raidid, d); |
raidPtr->raidid, d); |
*(int *) data = d; |
*(int *) data = d; |
return retcode; |
return (retcode); |
|
|
/* initialize all parity */ |
/* initialize all parity */ |
case RAIDFRAME_REWRITEPARITY: |
case RAIDFRAME_REWRITEPARITY: |
Line 1481 raidioctl(dev_t dev, u_long cmd, void *d |
|
Line 1385 raidioctl(dev_t dev, u_long cmd, void *d |
|
if (raidPtr->Layout.map->faultsTolerated == 0) { |
if (raidPtr->Layout.map->faultsTolerated == 0) { |
/* Parity for RAID 0 is trivially correct */ |
/* Parity for RAID 0 is trivially correct */ |
raidPtr->parity_good = RF_RAID_CLEAN; |
raidPtr->parity_good = RF_RAID_CLEAN; |
return 0; |
return(0); |
} |
} |
|
|
if (raidPtr->parity_rewrite_in_progress == 1) { |
if (raidPtr->parity_rewrite_in_progress == 1) { |
/* Re-write is already in progress! */ |
/* Re-write is already in progress! */ |
return EINVAL; |
return(EINVAL); |
} |
} |
|
|
return RF_CREATE_THREAD(raidPtr->parity_rewrite_thread, |
retcode = RF_CREATE_THREAD(raidPtr->parity_rewrite_thread, |
rf_RewriteParityThread, raidPtr,"raid_parity"); |
rf_RewriteParityThread, |
|
raidPtr,"raid_parity"); |
|
return (retcode); |
|
|
|
|
case RAIDFRAME_ADD_HOT_SPARE: |
case RAIDFRAME_ADD_HOT_SPARE: |
sparePtr = (RF_SingleComponent_t *) data; |
sparePtr = (RF_SingleComponent_t *) data; |
memcpy(&component, sparePtr, sizeof(RF_SingleComponent_t)); |
memcpy( &component, sparePtr, sizeof(RF_SingleComponent_t)); |
return rf_add_hot_spare(raidPtr, &component); |
retcode = rf_add_hot_spare(raidPtr, &component); |
|
return(retcode); |
|
|
case RAIDFRAME_REMOVE_HOT_SPARE: |
case RAIDFRAME_REMOVE_HOT_SPARE: |
return retcode; |
return(retcode); |
|
|
case RAIDFRAME_DELETE_COMPONENT: |
case RAIDFRAME_DELETE_COMPONENT: |
componentPtr = (RF_SingleComponent_t *)data; |
componentPtr = (RF_SingleComponent_t *)data; |
memcpy(&component, componentPtr, sizeof(RF_SingleComponent_t)); |
memcpy( &component, componentPtr, |
return rf_delete_component(raidPtr, &component); |
sizeof(RF_SingleComponent_t)); |
|
retcode = rf_delete_component(raidPtr, &component); |
|
return(retcode); |
|
|
case RAIDFRAME_INCORPORATE_HOT_SPARE: |
case RAIDFRAME_INCORPORATE_HOT_SPARE: |
componentPtr = (RF_SingleComponent_t *)data; |
componentPtr = (RF_SingleComponent_t *)data; |
memcpy(&component, componentPtr, sizeof(RF_SingleComponent_t)); |
memcpy( &component, componentPtr, |
return rf_incorporate_hot_spare(raidPtr, &component); |
sizeof(RF_SingleComponent_t)); |
|
retcode = rf_incorporate_hot_spare(raidPtr, &component); |
|
return(retcode); |
|
|
case RAIDFRAME_REBUILD_IN_PLACE: |
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); |
|
|
case RAIDFRAME_GET_INFO: |
case RAIDFRAME_GET_INFO: |
ucfgp = *(RF_DeviceConfig_t **)data; |
#ifdef COMPAT_NETBSD32 |
d_cfg = RF_Malloc(sizeof(*d_cfg)); |
#ifdef _LP64 |
|
case RAIDFRAME_GET_INFO32: |
|
#endif |
|
#endif |
|
RF_Malloc(d_cfg, sizeof(RF_DeviceConfig_t), |
|
(RF_DeviceConfig_t *)); |
if (d_cfg == NULL) |
if (d_cfg == NULL) |
return ENOMEM; |
return (ENOMEM); |
retcode = rf_get_info(raidPtr, d_cfg); |
retcode = rf_get_info(raidPtr, d_cfg); |
if (retcode == 0) { |
if (retcode == 0) { |
retcode = copyout(d_cfg, ucfgp, sizeof(*d_cfg)); |
#ifdef COMPAT_NETBSD32 |
|
#ifdef _LP64 |
|
if (cmd == RAIDFRAME_GET_INFO32) |
|
ucfgp = NETBSD32PTR64(*(netbsd32_pointer_t *)data); |
|
else |
|
#endif |
|
#endif |
|
ucfgp = *(RF_DeviceConfig_t **)data; |
|
retcode = copyout(d_cfg, ucfgp, sizeof(RF_DeviceConfig_t)); |
} |
} |
RF_Free(d_cfg, sizeof(RF_DeviceConfig_t)); |
RF_Free(d_cfg, sizeof(RF_DeviceConfig_t)); |
return retcode; |
|
|
return (retcode); |
|
|
case RAIDFRAME_CHECK_PARITY: |
case RAIDFRAME_CHECK_PARITY: |
*(int *) data = raidPtr->parity_good; |
*(int *) data = raidPtr->parity_good; |
return 0; |
return (0); |
|
|
case RAIDFRAME_PARITYMAP_STATUS: |
case RAIDFRAME_PARITYMAP_STATUS: |
if (rf_paritymap_ineligible(raidPtr)) |
if (rf_paritymap_ineligible(raidPtr)) |
return EINVAL; |
return EINVAL; |
rf_paritymap_status(raidPtr->parity_map, data); |
rf_paritymap_status(raidPtr->parity_map, |
|
(struct rf_pmstat *)data); |
return 0; |
return 0; |
|
|
case RAIDFRAME_PARITYMAP_SET_PARAMS: |
case RAIDFRAME_PARITYMAP_SET_PARAMS: |
Line 1540 raidioctl(dev_t dev, u_long cmd, void *d |
|
Line 1527 raidioctl(dev_t dev, u_long cmd, void *d |
|
return EINVAL; |
return EINVAL; |
if (raidPtr->parity_map == NULL) |
if (raidPtr->parity_map == NULL) |
return ENOENT; /* ??? */ |
return ENOENT; /* ??? */ |
if (rf_paritymap_set_params(raidPtr->parity_map, data, 1) != 0) |
if (0 != rf_paritymap_set_params(raidPtr->parity_map, |
|
(struct rf_pmparams *)data, 1)) |
return EINVAL; |
return EINVAL; |
return 0; |
return 0; |
|
|
Line 1559 raidioctl(dev_t dev, u_long cmd, void *d |
|
Line 1547 raidioctl(dev_t dev, u_long cmd, void *d |
|
|
|
case RAIDFRAME_RESET_ACCTOTALS: |
case RAIDFRAME_RESET_ACCTOTALS: |
memset(&raidPtr->acc_totals, 0, sizeof(raidPtr->acc_totals)); |
memset(&raidPtr->acc_totals, 0, sizeof(raidPtr->acc_totals)); |
return 0; |
return (0); |
|
|
case RAIDFRAME_GET_ACCTOTALS: |
case RAIDFRAME_GET_ACCTOTALS: |
totals = (RF_AccTotals_t *) data; |
totals = (RF_AccTotals_t *) data; |
*totals = raidPtr->acc_totals; |
*totals = raidPtr->acc_totals; |
return 0; |
return (0); |
|
|
case RAIDFRAME_KEEP_ACCTOTALS: |
case RAIDFRAME_KEEP_ACCTOTALS: |
raidPtr->keep_acc_totals = *(int *)data; |
raidPtr->keep_acc_totals = *(int *)data; |
return 0; |
return (0); |
|
|
case RAIDFRAME_GET_SIZE: |
case RAIDFRAME_GET_SIZE: |
*(int *) data = raidPtr->totalSectors; |
*(int *) data = raidPtr->totalSectors; |
return 0; |
return (0); |
|
|
|
/* fail a disk & optionally start reconstruction */ |
case RAIDFRAME_FAIL_DISK: |
case RAIDFRAME_FAIL_DISK: |
return rf_fail_disk(raidPtr, data); |
#ifdef COMPAT_80 |
|
case RAIDFRAME_FAIL_DISK80: |
|
#endif |
|
|
|
if (raidPtr->Layout.map->faultsTolerated == 0) { |
|
/* Can't do this on a RAID 0!! */ |
|
return(EINVAL); |
|
} |
|
|
|
rr = (struct rf_recon_req *) data; |
|
if (rr->col < 0 || rr->col >= raidPtr->numCol) |
|
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 */ |
|
rf_unlock_mutex2(raidPtr->mutex); |
|
return (EINVAL); |
|
} |
|
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 */ |
|
rf_unlock_mutex2(raidPtr->mutex); |
|
return (EINVAL); |
|
} |
|
if (raidPtr->Disks[rr->col].status == rf_ds_spared) { |
|
/* Can't fail a spared disk! */ |
|
rf_unlock_mutex2(raidPtr->mutex); |
|
return (EINVAL); |
|
} |
|
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; |
|
|
|
retcode = RF_CREATE_THREAD(raidPtr->recon_thread, |
|
rf_ReconThread, |
|
rrint, "raid_recon"); |
|
return (0); |
|
|
/* invoke a copyback operation after recon on whatever disk |
/* invoke a copyback operation after recon on whatever disk |
* needs it, if any */ |
* needs it, if any */ |
Line 1583 raidioctl(dev_t dev, u_long cmd, void *d |
|
Line 1618 raidioctl(dev_t dev, u_long cmd, void *d |
|
|
|
if (raidPtr->Layout.map->faultsTolerated == 0) { |
if (raidPtr->Layout.map->faultsTolerated == 0) { |
/* This makes no sense on a RAID 0!! */ |
/* This makes no sense on a RAID 0!! */ |
return EINVAL; |
return(EINVAL); |
} |
} |
|
|
if (raidPtr->copyback_in_progress == 1) { |
if (raidPtr->copyback_in_progress == 1) { |
/* Copyback is already in progress! */ |
/* Copyback is already in progress! */ |
return EINVAL; |
return(EINVAL); |
} |
} |
|
|
return RF_CREATE_THREAD(raidPtr->copyback_thread, |
retcode = RF_CREATE_THREAD(raidPtr->copyback_thread, |
rf_CopybackThread, raidPtr, "raid_copyback"); |
rf_CopybackThread, |
|
raidPtr,"raid_copyback"); |
|
return (retcode); |
|
|
/* return the percentage completion of reconstruction */ |
/* return the percentage completion of reconstruction */ |
case RAIDFRAME_CHECK_RECON_STATUS: |
case RAIDFRAME_CHECK_RECON_STATUS: |
return rf_check_recon_status(raidPtr, data); |
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); |
case RAIDFRAME_CHECK_RECON_STATUS_EXT: |
case RAIDFRAME_CHECK_RECON_STATUS_EXT: |
rf_check_recon_status_ext(raidPtr, data); |
rf_check_recon_status_ext(raidPtr, data); |
return 0; |
return (0); |
|
|
case RAIDFRAME_CHECK_PARITYREWRITE_STATUS: |
case RAIDFRAME_CHECK_PARITYREWRITE_STATUS: |
if (raidPtr->Layout.map->faultsTolerated == 0) { |
if (raidPtr->Layout.map->faultsTolerated == 0) { |
/* This makes no sense on a RAID 0, so tell the |
/* This makes no sense on a RAID 0, so tell the |
user it's done. */ |
user it's done. */ |
*(int *) data = 100; |
*(int *) data = 100; |
return 0; |
return(0); |
} |
} |
if (raidPtr->parity_rewrite_in_progress == 1) { |
if (raidPtr->parity_rewrite_in_progress == 1) { |
*(int *) data = 100 * |
*(int *) data = 100 * |
Line 1616 raidioctl(dev_t dev, u_long cmd, void *d |
|
Line 1667 raidioctl(dev_t dev, u_long cmd, void *d |
|
} else { |
} else { |
*(int *) data = 100; |
*(int *) data = 100; |
} |
} |
return 0; |
return (0); |
|
|
case RAIDFRAME_CHECK_PARITYREWRITE_STATUS_EXT: |
case RAIDFRAME_CHECK_PARITYREWRITE_STATUS_EXT: |
rf_check_parityrewrite_status_ext(raidPtr, data); |
rf_check_parityrewrite_status_ext(raidPtr, data); |
return 0; |
return (0); |
|
|
case RAIDFRAME_CHECK_COPYBACK_STATUS: |
case RAIDFRAME_CHECK_COPYBACK_STATUS: |
if (raidPtr->Layout.map->faultsTolerated == 0) { |
if (raidPtr->Layout.map->faultsTolerated == 0) { |
/* This makes no sense on a RAID 0 */ |
/* This makes no sense on a RAID 0 */ |
*(int *) data = 100; |
*(int *) data = 100; |
return 0; |
return(0); |
} |
} |
if (raidPtr->copyback_in_progress == 1) { |
if (raidPtr->copyback_in_progress == 1) { |
*(int *) data = 100 * raidPtr->copyback_stripes_done / |
*(int *) data = 100 * raidPtr->copyback_stripes_done / |
Line 1634 raidioctl(dev_t dev, u_long cmd, void *d |
|
Line 1685 raidioctl(dev_t dev, u_long cmd, void *d |
|
} else { |
} else { |
*(int *) data = 100; |
*(int *) data = 100; |
} |
} |
return 0; |
return (0); |
|
|
case RAIDFRAME_CHECK_COPYBACK_STATUS_EXT: |
case RAIDFRAME_CHECK_COPYBACK_STATUS_EXT: |
rf_check_copyback_status_ext(raidPtr, data); |
rf_check_copyback_status_ext(raidPtr, data); |
Line 1660 raidioctl(dev_t dev, u_long cmd, void *d |
|
Line 1711 raidioctl(dev_t dev, u_long cmd, void *d |
|
* -- I should either compute the spare table in the kernel, |
* -- I should either compute the spare table in the kernel, |
* or have a different -- XXX XXX -- interface (a different |
* or have a different -- XXX XXX -- interface (a different |
* character device) for delivering the table -- XXX */ |
* character device) for delivering the table -- XXX */ |
#if RF_DISABLED |
#if 0 |
case RAIDFRAME_SPARET_WAIT: |
case RAIDFRAME_SPARET_WAIT: |
rf_lock_mutex2(rf_sparet_wait_mutex); |
rf_lock_mutex2(rf_sparet_wait_mutex); |
while (!rf_sparet_wait_queue) |
while (!rf_sparet_wait_queue) |
rf_wait_cond2(rf_sparet_wait_cv, rf_sparet_wait_mutex); |
rf_wait_cond2(rf_sparet_wait_cv, rf_sparet_wait_mutex); |
RF_SparetWait_t *waitreq = rf_sparet_wait_queue; |
waitreq = rf_sparet_wait_queue; |
rf_sparet_wait_queue = rf_sparet_wait_queue->next; |
rf_sparet_wait_queue = rf_sparet_wait_queue->next; |
rf_unlock_mutex2(rf_sparet_wait_mutex); |
rf_unlock_mutex2(rf_sparet_wait_mutex); |
|
|
Line 1673 raidioctl(dev_t dev, u_long cmd, void *d |
|
Line 1724 raidioctl(dev_t dev, u_long cmd, void *d |
|
*((RF_SparetWait_t *) data) = *waitreq; |
*((RF_SparetWait_t *) data) = *waitreq; |
|
|
RF_Free(waitreq, sizeof(*waitreq)); |
RF_Free(waitreq, sizeof(*waitreq)); |
return 0; |
return (0); |
|
|
/* wakes up a process waiting on SPARET_WAIT and puts an error |
/* wakes up a process waiting on SPARET_WAIT and puts an error |
* code in it that will cause the dameon to exit */ |
* code in it that will cause the dameon to exit */ |
case RAIDFRAME_ABORT_SPARET_WAIT: |
case RAIDFRAME_ABORT_SPARET_WAIT: |
waitreq = RF_Malloc(sizeof(*waitreq)); |
RF_Malloc(waitreq, sizeof(*waitreq), (RF_SparetWait_t *)); |
waitreq->fcol = -1; |
waitreq->fcol = -1; |
rf_lock_mutex2(rf_sparet_wait_mutex); |
rf_lock_mutex2(rf_sparet_wait_mutex); |
waitreq->next = rf_sparet_wait_queue; |
waitreq->next = rf_sparet_wait_queue; |
rf_sparet_wait_queue = waitreq; |
rf_sparet_wait_queue = waitreq; |
rf_broadcast_cond2(rf_sparet_wait_cv); |
rf_broadcast_conf2(rf_sparet_wait_cv); |
rf_unlock_mutex2(rf_sparet_wait_mutex); |
rf_unlock_mutex2(rf_sparet_wait_mutex); |
return 0; |
return (0); |
|
|
/* used by the spare table daemon to deliver a spare table |
/* used by the spare table daemon to deliver a spare table |
* into the kernel */ |
* into the kernel */ |
Line 1696 raidioctl(dev_t dev, u_long cmd, void *d |
|
Line 1747 raidioctl(dev_t dev, u_long cmd, void *d |
|
|
|
/* respond to the requestor. the return status of the spare |
/* respond to the requestor. the return status of the spare |
* table installation is passed in the "fcol" field */ |
* table installation is passed in the "fcol" field */ |
waitred = RF_Malloc(sizeof(*waitreq)); |
RF_Malloc(waitreq, sizeof(*waitreq), (RF_SparetWait_t *)); |
waitreq->fcol = retcode; |
waitreq->fcol = retcode; |
rf_lock_mutex2(rf_sparet_wait_mutex); |
rf_lock_mutex2(rf_sparet_wait_mutex); |
waitreq->next = rf_sparet_resp_queue; |
waitreq->next = rf_sparet_resp_queue; |
Line 1704 raidioctl(dev_t dev, u_long cmd, void *d |
|
Line 1755 raidioctl(dev_t dev, u_long cmd, void *d |
|
rf_broadcast_cond2(rf_sparet_resp_cv); |
rf_broadcast_cond2(rf_sparet_resp_cv); |
rf_unlock_mutex2(rf_sparet_wait_mutex); |
rf_unlock_mutex2(rf_sparet_wait_mutex); |
|
|
return retcode; |
return (retcode); |
#endif |
|
default: |
|
/* |
|
* Don't bother trying to load compat modules |
|
* if it is not our ioctl. This is more efficient |
|
* and makes rump tests not depend on compat code |
|
*/ |
|
if (IOCGROUP(cmd) != 'r') |
|
break; |
|
#ifdef _LP64 |
|
if ((l->l_proc->p_flag & PK_32) != 0) { |
|
module_autoload("compat_netbsd32_raid", |
|
MODULE_CLASS_EXEC); |
|
MODULE_HOOK_CALL(raidframe_netbsd32_ioctl_hook, |
|
(rs, cmd, data), enosys(), retcode); |
|
if (retcode != EPASSTHROUGH) |
|
return retcode; |
|
} |
|
#endif |
#endif |
module_autoload("compat_raid_80", MODULE_CLASS_EXEC); |
|
MODULE_HOOK_CALL(raidframe_ioctl_80_hook, |
|
(rs, cmd, data), enosys(), retcode); |
|
if (retcode != EPASSTHROUGH) |
|
return retcode; |
|
|
|
module_autoload("compat_raid_50", MODULE_CLASS_EXEC); |
default: |
MODULE_HOOK_CALL(raidframe_ioctl_50_hook, |
|
(rs, cmd, data), enosys(), retcode); |
|
if (retcode != EPASSTHROUGH) |
|
return retcode; |
|
break; /* fall through to the os-specific code below */ |
break; /* fall through to the os-specific code below */ |
|
|
} |
} |
Line 2712 rf_get_component(RF_AutoConfig_t *ac_lis |
|
Line 2736 rf_get_component(RF_AutoConfig_t *ac_lis |
|
RF_ComponentLabel_t *clabel; |
RF_ComponentLabel_t *clabel; |
RF_AutoConfig_t *ac; |
RF_AutoConfig_t *ac; |
|
|
clabel = malloc(sizeof(RF_ComponentLabel_t), M_RAIDFRAME, M_WAITOK); |
clabel = malloc(sizeof(RF_ComponentLabel_t), M_RAIDFRAME, M_NOWAIT); |
|
if (clabel == NULL) { |
|
oomem: |
|
while(ac_list) { |
|
ac = ac_list; |
|
if (ac->clabel) |
|
free(ac->clabel, M_RAIDFRAME); |
|
ac_list = ac_list->next; |
|
free(ac, M_RAIDFRAME); |
|
} |
|
printf("RAID auto config: out of memory!\n"); |
|
return NULL; /* XXX probably should panic? */ |
|
} |
|
|
if (!raidread_component_label(secsize, dev, vp, clabel)) { |
if (!raidread_component_label(secsize, dev, vp, clabel)) { |
/* Got the label. Does it look reasonable? */ |
/* Got the label. Does it look reasonable? */ |
Line 2725 rf_get_component(RF_AutoConfig_t *ac_lis |
|
Line 2761 rf_get_component(RF_AutoConfig_t *ac_lis |
|
#endif |
#endif |
/* if it's reasonable, add it, else ignore it. */ |
/* if it's reasonable, add it, else ignore it. */ |
ac = malloc(sizeof(RF_AutoConfig_t), M_RAIDFRAME, |
ac = malloc(sizeof(RF_AutoConfig_t), M_RAIDFRAME, |
M_WAITOK); |
M_NOWAIT); |
|
if (ac == NULL) { |
|
free(clabel, M_RAIDFRAME); |
|
goto oomem; |
|
} |
strlcpy(ac->devname, cname, sizeof(ac->devname)); |
strlcpy(ac->devname, cname, sizeof(ac->devname)); |
ac->dev = dev; |
ac->dev = dev; |
ac->vp = vp; |
ac->vp = vp; |
Line 2821 rf_find_raid_components(void) |
|
Line 2861 rf_find_raid_components(void) |
|
if (bdevvp(dev, &vp)) |
if (bdevvp(dev, &vp)) |
panic("RAID can't alloc vnode"); |
panic("RAID can't alloc vnode"); |
|
|
vn_lock(vp, LK_EXCLUSIVE | LK_RETRY); |
|
error = VOP_OPEN(vp, FREAD | FSILENT, NOCRED); |
error = VOP_OPEN(vp, FREAD | FSILENT, NOCRED); |
|
|
if (error) { |
if (error) { |
Line 2842 rf_find_raid_components(void) |
|
Line 2881 rf_find_raid_components(void) |
|
printf("RAIDframe: can't get disk size" |
printf("RAIDframe: can't get disk size" |
" for dev %s (%d)\n", |
" for dev %s (%d)\n", |
device_xname(dv), error); |
device_xname(dv), error); |
|
vn_lock(vp, LK_EXCLUSIVE | LK_RETRY); |
VOP_CLOSE(vp, FREAD | FWRITE, NOCRED); |
VOP_CLOSE(vp, FREAD | FWRITE, NOCRED); |
vput(vp); |
vput(vp); |
continue; |
continue; |
Line 2853 rf_find_raid_components(void) |
|
Line 2893 rf_find_raid_components(void) |
|
if (error) { |
if (error) { |
printf("RAIDframe: can't get wedge info for " |
printf("RAIDframe: can't get wedge info for " |
"dev %s (%d)\n", device_xname(dv), error); |
"dev %s (%d)\n", device_xname(dv), error); |
|
vn_lock(vp, LK_EXCLUSIVE | LK_RETRY); |
VOP_CLOSE(vp, FREAD | FWRITE, NOCRED); |
VOP_CLOSE(vp, FREAD | FWRITE, NOCRED); |
vput(vp); |
vput(vp); |
continue; |
continue; |
} |
} |
|
|
if (strcmp(dkw.dkw_ptype, DKW_PTYPE_RAIDFRAME) != 0) { |
if (strcmp(dkw.dkw_ptype, DKW_PTYPE_RAIDFRAME) != 0) { |
|
vn_lock(vp, LK_EXCLUSIVE | LK_RETRY); |
VOP_CLOSE(vp, FREAD | FWRITE, NOCRED); |
VOP_CLOSE(vp, FREAD | FWRITE, NOCRED); |
vput(vp); |
vput(vp); |
continue; |
continue; |
} |
} |
|
|
VOP_UNLOCK(vp); |
|
ac_list = rf_get_component(ac_list, dev, vp, |
ac_list = rf_get_component(ac_list, dev, vp, |
device_xname(dv), dkw.dkw_size, numsecs, secsize); |
device_xname(dv), dkw.dkw_size, numsecs, secsize); |
rf_part_found = 1; /*There is a raid component on this disk*/ |
rf_part_found = 1; /*There is a raid component on this disk*/ |
Line 2885 rf_find_raid_components(void) |
|
Line 2926 rf_find_raid_components(void) |
|
|
|
/* don't need this any more. We'll allocate it again |
/* don't need this any more. We'll allocate it again |
a little later if we really do... */ |
a little later if we really do... */ |
|
vn_lock(vp, LK_EXCLUSIVE | LK_RETRY); |
VOP_CLOSE(vp, FREAD | FWRITE, NOCRED); |
VOP_CLOSE(vp, FREAD | FWRITE, NOCRED); |
vput(vp); |
vput(vp); |
|
|
Line 2903 rf_find_raid_components(void) |
|
Line 2945 rf_find_raid_components(void) |
|
if (bdevvp(dev, &vp)) |
if (bdevvp(dev, &vp)) |
panic("RAID can't alloc vnode"); |
panic("RAID can't alloc vnode"); |
|
|
vn_lock(vp, LK_EXCLUSIVE | LK_RETRY); |
|
error = VOP_OPEN(vp, FREAD, NOCRED); |
error = VOP_OPEN(vp, FREAD, NOCRED); |
if (error) { |
if (error) { |
/* Whatever... */ |
/* Whatever... */ |
vput(vp); |
vput(vp); |
continue; |
continue; |
} |
} |
VOP_UNLOCK(vp); |
|
snprintf(cname, sizeof(cname), "%s%c", |
snprintf(cname, sizeof(cname), "%s%c", |
device_xname(dv), 'a' + i); |
device_xname(dv), 'a' + i); |
ac_list = rf_get_component(ac_list, dev, vp, cname, |
ac_list = rf_get_component(ac_list, dev, vp, cname, |
Line 2932 rf_find_raid_components(void) |
|
Line 2972 rf_find_raid_components(void) |
|
if (bdevvp(dev, &vp)) |
if (bdevvp(dev, &vp)) |
panic("RAID can't alloc vnode"); |
panic("RAID can't alloc vnode"); |
|
|
vn_lock(vp, LK_EXCLUSIVE | LK_RETRY); |
|
|
|
error = VOP_OPEN(vp, FREAD, NOCRED); |
error = VOP_OPEN(vp, FREAD, NOCRED); |
if (error) { |
if (error) { |
/* Whatever... */ |
/* Whatever... */ |
vput(vp); |
vput(vp); |
continue; |
continue; |
} |
} |
VOP_UNLOCK(vp); |
|
snprintf(cname, sizeof(cname), "%s%c", |
snprintf(cname, sizeof(cname), "%s%c", |
device_xname(dv), 'a' + RAW_PART); |
device_xname(dv), 'a' + RAW_PART); |
ac_list = rf_get_component(ac_list, dev, vp, cname, |
ac_list = rf_get_component(ac_list, dev, vp, cname, |
Line 3072 rf_create_auto_sets(RF_AutoConfig_t *ac_ |
|
Line 3109 rf_create_auto_sets(RF_AutoConfig_t *ac_ |
|
|
|
if (config_sets == NULL) { |
if (config_sets == NULL) { |
/* will need at least this one... */ |
/* will need at least this one... */ |
config_sets = malloc(sizeof(RF_ConfigSet_t), |
config_sets = (RF_ConfigSet_t *) |
M_RAIDFRAME, M_WAITOK); |
malloc(sizeof(RF_ConfigSet_t), |
|
M_RAIDFRAME, M_NOWAIT); |
|
if (config_sets == NULL) { |
|
panic("rf_create_auto_sets: No memory!"); |
|
} |
/* this one is easy :) */ |
/* this one is easy :) */ |
config_sets->ac = ac; |
config_sets->ac = ac; |
config_sets->next = NULL; |
config_sets->next = NULL; |
Line 3093 rf_create_auto_sets(RF_AutoConfig_t *ac_ |
|
Line 3134 rf_create_auto_sets(RF_AutoConfig_t *ac_ |
|
} |
} |
if (cset==NULL) { |
if (cset==NULL) { |
/* didn't find a match above... new set..*/ |
/* didn't find a match above... new set..*/ |
cset = malloc(sizeof(RF_ConfigSet_t), |
cset = (RF_ConfigSet_t *) |
M_RAIDFRAME, M_WAITOK); |
malloc(sizeof(RF_ConfigSet_t), |
|
M_RAIDFRAME, M_NOWAIT); |
|
if (cset == NULL) { |
|
panic("rf_create_auto_sets: No memory!"); |
|
} |
cset->ac = ac; |
cset->ac = ac; |
ac->next = NULL; |
ac->next = NULL; |
cset->next = config_sets; |
cset->next = config_sets; |
Line 3443 rf_auto_config_set(RF_ConfigSet_t *cset) |
|
Line 3488 rf_auto_config_set(RF_ConfigSet_t *cset) |
|
#endif |
#endif |
|
|
/* 1. Create a config structure */ |
/* 1. Create a config structure */ |
config = malloc(sizeof(*config), M_RAIDFRAME, M_WAITOK|M_ZERO); |
config = malloc(sizeof(*config), M_RAIDFRAME, M_NOWAIT|M_ZERO); |
|
if (config == NULL) { |
|
printf("%s: Out of mem - config!?!?\n", __func__); |
|
/* XXX do something more intelligent here. */ |
|
return NULL; |
|
} |
|
|
/* |
/* |
2. Figure out what RAID ID this one is supposed to live at |
2. Figure out what RAID ID this one is supposed to live at |
Line 3461 rf_auto_config_set(RF_ConfigSet_t *cset) |
|
Line 3511 rf_auto_config_set(RF_ConfigSet_t *cset) |
|
|
|
if (sc == NULL) |
if (sc == NULL) |
sc = raidget(raidID, true); |
sc = raidget(raidID, true); |
|
if (sc == NULL) { |
|
printf("%s: Out of mem - softc!?!?\n", __func__); |
|
/* XXX do something more intelligent here. */ |
|
free(config, M_RAIDFRAME); |
|
return NULL; |
|
} |
|
|
raidPtr = &sc->sc_r; |
raidPtr = &sc->sc_r; |
|
|
/* XXX all this stuff should be done SOMEWHERE ELSE! */ |
/* XXX all this stuff should be done SOMEWHERE ELSE! */ |
|
|
rf_pool_init(struct pool *p, size_t size, const char *w_chan, |
rf_pool_init(struct pool *p, size_t size, const char *w_chan, |
size_t xmin, size_t xmax) |
size_t xmin, size_t xmax) |
{ |
{ |
|
int error; |
|
|
pool_init(p, size, 0, 0, 0, w_chan, NULL, IPL_BIO); |
pool_init(p, size, 0, 0, 0, w_chan, NULL, IPL_BIO); |
pool_sethiwat(p, xmax); |
pool_sethiwat(p, xmax); |
pool_prime(p, xmin); |
if ((error = pool_prime(p, xmin)) != 0) |
|
panic("%s: failed to prime pool: %d", __func__, error); |
|
pool_setlowat(p, xmin); |
} |
} |
|
|
/* |
/* |