summaryrefslogtreecommitdiff
path: root/sys/dev/raidframe
diff options
context:
space:
mode:
authormlelstv <mlelstv@NetBSD.org>2016-01-03 08:17:24 +0000
committermlelstv <mlelstv@NetBSD.org>2016-01-03 08:17:24 +0000
commit176866d98a02125f941996026533348174ae58ea (patch)
treec2ee584e216dd6af771078298223b5acd5ff60b8 /sys/dev/raidframe
parent47697f5f68725c19fdb14d06a014b526d1299311 (diff)
refactor driver to use common code in dksubr.
Diffstat (limited to 'sys/dev/raidframe')
-rw-r--r--sys/dev/raidframe/rf_engine.c6
-rw-r--r--sys/dev/raidframe/rf_kintf.h4
-rw-r--r--sys/dev/raidframe/rf_netbsdkintf.c1158
-rw-r--r--sys/dev/raidframe/rf_states.c26
4 files changed, 425 insertions, 769 deletions
diff --git a/sys/dev/raidframe/rf_engine.c b/sys/dev/raidframe/rf_engine.c
index a527c176770..abb67d2495e 100644
--- a/sys/dev/raidframe/rf_engine.c
+++ b/sys/dev/raidframe/rf_engine.c
@@ -1,4 +1,4 @@
-/* $NetBSD: rf_engine.c,v 1.50 2014/10/18 08:33:28 snj Exp $ */
+/* $NetBSD: rf_engine.c,v 1.51 2016/01/03 08:17:24 mlelstv Exp $ */
/*
* Copyright (c) 1995 Carnegie-Mellon University.
* All rights reserved.
@@ -55,7 +55,7 @@
****************************************************************************/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: rf_engine.c,v 1.50 2014/10/18 08:33:28 snj Exp $");
+__KERNEL_RCSID(0, "$NetBSD: rf_engine.c,v 1.51 2016/01/03 08:17:24 mlelstv Exp $");
#include <sys/errno.h>
@@ -843,7 +843,7 @@ DAGExecutionThread(RF_ThreadArg_t arg)
/*
* rf_RaidIOThread() -- When I/O to a component begins, raidstrategy()
- * puts the I/O on a buf_queue, and then signals raidPtr->iodone. If
+ * puts the I/O on a buffer queue, and then signals raidPtr->iodone. If
* necessary, this function calls raidstart() to initiate the I/O.
* When I/O to a component completes, KernelWakeupFunc() puts the
* completed request onto raidPtr->iodone TAILQ. This function looks
diff --git a/sys/dev/raidframe/rf_kintf.h b/sys/dev/raidframe/rf_kintf.h
index fb6bb2fed8f..eeba4233bd3 100644
--- a/sys/dev/raidframe/rf_kintf.h
+++ b/sys/dev/raidframe/rf_kintf.h
@@ -1,4 +1,4 @@
-/* $NetBSD: rf_kintf.h,v 1.23 2011/08/03 14:44:38 oster Exp $ */
+/* $NetBSD: rf_kintf.h,v 1.24 2016/01/03 08:17:24 mlelstv Exp $ */
/*
* rf_kintf.h
*
@@ -42,6 +42,7 @@ int rf_reasonable_label(RF_ComponentLabel_t *, uint64_t);
void raidstart(RF_Raid_t * raidPtr);
int rf_DispatchKernelIO(RF_DiskQueue_t * queue, RF_DiskQueueData_t * req);
+void raiddone(RF_Raid_t * raidPtr, struct buf * bp);
int raidfetch_component_label(RF_Raid_t *, RF_RowCol_t);
RF_ComponentLabel_t *raidget_component_label(RF_Raid_t *, RF_RowCol_t);
@@ -59,7 +60,6 @@ void raid_init_component_label(RF_Raid_t *, RF_ComponentLabel_t *);
void rf_print_component_label(RF_ComponentLabel_t *);
void rf_UnconfigureVnodes( RF_Raid_t * );
void rf_close_component( RF_Raid_t *, struct vnode *, int);
-void rf_disk_unbusy(RF_RaidAccessDesc_t *);
int rf_getdisksize(struct vnode *, RF_RaidDisk_t *);
int rf_sync_component_caches(RF_Raid_t *raidPtr);
#endif /* _RF__RF_KINTF_H_ */
diff --git a/sys/dev/raidframe/rf_netbsdkintf.c b/sys/dev/raidframe/rf_netbsdkintf.c
index bc62579a1a1..4962dcf01fa 100644
--- a/sys/dev/raidframe/rf_netbsdkintf.c
+++ b/sys/dev/raidframe/rf_netbsdkintf.c
@@ -1,4 +1,4 @@
-/* $NetBSD: rf_netbsdkintf.c,v 1.334 2016/01/02 16:20:50 mlelstv Exp $ */
+/* $NetBSD: rf_netbsdkintf.c,v 1.335 2016/01/03 08:17:24 mlelstv 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.334 2016/01/02 16:20:50 mlelstv Exp $");
+__KERNEL_RCSID(0, "$NetBSD: rf_netbsdkintf.c,v 1.335 2016/01/03 08:17:24 mlelstv Exp $");
#ifdef _KERNEL_OPT
#include "opt_compat_netbsd.h"
@@ -181,6 +181,7 @@ static void InitBP(struct buf *, struct vnode *, unsigned,
void *, int, struct proc *);
struct raid_softc;
static void raidinit(struct raid_softc *);
+static int raiddoaccess(RF_Raid_t *raidPtr, struct buf *bp);
static int raid_match(device_t, cfdata_t, void *);
static void raid_attach(device_t, device_t, void *);
@@ -196,6 +197,9 @@ static int raidwrite_component_label(unsigned,
static int raidread_component_label(unsigned,
dev_t, struct vnode *, RF_ComponentLabel_t *);
+static int raid_diskstart(device_t, struct buf *bp);
+static int raid_dumpblocks(device_t, void *, daddr_t, int);
+static int raid_lastclose(device_t);
static dev_type_open(raidopen);
static dev_type_close(raidclose);
@@ -233,12 +237,17 @@ const struct cdevsw raid_cdevsw = {
};
static struct dkdriver rf_dkdriver = {
+ .d_open = raidopen,
+ .d_close = raidclose,
.d_strategy = raidstrategy,
+ .d_diskstart = raid_diskstart,
+ .d_dumpblocks = raid_dumpblocks,
+ .d_lastclose = raid_lastclose,
.d_minphys = minphys
};
struct raid_softc {
- device_t sc_dev;
+ struct dk_softc sc_dksc;
int sc_unit;
int sc_flags; /* flags */
int sc_cflags; /* configuration flags */
@@ -246,8 +255,6 @@ struct raid_softc {
kcondvar_t sc_cv; /* and the condvar */
uint64_t sc_size; /* size of the raid device */
char sc_xname[20]; /* XXX external name */
- struct disk sc_dkdev; /* generic disk device info */
- struct bufq_state *buf_queue; /* used for the device queue */
RF_Raid_t sc_r;
LIST_ENTRY(raid_softc) sc_link;
};
@@ -256,10 +263,12 @@ struct raid_softc {
#define RAIDF_WLABEL 0x02 /* label area is writable */
#define RAIDF_LABELLING 0x04 /* unit is currently being labelled */
#define RAIDF_SHUTDOWN 0x08 /* unit is being shutdown */
+#define RAIDF_DETACH 0x10 /* detach after final close */
#define RAIDF_WANTED 0x40 /* someone is waiting to obtain a lock */
#define RAIDF_LOCKED 0x80 /* unit is locked */
#define raidunit(x) DISKUNIT(x)
+#define raidsoftc(dev) (((struct raid_softc *)device_private(dev))->sc_r.softc)
extern struct cfdriver raid_cd;
CFATTACH_DECL3_NEW(raid, sizeof(struct raid_softc),
@@ -292,11 +301,6 @@ CFATTACH_DECL3_NEW(raid, sizeof(struct raid_softc),
/* declared here, and made public, for the benefit of KVM stuff.. */
-static void raidgetdefaultlabel(RF_Raid_t *, struct raid_softc *,
- struct disklabel *);
-static void raidgetdisklabel(dev_t);
-static void raidmakedisklabel(struct raid_softc *);
-
static int raidlock(struct raid_softc *);
static void raidunlock(struct raid_softc *);
@@ -352,7 +356,6 @@ raidcreate(int unit) {
return NULL;
}
sc->sc_unit = unit;
- bufq_alloc(&sc->buf_queue, "fcfs", BUFQ_SORT_RAWBLOCK);
cv_init(&sc->sc_cv, "raidunit");
mutex_init(&sc->sc_mutex, MUTEX_DEFAULT, IPL_NONE);
return sc;
@@ -362,7 +365,6 @@ static void
raiddestroy(struct raid_softc *sc) {
cv_destroy(&sc->sc_cv);
mutex_destroy(&sc->sc_mutex);
- bufq_free(sc->buf_queue);
kmem_free(sc, sizeof(*sc));
}
@@ -480,6 +482,7 @@ rf_buildroothack(RF_ConfigSet_t *config_sets)
RF_ConfigSet_t *next_cset;
int num_root;
struct raid_softc *sc, *rsc;
+ struct dk_softc *dksc;
sc = rsc = NULL;
num_root = 0;
@@ -510,6 +513,7 @@ rf_buildroothack(RF_ConfigSet_t *config_sets)
rf_cleanup_config_set(cset);
cset = next_cset;
}
+ dksc = &rsc->sc_dksc;
/* if the user has specified what the root device should be
then we don't touch booted_device or boothowto... */
@@ -532,14 +536,14 @@ rf_buildroothack(RF_ConfigSet_t *config_sets)
*/
if (num_root == 1) {
device_t candidate_root;
- if (rsc->sc_dkdev.dk_nwedges != 0) {
+ if (dksc->sc_dkdev.dk_nwedges != 0) {
char cname[sizeof(cset->ac->devname)];
/* XXX: assume 'a' */
snprintf(cname, sizeof(cname), "%s%c",
- device_xname(rsc->sc_dev), 'a');
+ device_xname(dksc->sc_dev), 'a');
candidate_root = dkwedge_find_by_wname(cname);
} else
- candidate_root = rsc->sc_dev;
+ candidate_root = dksc->sc_dev;
if (booted_device == NULL ||
rsc->sc_r.root_partition == 1 ||
rf_containsboot(&rsc->sc_r, booted_device)) {
@@ -570,12 +574,13 @@ rf_buildroothack(RF_ConfigSet_t *config_sets)
if (rf_containsboot(r, booted_device)) {
num_root++;
rsc = sc;
+ dksc = &rsc->sc_dksc;
}
}
mutex_exit(&raid_lock);
if (num_root == 1) {
- booted_device = rsc->sc_dev;
+ booted_device = dksc->sc_dev;
booted_partition = 0; /* XXX assume 'a' */
} else {
/* we can't guess.. require the user to answer... */
@@ -588,55 +593,49 @@ static int
raidsize(dev_t dev)
{
struct raid_softc *rs;
- struct disklabel *lp;
- int part, unit, omask, size;
+ struct dk_softc *dksc;
+ unsigned int unit;
unit = raidunit(dev);
if ((rs = raidget(unit, false)) == NULL)
- return -1;
- if ((rs->sc_flags & RAIDF_INITED) == 0)
- return (-1);
+ return ENXIO;
+ dksc = &rs->sc_dksc;
- part = DISKPART(dev);
- omask = rs->sc_dkdev.dk_openmask & (1 << part);
- lp = rs->sc_dkdev.dk_label;
+ if ((rs->sc_flags & RAIDF_INITED) == 0)
+ return (ENODEV);
- if (omask == 0 && raidopen(dev, 0, S_IFBLK, curlwp))
- return (-1);
+ return dk_size(dksc, dev);
+}
- if (lp->d_partitions[part].p_fstype != FS_SWAP)
- size = -1;
- else
- size = lp->d_partitions[part].p_size *
- (lp->d_secsize / DEV_BSIZE);
+static int
+raiddump(dev_t dev, daddr_t blkno, void *va, size_t size)
+{
+ unsigned int unit;
+ struct raid_softc *rs;
+ struct dk_softc *dksc;
- if (omask == 0 && raidclose(dev, 0, S_IFBLK, curlwp))
- return (-1);
+ unit = raidunit(dev);
+ if ((rs = raidget(unit, false)) == NULL)
+ return ENXIO;
+ dksc = &rs->sc_dksc;
- return (size);
+ if ((rs->sc_flags & RAIDF_INITED) == 0)
+ return ENODEV;
+ return dk_dump(dksc, dev, blkno, va, size);
}
static int
-raiddump(dev_t dev, daddr_t blkno, void *va, size_t size)
+raid_dumpblocks(device_t dev, void *va, daddr_t blkno, int nblk)
{
- int unit = raidunit(dev);
- struct raid_softc *rs;
+ struct raid_softc *rs = raidsoftc(dev);
const struct bdevsw *bdev;
- struct disklabel *lp;
RF_Raid_t *raidPtr;
- daddr_t offset;
- int part, c, sparecol, j, scol, dumpto;
+ int c, sparecol, j, scol, dumpto;
int error = 0;
- if ((rs = raidget(unit, false)) == NULL)
- return ENXIO;
-
raidPtr = &rs->sc_r;
- if ((rs->sc_flags & RAIDF_INITED) == 0)
- return ENXIO;
-
/* we only support dumping to RAID 1 sets */
if (raidPtr->Layout.numDataCol != 1 ||
raidPtr->Layout.numParityCol != 1)
@@ -645,23 +644,6 @@ raiddump(dev_t dev, daddr_t blkno, void *va, size_t size)
if ((error = raidlock(rs)) != 0)
return error;
- if (size % DEV_BSIZE != 0) {
- error = EINVAL;
- goto out;
- }
-
- if (blkno + size / DEV_BSIZE > rs->sc_size) {
- printf("%s: blkno (%" PRIu64 ") + size / DEV_BSIZE (%zu) > "
- "sc->sc_size (%" PRIu64 ")\n", __func__, blkno,
- size / DEV_BSIZE, rs->sc_size);
- error = EINVAL;
- goto out;
- }
-
- part = DISKPART(dev);
- lp = rs->sc_dkdev.dk_label;
- offset = lp->d_partitions[part].p_offset + RF_PROTECTED_SECTORS;
-
/* figure out what device is alive.. */
/*
@@ -736,16 +718,8 @@ raiddump(dev_t dev, daddr_t blkno, void *va, size_t size)
bdev = bdevsw_lookup(raidPtr->Disks[dumpto].dev);
- /*
- Note that blkno is relative to this particular partition.
- By adding the offset of this partition in the RAID
- set, and also adding RF_PROTECTED_SECTORS, we get a
- value that is relative to the partition used for the
- underlying component.
- */
-
error = (*bdev->d_dump)(raidPtr->Disks[dumpto].dev,
- blkno + offset, va, size);
+ blkno, va, nblk);
out:
raidunlock(rs);
@@ -760,9 +734,9 @@ raidopen(dev_t dev, int flags, int fmt,
{
int unit = raidunit(dev);
struct raid_softc *rs;
- struct disklabel *lp;
- int part, pmask;
+ struct dk_softc *dksc;
int error = 0;
+ int part, pmask;
if ((rs = raidget(unit, true)) == NULL)
return ENXIO;
@@ -774,47 +748,12 @@ raidopen(dev_t dev, int flags, int fmt,
goto bad;
}
- lp = rs->sc_dkdev.dk_label;
+ dksc = &rs->sc_dksc;
part = DISKPART(dev);
-
- /*
- * If there are wedges, and this is not RAW_PART, then we
- * need to fail.
- */
- if (rs->sc_dkdev.dk_nwedges != 0 && part != RAW_PART) {
- error = EBUSY;
- goto bad;
- }
pmask = (1 << part);
- if ((rs->sc_flags & RAIDF_INITED) &&
- (rs->sc_dkdev.dk_nwedges == 0) &&
- (rs->sc_dkdev.dk_openmask == 0))
- raidgetdisklabel(dev);
-
- /* make sure that this partition exists */
-
- if (part != RAW_PART) {
- if (((rs->sc_flags & RAIDF_INITED) == 0) ||
- ((part >= lp->d_npartitions) ||
- (lp->d_partitions[part].p_fstype == FS_UNUSED))) {
- error = ENXIO;
- goto bad;
- }
- }
- /* Prevent this unit from being unconfigured while open. */
- switch (fmt) {
- case S_IFCHR:
- rs->sc_dkdev.dk_copenmask |= pmask;
- break;
-
- case S_IFBLK:
- rs->sc_dkdev.dk_bopenmask |= pmask;
- break;
- }
-
- if ((rs->sc_dkdev.dk_openmask == 0) &&
+ if (!DK_BUSY(dksc, pmask) &&
((rs->sc_flags & RAIDF_INITED) != 0)) {
/* First one... mark things as dirty... Note that we *MUST*
have done a configure before this. I DO NOT WANT TO BE
@@ -827,9 +766,8 @@ raidopen(dev_t dev, int flags, int fmt,
rf_markalldirty(&rs->sc_r);
}
-
- rs->sc_dkdev.dk_openmask =
- rs->sc_dkdev.dk_copenmask | rs->sc_dkdev.dk_bopenmask;
+ if ((rs->sc_flags & RAIDF_INITED) != 0)
+ error = dk_open(dksc, dev, flags, fmt, l);
bad:
raidunlock(rs);
@@ -839,141 +777,144 @@ bad:
}
+static int
+raid_lastclose(device_t self)
+{
+ struct raid_softc *rs = raidsoftc(self);
+
+ /* Last one... device is not unconfigured yet.
+ Device shutdown has taken care of setting the
+ clean bits if RAIDF_INITED is not set
+ mark things as clean... */
+
+ rf_update_component_labels(&rs->sc_r,
+ RF_FINAL_COMPONENT_UPDATE);
+
+ /* pass to unlocked code */
+ if ((rs->sc_flags & RAIDF_SHUTDOWN) != 0)
+ rs->sc_flags |= RAIDF_DETACH;
+
+ return 0;
+}
+
/* ARGSUSED */
static int
raidclose(dev_t dev, int flags, int fmt, struct lwp *l)
{
int unit = raidunit(dev);
struct raid_softc *rs;
- int error = 0;
- int part;
+ struct dk_softc *dksc;
+ cfdata_t cf;
+ int error = 0, do_detach = 0, do_put = 0;
if ((rs = raidget(unit, false)) == NULL)
return ENXIO;
+ dksc = &rs->sc_dksc;
if ((error = raidlock(rs)) != 0)
return (error);
- part = DISKPART(dev);
+ if ((rs->sc_flags & RAIDF_INITED) != 0) {
+ error = dk_close(dksc, dev, flags, fmt, l);
+ if ((rs->sc_flags & RAIDF_DETACH) != 0)
+ do_detach = 1;
+ } else if ((rs->sc_flags & RAIDF_SHUTDOWN) != 0)
+ do_put = 1;
- /* ...that much closer to allowing unconfiguration... */
- switch (fmt) {
- case S_IFCHR:
- rs->sc_dkdev.dk_copenmask &= ~(1 << part);
- break;
-
- case S_IFBLK:
- rs->sc_dkdev.dk_bopenmask &= ~(1 << part);
- break;
- }
- rs->sc_dkdev.dk_openmask =
- rs->sc_dkdev.dk_copenmask | rs->sc_dkdev.dk_bopenmask;
-
- if ((rs->sc_dkdev.dk_openmask == 0) &&
- ((rs->sc_flags & RAIDF_INITED) != 0)) {
- /* Last one... device is not unconfigured yet.
- Device shutdown has taken care of setting the
- clean bits if RAIDF_INITED is not set
- mark things as clean... */
+ raidunlock(rs);
- rf_update_component_labels(&rs->sc_r,
- RF_FINAL_COMPONENT_UPDATE);
+ if (do_detach) {
+ /* free the pseudo device attach bits */
+ cf = device_cfdata(dksc->sc_dev);
+ error = config_detach(dksc->sc_dev, 0);
+ if (error == 0)
+ free(cf, M_RAIDFRAME);
+ } else if (do_put) {
+ raidput(rs);
}
- if ((rs->sc_dkdev.dk_openmask == 0) &&
- ((rs->sc_flags & RAIDF_SHUTDOWN) != 0)) {
- /*
- * Detach this raid unit
- */
- cfdata_t cf = NULL;
- int retcode = 0;
- if (rs->sc_dev != NULL) {
- cf = device_cfdata(rs->sc_dev);
+ return (error);
- raidunlock(rs);
- retcode = config_detach(rs->sc_dev, 0);
- if (retcode == 0)
- /* free the pseudo device attach bits */
- free(cf, M_RAIDFRAME);
- } else {
- raidput(rs);
- }
- return retcode;
- }
+}
- raidunlock(rs);
- return (0);
+static void
+raid_wakeup(RF_Raid_t *raidPtr)
+{
+ rf_lock_mutex2(raidPtr->iodone_lock);
+ rf_signal_cond2(raidPtr->iodone_cv);
+ rf_unlock_mutex2(raidPtr->iodone_lock);
}
static void
raidstrategy(struct buf *bp)
{
- unsigned int unit = raidunit(bp->b_dev);
- RF_Raid_t *raidPtr;
- int wlabel;
+ unsigned int unit;
struct raid_softc *rs;
+ struct dk_softc *dksc;
+ RF_Raid_t *raidPtr;
+ unit = raidunit(bp->b_dev);
if ((rs = raidget(unit, false)) == NULL) {
bp->b_error = ENXIO;
- goto done;
+ goto fail;
}
if ((rs->sc_flags & RAIDF_INITED) == 0) {
bp->b_error = ENXIO;
- goto done;
+ goto fail;
}
+ dksc = &rs->sc_dksc;
raidPtr = &rs->sc_r;
- if (!raidPtr->valid) {
- bp->b_error = ENODEV;
- goto done;
- }
- if (bp->b_bcount == 0) {
- db1_printf(("b_bcount is zero..\n"));
+
+ /* Queue IO only */
+ if (dk_strategy_defer(dksc, bp))
goto done;
- }
- /*
- * Do bounds checking and adjust transfer. If there's an
- * error, the bounds check will flag that for us.
- */
+ /* schedule the IO to happen at the next convenient time */
+ raid_wakeup(raidPtr);
- wlabel = rs->sc_flags & (RAIDF_WLABEL | RAIDF_LABELLING);
- if (DISKPART(bp->b_dev) == RAW_PART) {
- uint64_t size; /* device size in DEV_BSIZE unit */
+done:
+ return;
- if (raidPtr->logBytesPerSector > DEV_BSHIFT) {
- size = raidPtr->totalSectors <<
- (raidPtr->logBytesPerSector - DEV_BSHIFT);
- } else {
- size = raidPtr->totalSectors >>
- (DEV_BSHIFT - raidPtr->logBytesPerSector);
- }
- if (bounds_check_with_mediasize(bp, DEV_BSIZE, size) <= 0) {
- goto done;
- }
- } else {
- if (bounds_check_with_label(&rs->sc_dkdev, bp, wlabel) <= 0) {
- db1_printf(("Bounds check failed!!:%d %d\n",
- (int) bp->b_blkno, (int) wlabel));
- goto done;
- }
- }
+fail:
+ bp->b_resid = bp->b_bcount;
+ biodone(bp);
+}
- rf_lock_mutex2(raidPtr->iodone_lock);
+static int
+raid_diskstart(device_t dev, struct buf *bp)
+{
+ struct raid_softc *rs = raidsoftc(dev);
+ RF_Raid_t *raidPtr;
+
+ raidPtr = &rs->sc_r;
+ if (!raidPtr->valid) {
+ db1_printf(("raid is not valid..\n"));
+ return ENODEV;
+ }
+ /* XXX */
bp->b_resid = 0;
- /* stuff it onto our queue */
- bufq_put(rs->buf_queue, bp);
+ return raiddoaccess(raidPtr, bp);
+}
- /* scheduled the IO to happen at the next convenient time */
- rf_signal_cond2(raidPtr->iodone_cv);
- rf_unlock_mutex2(raidPtr->iodone_lock);
+void
+raiddone(RF_Raid_t *raidPtr, struct buf *bp)
+{
+ struct raid_softc *rs;
+ struct dk_softc *dksc;
- return;
+ rs = raidPtr->softc;
+ dksc = &rs->sc_dksc;
-done:
- bp->b_resid = bp->b_bcount;
- biodone(bp);
+ dk_done(dksc, bp);
+
+ rf_lock_mutex2(raidPtr->mutex);
+ raidPtr->openings++;
+ rf_unlock_mutex2(raidPtr->mutex);
+
+ /* schedule more IO */
+ raid_wakeup(raidPtr);
}
/* ARGSUSED */
@@ -1013,16 +954,13 @@ raidwrite(dev_t dev, struct uio *uio, int flags)
static int
raid_detach_unlocked(struct raid_softc *rs)
{
- int error;
+ struct dk_softc *dksc = &rs->sc_dksc;
RF_Raid_t *raidPtr;
+ int error;
raidPtr = &rs->sc_r;
- /*
- * If somebody has a partition mounted, we shouldn't
- * shutdown.
- */
- if (rs->sc_dkdev.dk_openmask != 0)
+ if (DK_BUSY(dksc, 0))
return EBUSY;
if ((rs->sc_flags & RAIDF_INITED) == 0)
@@ -1033,13 +971,18 @@ raid_detach_unlocked(struct raid_softc *rs)
if ((error = rf_Shutdown(raidPtr)) != 0)
return error;
- /* Detach the disk. */
- dkwedge_delall(&rs->sc_dkdev);
- disk_detach(&rs->sc_dkdev);
- disk_destroy(&rs->sc_dkdev);
-
rs->sc_flags &= ~RAIDF_INITED;
+ /* Kill off any queued buffers */
+ dk_drain(dksc);
+ bufq_free(dksc->sc_bufq);
+
+ /* Detach the disk. */
+ dkwedge_delall(&dksc->sc_dkdev);
+ disk_detach(&dksc->sc_dkdev);
+ disk_destroy(&dksc->sc_dkdev);
+ dk_detach(dksc);
+
return 0;
}
@@ -1048,8 +991,9 @@ raidioctl(dev_t dev, u_long cmd, void *data, int flag, struct lwp *l)
{
int unit = raidunit(dev);
int error = 0;
- int part, pmask, s;
+ 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;
@@ -1067,62 +1011,17 @@ raidioctl(dev_t dev, u_long cmd, void *data, int flag, struct lwp *l)
RF_SingleComponent_t component;
RF_ProgressInfo_t progressInfo, **progressInfoPtr;
int i, j, d;
-#ifdef __HAVE_OLD_DISKLABEL
- struct disklabel newlabel;
-#endif
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 open for writes for these commands... */
- switch (cmd) {
-#ifdef DIOCGSECTORSIZE
- case DIOCGSECTORSIZE:
- *(u_int *)data = raidPtr->bytesPerSector;
- return 0;
- case DIOCGMEDIASIZE:
- *(off_t *)data =
- (off_t)raidPtr->totalSectors * raidPtr->bytesPerSector;
- return 0;
-#endif
- case DIOCSDINFO:
- case DIOCWDINFO:
-#ifdef __HAVE_OLD_DISKLABEL
- case ODIOCWDINFO:
- case ODIOCSDINFO:
-#endif
- case DIOCWLABEL:
- case DIOCAWEDGE:
- case DIOCDWEDGE:
- case DIOCMWEDGES:
- case DIOCSSTRATEGY:
- if ((flag & FWRITE) == 0)
- return (EBADF);
- }
-
/* Must be initialized for these... */
switch (cmd) {
- case DIOCGDINFO:
- case DIOCSDINFO:
- case DIOCWDINFO:
-#ifdef __HAVE_OLD_DISKLABEL
- case ODIOCGDINFO:
- case ODIOCWDINFO:
- case ODIOCSDINFO:
- case ODIOCGDEFLABEL:
-#endif
- case DIOCGPARTINFO:
- case DIOCWLABEL:
- case DIOCGDEFLABEL:
- case DIOCAWEDGE:
- case DIOCDWEDGE:
- case DIOCLWEDGES:
- case DIOCMWEDGES:
- case DIOCCACHESYNC:
case RAIDFRAME_REWRITEPARITY:
case RAIDFRAME_GET_INFO:
case RAIDFRAME_RESET_ACCTOTALS:
@@ -1152,8 +1051,6 @@ raidioctl(dev_t dev, u_long cmd, void *data, int flag, struct lwp *l)
case RAIDFRAME_PARITYMAP_GET_DISABLE:
case RAIDFRAME_PARITYMAP_SET_DISABLE:
case RAIDFRAME_PARITYMAP_SET_PARAMS:
- case DIOCGSTRATEGY:
- case DIOCSSTRATEGY:
if ((rs->sc_flags & RAIDF_INITED) == 0)
return (ENXIO);
}
@@ -1249,6 +1146,7 @@ raidioctl(dev_t dev, u_long cmd, void *data, int flag, struct lwp *l)
raidPtr->openings = RAIDOUTSTANDING;
raidinit(rs);
+ raid_wakeup(raidPtr);
rf_markalldirty(raidPtr);
}
/* free the buffers. No return code here. */
@@ -1275,11 +1173,10 @@ raidioctl(dev_t dev, u_long cmd, void *data, int flag, struct lwp *l)
if ((error = raidlock(rs)) != 0)
return (error);
- if ((rs->sc_dkdev.dk_openmask & ~pmask) ||
- ((rs->sc_dkdev.dk_bopenmask & pmask) &&
- (rs->sc_dkdev.dk_copenmask & pmask)))
+ if (DK_BUSY(dksc, pmask))
retcode = EBUSY;
else {
+ /* detach and free on close */
rs->sc_flags |= RAIDF_SHUTDOWN;
retcode = 0;
}
@@ -1832,115 +1729,14 @@ raidioctl(dev_t dev, u_long cmd, void *data, int flag, struct lwp *l)
* Add support for "regular" device ioctls here.
*/
- error = disk_ioctl(&rs->sc_dkdev, dev, cmd, data, flag, l);
+ error = dk_ioctl(dksc, dev, cmd, data, flag, l);
if (error != EPASSTHROUGH)
return (error);
switch (cmd) {
- case DIOCWDINFO:
- case DIOCSDINFO:
-#ifdef __HAVE_OLD_DISKLABEL
- case ODIOCWDINFO:
- case ODIOCSDINFO:
-#endif
- {
- struct disklabel *lp;
-#ifdef __HAVE_OLD_DISKLABEL
- if (cmd == ODIOCSDINFO || cmd == ODIOCWDINFO) {
- memset(&newlabel, 0, sizeof newlabel);
- memcpy(&newlabel, data, sizeof (struct olddisklabel));
- lp = &newlabel;
- } else
-#endif
- lp = (struct disklabel *)data;
-
- if ((error = raidlock(rs)) != 0)
- return (error);
-
- rs->sc_flags |= RAIDF_LABELLING;
-
- error = setdisklabel(rs->sc_dkdev.dk_label,
- lp, 0, rs->sc_dkdev.dk_cpulabel);
- if (error == 0) {
- if (cmd == DIOCWDINFO
-#ifdef __HAVE_OLD_DISKLABEL
- || cmd == ODIOCWDINFO
-#endif
- )
- error = writedisklabel(RAIDLABELDEV(dev),
- raidstrategy, rs->sc_dkdev.dk_label,
- rs->sc_dkdev.dk_cpulabel);
- }
- rs->sc_flags &= ~RAIDF_LABELLING;
-
- raidunlock(rs);
-
- if (error)
- return (error);
- break;
- }
-
- case DIOCWLABEL:
- if (*(int *) data != 0)
- rs->sc_flags |= RAIDF_WLABEL;
- else
- rs->sc_flags &= ~RAIDF_WLABEL;
- break;
-
- case DIOCGDEFLABEL:
- raidgetdefaultlabel(raidPtr, rs, (struct disklabel *) data);
- break;
-
-#ifdef __HAVE_OLD_DISKLABEL
- case ODIOCGDEFLABEL:
- raidgetdefaultlabel(raidPtr, rs, &newlabel);
- if (newlabel.d_npartitions > OLDMAXPARTITIONS)
- return ENOTTY;
- memcpy(data, &newlabel, sizeof (struct olddisklabel));
- break;
-#endif
-
case DIOCCACHESYNC:
return rf_sync_component_caches(raidPtr);
- case DIOCGSTRATEGY:
- {
- struct disk_strategy *dks = (void *)data;
-
- s = splbio();
- strlcpy(dks->dks_name, bufq_getstrategyname(rs->buf_queue),
- sizeof(dks->dks_name));
- splx(s);
- dks->dks_paramlen = 0;
-
- return 0;
- }
-
- case DIOCSSTRATEGY:
- {
- struct disk_strategy *dks = (void *)data;
- struct bufq_state *new;
- struct bufq_state *old;
-
- if (dks->dks_param != NULL) {
- return EINVAL;
- }
- dks->dks_name[sizeof(dks->dks_name) - 1] = 0; /* ensure term */
- error = bufq_alloc(&new, dks->dks_name,
- BUFQ_EXACT|BUFQ_SORT_RAWBLOCK);
- if (error) {
- return error;
- }
- s = splbio();
- old = rs->buf_queue;
- bufq_move(new, old);
- rs->buf_queue = new;
- splx(s);
- bufq_free(old);
-
- return 0;
- }
-
default:
retcode = ENOTTY;
}
@@ -1957,17 +1753,15 @@ static void
raidinit(struct raid_softc *rs)
{
cfdata_t cf;
- int unit;
+ unsigned int unit;
+ struct dk_softc *dksc = &rs->sc_dksc;
RF_Raid_t *raidPtr = &rs->sc_r;
+ device_t dev;
unit = raidPtr->raidid;
-
- /* XXX should check return code first... */
- rs->sc_flags |= RAIDF_INITED;
-
/* XXX doesn't check bounds. */
- snprintf(rs->sc_xname, sizeof(rs->sc_xname), "raid%d", unit);
+ snprintf(rs->sc_xname, sizeof(rs->sc_xname), "raid%u", unit);
/* attach the pseudo device */
cf = malloc(sizeof(*cf), M_RAIDFRAME, M_WAITOK);
@@ -1976,33 +1770,41 @@ raidinit(struct raid_softc *rs)
cf->cf_unit = unit;
cf->cf_fstate = FSTATE_STAR;
- rs->sc_dev = config_attach_pseudo(cf);
-
- if (rs->sc_dev == NULL) {
+ dev = config_attach_pseudo(cf);
+ if (dev == NULL) {
printf("raid%d: config_attach_pseudo failed\n",
raidPtr->raidid);
- rs->sc_flags &= ~RAIDF_INITED;
free(cf, M_RAIDFRAME);
return;
}
+ /* provide a backpointer to the real softc */
+ raidsoftc(dev) = rs;
+
/* disk_attach actually creates space for the CPU disklabel, among
* other things, so it's critical to call this *BEFORE* we try putzing
* with disklabels. */
-
- disk_init(&rs->sc_dkdev, rs->sc_xname, &rf_dkdriver);
- disk_attach(&rs->sc_dkdev);
+ dk_init(dksc, dev, DKTYPE_RAID);
+ disk_init(&dksc->sc_dkdev, rs->sc_xname, &rf_dkdriver);
/* XXX There may be a weird interaction here between this, and
* protectedSectors, as used in RAIDframe. */
rs->sc_size = raidPtr->totalSectors;
+ /* Attach dk and disk subsystems */
+ dk_attach(dksc);
+ disk_attach(&dksc->sc_dkdev);
rf_set_geometry(rs, raidPtr);
- dkwedge_discover(&rs->sc_dkdev);
+ bufq_alloc(&dksc->sc_bufq, "fcfs", BUFQ_SORT_RAWBLOCK);
+
+ /* mark unit as usuable */
+ rs->sc_flags |= RAIDF_INITED;
+ dkwedge_discover(&dksc->sc_dkdev);
}
+
#if (RF_INCLUDE_PARITY_DECLUSTERING_DS > 0)
/* wake up the daemon & tell it to get us a spare table
* XXX
@@ -2049,16 +1851,11 @@ rf_GetSpareTableFromDaemon(RF_SparetWait_t *req)
void
raidstart(RF_Raid_t *raidPtr)
{
- RF_SectorCount_t num_blocks, pb, sum;
- RF_RaidAddr_t raid_addr;
- struct partition *pp;
- daddr_t blocknum;
struct raid_softc *rs;
- int do_async;
- struct buf *bp;
- int rc;
+ struct dk_softc *dksc;
rs = raidPtr->softc;
+ dksc = &rs->sc_dksc;
/* quick check to see if anything has died recently */
rf_lock_mutex2(raidPtr->mutex);
if (raidPtr->numNewFailures > 0) {
@@ -2068,105 +1865,89 @@ raidstart(RF_Raid_t *raidPtr)
rf_lock_mutex2(raidPtr->mutex);
raidPtr->numNewFailures--;
}
+ rf_unlock_mutex2(raidPtr->mutex);
- /* Check to see if we're at the limit... */
- while (raidPtr->openings > 0) {
- rf_unlock_mutex2(raidPtr->mutex);
-
- /* get the next item, if any, from the queue */
- if ((bp = bufq_get(rs->buf_queue)) == NULL) {
- /* nothing more to do */
- return;
- }
-
- /* Ok, for the bp we have here, bp->b_blkno is relative to the
- * partition.. Need to make it absolute to the underlying
- * device.. */
-
- blocknum = bp->b_blkno << DEV_BSHIFT >> raidPtr->logBytesPerSector;
- if (DISKPART(bp->b_dev) != RAW_PART) {
- pp = &rs->sc_dkdev.dk_label->d_partitions[DISKPART(bp->b_dev)];
- blocknum += pp->p_offset;
- }
+ if ((rs->sc_flags & RAIDF_INITED) == 0) {
+ printf("raid%d: raidstart not ready\n", raidPtr->raidid);
+ return;
+ }
- db1_printf(("Blocks: %d, %d\n", (int) bp->b_blkno,
- (int) blocknum));
+ dk_start(dksc, NULL);
+}
- db1_printf(("bp->b_bcount = %d\n", (int) bp->b_bcount));
- db1_printf(("bp->b_resid = %d\n", (int) bp->b_resid));
+static int
+raiddoaccess(RF_Raid_t *raidPtr, struct buf *bp)
+{
+ RF_SectorCount_t num_blocks, pb, sum;
+ RF_RaidAddr_t raid_addr;
+ daddr_t blocknum;
+ int do_async;
+ int rc;
- /* *THIS* is where we adjust what block we're going to...
- * but DO NOT TOUCH bp->b_blkno!!! */
- raid_addr = blocknum;
+ rf_lock_mutex2(raidPtr->mutex);
+ if (raidPtr->openings == 0) {
+ rf_unlock_mutex2(raidPtr->mutex);
+ return EAGAIN;
+ }
+ rf_unlock_mutex2(raidPtr->mutex);
- num_blocks = bp->b_bcount >> raidPtr->logBytesPerSector;
- pb = (bp->b_bcount & raidPtr->sectorMask) ? 1 : 0;
- sum = raid_addr + num_blocks + pb;
- if (1 || rf_debugKernelAccess) {
- db1_printf(("raid_addr=%d sum=%d num_blocks=%d(+%d) (%d)\n",
- (int) raid_addr, (int) sum, (int) num_blocks,
- (int) pb, (int) bp->b_resid));
- }
- if ((sum > raidPtr->totalSectors) || (sum < raid_addr)
- || (sum < num_blocks) || (sum < pb)) {
- bp->b_error = ENOSPC;
- bp->b_resid = bp->b_bcount;
- biodone(bp);
- rf_lock_mutex2(raidPtr->mutex);
- continue;
- }
- /*
- * XXX rf_DoAccess() should do this, not just DoAccessKernel()
- */
+ blocknum = bp->b_rawblkno;
- if (bp->b_bcount & raidPtr->sectorMask) {
- bp->b_error = EINVAL;
- bp->b_resid = bp->b_bcount;
- biodone(bp);
- rf_lock_mutex2(raidPtr->mutex);
- continue;
+ db1_printf(("Blocks: %d, %d\n", (int) bp->b_blkno,
+ (int) blocknum));
- }
- db1_printf(("Calling DoAccess..\n"));
+ db1_printf(("bp->b_bcount = %d\n", (int) bp->b_bcount));
+ db1_printf(("bp->b_resid = %d\n", (int) bp->b_resid));
+ /* *THIS* is where we adjust what block we're going to...
+ * but DO NOT TOUCH bp->b_blkno!!! */
+ raid_addr = blocknum;
- rf_lock_mutex2(raidPtr->mutex);
- raidPtr->openings--;
- rf_unlock_mutex2(raidPtr->mutex);
+ num_blocks = bp->b_bcount >> raidPtr->logBytesPerSector;
+ pb = (bp->b_bcount & raidPtr->sectorMask) ? 1 : 0;
+ sum = raid_addr + num_blocks + pb;
+ if (1 || rf_debugKernelAccess) {
+ db1_printf(("raid_addr=%d sum=%d num_blocks=%d(+%d) (%d)\n",
+ (int) raid_addr, (int) sum, (int) num_blocks,
+ (int) pb, (int) bp->b_resid));
+ }
+ if ((sum > raidPtr->totalSectors) || (sum < raid_addr)
+ || (sum < num_blocks) || (sum < pb)) {
+ rc = ENOSPC;
+ goto done;
+ }
+ /*
+ * XXX rf_DoAccess() should do this, not just DoAccessKernel()
+ */
- /*
- * Everything is async.
- */
- do_async = 1;
+ if (bp->b_bcount & raidPtr->sectorMask) {
+ rc = ENOSPC;
+ goto done;
+ }
+ db1_printf(("Calling DoAccess..\n"));
- disk_busy(&rs->sc_dkdev);
- /* XXX we're still at splbio() here... do we *really*
- need to be? */
+ rf_lock_mutex2(raidPtr->mutex);
+ raidPtr->openings--;
+ rf_unlock_mutex2(raidPtr->mutex);
- /* don't ever condition on bp->b_flags & B_WRITE.
- * always condition on B_READ instead */
+ /*
+ * Everything is async.
+ */
+ do_async = 1;
- rc = rf_DoAccess(raidPtr, (bp->b_flags & B_READ) ?
- RF_IO_TYPE_READ : RF_IO_TYPE_WRITE,
- do_async, raid_addr, num_blocks,
- bp->b_data, bp, RF_DAG_NONBLOCKING_IO);
+ /* don't ever condition on bp->b_flags & B_WRITE.
+ * always condition on B_READ instead */
- if (rc) {
- bp->b_error = rc;
- bp->b_resid = bp->b_bcount;
- biodone(bp);
- /* continue loop */
- }
+ rc = rf_DoAccess(raidPtr, (bp->b_flags & B_READ) ?
+ RF_IO_TYPE_READ : RF_IO_TYPE_WRITE,
+ do_async, raid_addr, num_blocks,
+ bp->b_data, bp, RF_DAG_NONBLOCKING_IO);
- rf_lock_mutex2(raidPtr->mutex);
- }
- rf_unlock_mutex2(raidPtr->mutex);
+done:
+ return rc;
}
-
-
-
/* invoke an I/O from kernel mode. Disk queue should be locked upon entry */
int
@@ -2341,128 +2122,6 @@ InitBP(struct buf *bp, struct vnode *b_vp, unsigned rw_flag, dev_t dev,
bp->b_private = cbArg;
}
-static void
-raidgetdefaultlabel(RF_Raid_t *raidPtr, struct raid_softc *rs,
- struct disklabel *lp)
-{
- memset(lp, 0, sizeof(*lp));
-
- /* fabricate a label... */
- if (raidPtr->totalSectors > UINT32_MAX)
- lp->d_secperunit = UINT32_MAX;
- else
- lp->d_secperunit = raidPtr->totalSectors;
- lp->d_secsize = raidPtr->bytesPerSector;
- lp->d_nsectors = raidPtr->Layout.dataSectorsPerStripe;
- lp->d_ntracks = 4 * raidPtr->numCol;
- lp->d_ncylinders = raidPtr->totalSectors /
- (lp->d_nsectors * lp->d_ntracks);
- lp->d_secpercyl = lp->d_ntracks * lp->d_nsectors;
-
- strncpy(lp->d_typename, "raid", sizeof(lp->d_typename));
- lp->d_type = DKTYPE_RAID;
- strncpy(lp->d_packname, "fictitious", sizeof(lp->d_packname));
- lp->d_rpm = 3600;
- lp->d_interleave = 1;
- lp->d_flags = 0;
-
- lp->d_partitions[RAW_PART].p_offset = 0;
- lp->d_partitions[RAW_PART].p_size = lp->d_secperunit;
- lp->d_partitions[RAW_PART].p_fstype = FS_UNUSED;
- lp->d_npartitions = RAW_PART + 1;
-
- lp->d_magic = DISKMAGIC;
- lp->d_magic2 = DISKMAGIC;
- lp->d_checksum = dkcksum(rs->sc_dkdev.dk_label);
-
-}
-/*
- * Read the disklabel from the raid device. If one is not present, fake one
- * up.
- */
-static void
-raidgetdisklabel(dev_t dev)
-{
- int unit = raidunit(dev);
- struct raid_softc *rs;
- const char *errstring;
- struct disklabel *lp;
- struct cpu_disklabel *clp;
- RF_Raid_t *raidPtr;
-
- if ((rs = raidget(unit, false)) == NULL)
- return;
-
- lp = rs->sc_dkdev.dk_label;
- clp = rs->sc_dkdev.dk_cpulabel;
-
- db1_printf(("Getting the disklabel...\n"));
-
- memset(clp, 0, sizeof(*clp));
-
- raidPtr = &rs->sc_r;
-
- raidgetdefaultlabel(raidPtr, rs, lp);
-
- /*
- * Call the generic disklabel extraction routine.
- */
- errstring = readdisklabel(RAIDLABELDEV(dev), raidstrategy,
- rs->sc_dkdev.dk_label, rs->sc_dkdev.dk_cpulabel);
- if (errstring)
- raidmakedisklabel(rs);
- else {
- int i;
- struct partition *pp;
-
- /*
- * Sanity check whether the found disklabel is valid.
- *
- * This is necessary since total size of the raid device
- * may vary when an interleave is changed even though exactly
- * same components are used, and old disklabel may used
- * if that is found.
- */
- if (lp->d_secperunit < UINT32_MAX ?
- lp->d_secperunit != rs->sc_size :
- lp->d_secperunit > rs->sc_size)
- printf("raid%d: WARNING: %s: "
- "total sector size in disklabel (%ju) != "
- "the size of raid (%ju)\n", unit, rs->sc_xname,
- (uintmax_t)lp->d_secperunit,
- (uintmax_t)rs->sc_size);
- for (i = 0; i < lp->d_npartitions; i++) {
- pp = &lp->d_partitions[i];
- if (pp->p_offset + pp->p_size > rs->sc_size)
- printf("raid%d: WARNING: %s: end of partition `%c' "
- "exceeds the size of raid (%ju)\n",
- unit, rs->sc_xname, 'a' + i,
- (uintmax_t)rs->sc_size);
- }
- }
-
-}
-/*
- * Take care of things one might want to take care of in the event
- * that a disklabel isn't present.
- */
-static void
-raidmakedisklabel(struct raid_softc *rs)
-{
- struct disklabel *lp = rs->sc_dkdev.dk_label;
- db1_printf(("Making a label..\n"));
-
- /*
- * For historical reasons, if there's no disklabel present
- * the raw partition must be marked FS_BSDFFS.
- */
-
- lp->d_partitions[RAW_PART].p_fstype = FS_BSDFFS;
-
- strncpy(lp->d_packname, "default label", sizeof(lp->d_packname));
-
- lp->d_checksum = dkcksum(lp);
-}
/*
* Wait interruptibly for an exclusive lock.
*
@@ -2475,16 +2134,18 @@ raidlock(struct raid_softc *rs)
{
int error;
+ error = 0;
mutex_enter(&rs->sc_mutex);
while ((rs->sc_flags & RAIDF_LOCKED) != 0) {
rs->sc_flags |= RAIDF_WANTED;
error = cv_wait_sig(&rs->sc_cv, &rs->sc_mutex);
if (error != 0)
- return (error);
+ goto done;
}
rs->sc_flags |= RAIDF_LOCKED;
+done:
mutex_exit(&rs->sc_mutex);
- return (0);
+ return (error);
}
/*
* Unlock and wake up any waiters.
@@ -3089,171 +2750,186 @@ rf_find_raid_components(void)
RF_AutoConfig_t *ac_list;
uint64_t numsecs;
unsigned secsize;
+ int dowedges;
/* initialize the AutoConfig list */
ac_list = NULL;
- /* we begin by trolling through *all* the devices on the system */
+ /*
+ * we begin by trolling through *all* the devices on the system *twice*
+ * first we scan for wedges, second for other devices. This avoids
+ * using a raw partition instead of a wedge that covers the whole disk
+ */
- for (dv = deviter_first(&di, DEVITER_F_ROOT_FIRST); dv != NULL;
- dv = deviter_next(&di)) {
+ for (dowedges=1; dowedges>=0; --dowedges) {
+ for (dv = deviter_first(&di, DEVITER_F_ROOT_FIRST); dv != NULL;
+ dv = deviter_next(&di)) {
- /* we are only interested in disks... */
- if (device_class(dv) != DV_DISK)
- continue;
+ /* we are only interested in disks... */
+ if (device_class(dv) != DV_DISK)
+ continue;
- /* we don't care about floppies... */
- if (device_is_a(dv, "fd")) {
- continue;
- }
+ /* we don't care about floppies... */
+ if (device_is_a(dv, "fd")) {
+ continue;
+ }
- /* we don't care about CD's... */
- if (device_is_a(dv, "cd")) {
- continue;
- }
+ /* we don't care about CD's... */
+ if (device_is_a(dv, "cd")) {
+ continue;
+ }
- /* we don't care about md's... */
- if (device_is_a(dv, "md")) {
- continue;
- }
+ /* we don't care about md's... */
+ if (device_is_a(dv, "md")) {
+ continue;
+ }
- /* hdfd is the Atari/Hades floppy driver */
- if (device_is_a(dv, "hdfd")) {
- continue;
- }
+ /* hdfd is the Atari/Hades floppy driver */
+ if (device_is_a(dv, "hdfd")) {
+ continue;
+ }
- /* fdisa is the Atari/Milan floppy driver */
- if (device_is_a(dv, "fdisa")) {
- continue;
- }
+ /* fdisa is the Atari/Milan floppy driver */
+ if (device_is_a(dv, "fdisa")) {
+ continue;
+ }
- /* need to find the device_name_to_block_device_major stuff */
- bmajor = devsw_name2blk(device_xname(dv), NULL, 0);
+ /* are we in the wedges pass ? */
+ wedge = device_is_a(dv, "dk");
+ if (wedge != dowedges) {
+ continue;
+ }
- rf_part_found = 0; /*No raid partition as yet*/
+ /* need to find the device_name_to_block_device_major stuff */
+ bmajor = devsw_name2blk(device_xname(dv), NULL, 0);
- /* get a vnode for the raw partition of this disk */
+ rf_part_found = 0; /*No raid partition as yet*/
- wedge = device_is_a(dv, "dk");
- bminor = minor(device_unit(dv));
- dev = wedge ? makedev(bmajor, bminor) :
- MAKEDISKDEV(bmajor, bminor, RAW_PART);
- if (bdevvp(dev, &vp))
- panic("RAID can't alloc vnode");
+ /* get a vnode for the raw partition of this disk */
+ bminor = minor(device_unit(dv));
+ dev = wedge ? makedev(bmajor, bminor) :
+ MAKEDISKDEV(bmajor, bminor, RAW_PART);
+ if (bdevvp(dev, &vp))
+ panic("RAID can't alloc vnode");
- error = VOP_OPEN(vp, FREAD | FSILENT, NOCRED);
+ error = VOP_OPEN(vp, FREAD | FSILENT, NOCRED);
- if (error) {
- /* "Who cares." Continue looking
- for something that exists*/
- vput(vp);
- continue;
- }
+ if (error) {
+ /* "Who cares." Continue looking
+ for something that exists*/
+ vput(vp);
+ continue;
+ }
- error = getdisksize(vp, &numsecs, &secsize);
- if (error) {
- vput(vp);
- continue;
- }
- if (wedge) {
- struct dkwedge_info dkw;
- error = VOP_IOCTL(vp, DIOCGWEDGEINFO, &dkw, FREAD,
- NOCRED);
+ error = getdisksize(vp, &numsecs, &secsize);
if (error) {
- printf("RAIDframe: can't get wedge info for "
+ printf("RAIDframe: can't get disk size for "
"dev %s (%d)\n", device_xname(dv), error);
vn_lock(vp, LK_EXCLUSIVE | LK_RETRY);
VOP_CLOSE(vp, FREAD | FWRITE, NOCRED);
vput(vp);
continue;
}
+ if (wedge) {
+ struct dkwedge_info dkw;
+ error = VOP_IOCTL(vp, DIOCGWEDGEINFO, &dkw, FREAD,
+ NOCRED);
+ if (error) {
+ printf("RAIDframe: can't get wedge info for "
+ "dev %s (%d)\n", device_xname(dv), error);
+ vn_lock(vp, LK_EXCLUSIVE | LK_RETRY);
+ VOP_CLOSE(vp, FREAD | FWRITE, NOCRED);
+ vput(vp);
+ continue;
+ }
- if (strcmp(dkw.dkw_ptype, DKW_PTYPE_RAIDFRAME) != 0) {
- vn_lock(vp, LK_EXCLUSIVE | LK_RETRY);
- VOP_CLOSE(vp, FREAD | FWRITE, NOCRED);
- vput(vp);
+ if (strcmp(dkw.dkw_ptype, DKW_PTYPE_RAIDFRAME) != 0) {
+ vn_lock(vp, LK_EXCLUSIVE | LK_RETRY);
+ VOP_CLOSE(vp, FREAD | FWRITE, NOCRED);
+ vput(vp);
+ continue;
+ }
+
+ ac_list = rf_get_component(ac_list, dev, vp,
+ device_xname(dv), dkw.dkw_size, numsecs, secsize);
+ rf_part_found = 1; /*There is a raid component on this disk*/
continue;
}
-
- ac_list = rf_get_component(ac_list, dev, vp,
- device_xname(dv), dkw.dkw_size, numsecs, secsize);
- rf_part_found = 1; /*There is a raid component on this disk*/
- continue;
- }
- /* Ok, the disk exists. Go get the disklabel. */
- error = VOP_IOCTL(vp, DIOCGDINFO, &label, FREAD, NOCRED);
- if (error) {
- /*
- * XXX can't happen - open() would
- * have errored out (or faked up one)
- */
- if (error != ENOTTY)
- printf("RAIDframe: can't get label for dev "
- "%s (%d)\n", device_xname(dv), error);
- }
+ /* Ok, the disk exists. Go get the disklabel. */
+ error = VOP_IOCTL(vp, DIOCGDINFO, &label, FREAD, NOCRED);
+ if (error) {
+ /*
+ * XXX can't happen - open() would
+ * have errored out (or faked up one)
+ */
+ if (error != ENOTTY)
+ printf("RAIDframe: can't get label for dev "
+ "%s (%d)\n", device_xname(dv), error);
+ }
- /* don't need this any more. We'll allocate it again
- a little later if we really do... */
- vn_lock(vp, LK_EXCLUSIVE | LK_RETRY);
- VOP_CLOSE(vp, FREAD | FWRITE, NOCRED);
- vput(vp);
+ /* don't need this any more. We'll allocate it again
+ a little later if we really do... */
+ vn_lock(vp, LK_EXCLUSIVE | LK_RETRY);
+ VOP_CLOSE(vp, FREAD | FWRITE, NOCRED);
+ vput(vp);
- if (error)
- continue;
+ if (error)
+ continue;
- rf_part_found = 0; /*No raid partitions yet*/
- for (i = 0; i < label.d_npartitions; i++) {
- char cname[sizeof(ac_list->devname)];
+ rf_part_found = 0; /*No raid partitions yet*/
+ for (i = 0; i < label.d_npartitions; i++) {
+ char cname[sizeof(ac_list->devname)];
- /* We only support partitions marked as RAID */
- if (label.d_partitions[i].p_fstype != FS_RAID)
- continue;
+ /* We only support partitions marked as RAID */
+ if (label.d_partitions[i].p_fstype != FS_RAID)
+ continue;
- dev = MAKEDISKDEV(bmajor, device_unit(dv), i);
- if (bdevvp(dev, &vp))
- panic("RAID can't alloc vnode");
+ dev = MAKEDISKDEV(bmajor, device_unit(dv), i);
+ if (bdevvp(dev, &vp))
+ panic("RAID can't alloc vnode");
- error = VOP_OPEN(vp, FREAD, NOCRED);
- if (error) {
- /* Whatever... */
- vput(vp);
- continue;
- }
- snprintf(cname, sizeof(cname), "%s%c",
- device_xname(dv), 'a' + i);
- ac_list = rf_get_component(ac_list, dev, vp, cname,
- label.d_partitions[i].p_size, numsecs, secsize);
+ error = VOP_OPEN(vp, FREAD, NOCRED);
+ if (error) {
+ /* Whatever... */
+ vput(vp);
+ continue;
+ }
+ snprintf(cname, sizeof(cname), "%s%c",
+ device_xname(dv), 'a' + i);
+ ac_list = rf_get_component(ac_list, dev, vp, cname,
+ label.d_partitions[i].p_size, numsecs, secsize);
rf_part_found = 1; /*There is at least one raid partition on this disk*/
- }
+ }
- /*
- *If there is no raid component on this disk, either in a
- *disklabel or inside a wedge, check the raw partition as well,
- *as it is possible to configure raid components on raw disk
- *devices.
- */
+ /*
+ *If there is no raid component on this disk, either in a
+ *disklabel or inside a wedge, check the raw partition as well,
+ *as it is possible to configure raid components on raw disk
+ *devices.
+ */
- if (!rf_part_found) {
- char cname[sizeof(ac_list->devname)];
+ if (!rf_part_found) {
+ char cname[sizeof(ac_list->devname)];
- dev = MAKEDISKDEV(bmajor, device_unit(dv), RAW_PART);
- if (bdevvp(dev, &vp))
- panic("RAID can't alloc vnode");
+ dev = MAKEDISKDEV(bmajor, device_unit(dv), RAW_PART);
+ if (bdevvp(dev, &vp))
+ panic("RAID can't alloc vnode");
- error = VOP_OPEN(vp, FREAD, NOCRED);
- if (error) {
- /* Whatever... */
- vput(vp);
- continue;
+ error = VOP_OPEN(vp, FREAD, NOCRED);
+ if (error) {
+ /* Whatever... */
+ vput(vp);
+ continue;
+ }
+ snprintf(cname, sizeof(cname), "%s%c",
+ device_xname(dv), 'a' + RAW_PART);
+ ac_list = rf_get_component(ac_list, dev, vp, cname,
+ label.d_partitions[RAW_PART].p_size, numsecs, secsize);
}
- snprintf(cname, sizeof(cname), "%s%c",
- device_xname(dv), 'a' + RAW_PART);
- ac_list = rf_get_component(ac_list, dev, vp, cname,
- label.d_partitions[RAW_PART].p_size, numsecs, secsize);
}
+ deviter_release(&di);
}
- deviter_release(&di);
return ac_list;
}
@@ -3681,7 +3357,7 @@ rf_release_all_vps(RF_ConfigSet_t *cset)
/* Close the vp, and give it back */
if (ac->vp) {
vn_lock(ac->vp, LK_EXCLUSIVE | LK_RETRY);
- VOP_CLOSE(ac->vp, FREAD, NOCRED);
+ VOP_CLOSE(ac->vp, FREAD | FWRITE, NOCRED);
vput(ac->vp);
ac->vp = NULL;
}
@@ -3829,18 +3505,6 @@ rf_auto_config_set(RF_ConfigSet_t *cset)
}
void
-rf_disk_unbusy(RF_RaidAccessDesc_t *desc)
-{
- struct buf *bp;
- struct raid_softc *rs;
-
- bp = (struct buf *)desc->bp;
- rs = desc->raidPtr->softc;
- disk_unbusy(&rs->sc_dkdev, (bp->b_bcount - bp->b_resid),
- (bp->b_flags & B_READ));
-}
-
-void
rf_pool_init(struct pool *p, size_t size, const char *w_chan,
size_t xmin, size_t xmax)
{
@@ -3851,21 +3515,28 @@ rf_pool_init(struct pool *p, size_t size, const char *w_chan,
}
/*
- * rf_buf_queue_check(RF_Raid_t raidPtr) -- looks into the buf_queue to see
- * if there is IO pending and if that IO could possibly be done for a
- * given RAID set. Returns 0 if IO is waiting and can be done, 1
+ * rf_buf_queue_check(RF_Raid_t raidPtr) -- looks into the buffer queue
+ * to see if there is IO pending and if that IO could possibly be done
+ * for a given RAID set. Returns 0 if IO is waiting and can be done, 1
* otherwise.
*
*/
-
int
rf_buf_queue_check(RF_Raid_t *raidPtr)
{
- struct raid_softc *rs = raidPtr->softc;
- if ((bufq_peek(rs->buf_queue) != NULL) && raidPtr->openings > 0) {
+ struct raid_softc *rs;
+ struct dk_softc *dksc;
+
+ rs = raidPtr->softc;
+ dksc = &rs->sc_dksc;
+
+ if ((rs->sc_flags & RAIDF_INITED) == 0)
+ return 1;
+
+ if (dk_strategy_pending(dksc) && raidPtr->openings > 0) {
/* there is work to do */
return 0;
- }
+ }
/* default is nothing to do */
return 1;
}
@@ -3896,7 +3567,6 @@ raid_match(device_t self, cfdata_t cfdata, void *aux)
static void
raid_attach(device_t parent, device_t self, void *aux)
{
-
}
@@ -3904,7 +3574,7 @@ static int
raid_detach(device_t self, int flags)
{
int error;
- struct raid_softc *rs = raidget(device_unit(self), false);
+ struct raid_softc *rs = raidsoftc(self);
if (rs == NULL)
return ENXIO;
@@ -3930,7 +3600,8 @@ raid_detach(device_t self, int flags)
static void
rf_set_geometry(struct raid_softc *rs, RF_Raid_t *raidPtr)
{
- struct disk_geom *dg = &rs->sc_dkdev.dk_geom;
+ struct dk_softc *dksc = &rs->sc_dksc;
+ struct disk_geom *dg = &dksc->sc_dkdev.dk_geom;
memset(dg, 0, sizeof(*dg));
@@ -3939,7 +3610,7 @@ rf_set_geometry(struct raid_softc *rs, RF_Raid_t *raidPtr)
dg->dg_nsectors = raidPtr->Layout.dataSectorsPerStripe;
dg->dg_ntracks = 4 * raidPtr->numCol;
- disk_set_info(rs->sc_dev, &rs->sc_dkdev, NULL);
+ disk_set_info(dksc->sc_dev, &dksc->sc_dkdev, NULL);
}
/*
@@ -4110,12 +3781,14 @@ raid_modcmd_fini(void)
error = config_cfattach_detach(raid_cd.cd_name, &raid_ca);
if (error != 0) {
+ aprint_error("%s: cannot detach cfattach\n",__func__);
mutex_exit(&raid_lock);
return error;
}
#ifdef _MODULE
error = config_cfdriver_detach(&raid_cd);
if (error != 0) {
+ aprint_error("%s: cannot detach cfdriver\n",__func__);
config_cfattach_attach(raid_cd.cd_name, &raid_ca);
mutex_exit(&raid_lock);
return error;
@@ -4123,6 +3796,7 @@ raid_modcmd_fini(void)
#endif
error = devsw_detach(&raid_bdevsw, &raid_cdevsw);
if (error != 0) {
+ aprint_error("%s: cannot detach devsw\n",__func__);
#ifdef _MODULE
config_cfdriver_attach(&raid_cd);
#endif
diff --git a/sys/dev/raidframe/rf_states.c b/sys/dev/raidframe/rf_states.c
index 29492a4f8b1..66e315f3799 100644
--- a/sys/dev/raidframe/rf_states.c
+++ b/sys/dev/raidframe/rf_states.c
@@ -1,4 +1,4 @@
-/* $NetBSD: rf_states.c,v 1.49 2011/05/11 18:13:12 mrg Exp $ */
+/* $NetBSD: rf_states.c,v 1.50 2016/01/03 08:17:24 mlelstv Exp $ */
/*
* Copyright (c) 1995 Carnegie-Mellon University.
* All rights reserved.
@@ -27,7 +27,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: rf_states.c,v 1.49 2011/05/11 18:13:12 mrg Exp $");
+__KERNEL_RCSID(0, "$NetBSD: rf_states.c,v 1.50 2016/01/03 08:17:24 mlelstv Exp $");
#include <sys/errno.h>
@@ -222,24 +222,6 @@ rf_State_LastState(RF_RaidAccessDesc_t *desc)
KASSERT(desc->async_flag);
/*
- * That's all the IO for this one... unbusy the 'disk'.
- */
-
- rf_disk_unbusy(desc);
-
- /*
- * Wakeup any requests waiting to go.
- */
-
- rf_lock_mutex2(desc->raidPtr->mutex);
- desc->raidPtr->openings++;
- rf_unlock_mutex2(desc->raidPtr->mutex);
-
- rf_lock_mutex2(desc->raidPtr->iodone_lock);
- rf_signal_cond2(desc->raidPtr->iodone_cv);
- rf_unlock_mutex2(desc->raidPtr->iodone_lock);
-
- /*
* The parity_map hook has to go here, because the iodone
* callback goes straight into the kintf layer.
*/
@@ -248,8 +230,8 @@ rf_State_LastState(RF_RaidAccessDesc_t *desc)
rf_paritymap_end(desc->raidPtr->parity_map,
desc->raidAddress, desc->numBlocks);
- /* printf("Calling biodone on 0x%x\n",desc->bp); */
- biodone(desc->bp); /* access came through ioctl */
+ /* printf("Calling raiddone on 0x%x\n",desc->bp); */
+ raiddone(desc->raidPtr, desc->bp); /* access came through ioctl */
if (callbackFunc)
callbackFunc(callbackArg);