diff options
| author | mlelstv <mlelstv@NetBSD.org> | 2016-01-03 08:17:24 +0000 |
|---|---|---|
| committer | mlelstv <mlelstv@NetBSD.org> | 2016-01-03 08:17:24 +0000 |
| commit | 176866d98a02125f941996026533348174ae58ea (patch) | |
| tree | c2ee584e216dd6af771078298223b5acd5ff60b8 /sys/dev/raidframe | |
| parent | 47697f5f68725c19fdb14d06a014b526d1299311 (diff) | |
refactor driver to use common code in dksubr.
Diffstat (limited to 'sys/dev/raidframe')
| -rw-r--r-- | sys/dev/raidframe/rf_engine.c | 6 | ||||
| -rw-r--r-- | sys/dev/raidframe/rf_kintf.h | 4 | ||||
| -rw-r--r-- | sys/dev/raidframe/rf_netbsdkintf.c | 1158 | ||||
| -rw-r--r-- | sys/dev/raidframe/rf_states.c | 26 |
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); |
