aboutsummaryrefslogtreecommitdiff
path: root/sys/dev/ccd
diff options
context:
space:
mode:
authorSatoshi Asami <asami@FreeBSD.org>1996-01-31 03:28:21 +0000
committerSatoshi Asami <asami@FreeBSD.org>1996-01-31 03:28:21 +0000
commit3bc746be91c04a326969480c00af3c56d20c32aa (patch)
treeaff7eaf735ac04e3f08f634870421d22101bf70f /sys/dev/ccd
parent56363b79a90c0ff14956efc013858061aa612d0c (diff)
Notes
Diffstat (limited to 'sys/dev/ccd')
-rw-r--r--sys/dev/ccd/ccd.c56
1 files changed, 41 insertions, 15 deletions
diff --git a/sys/dev/ccd/ccd.c b/sys/dev/ccd/ccd.c
index 66e5b2825eec..c6b349c0044a 100644
--- a/sys/dev/ccd/ccd.c
+++ b/sys/dev/ccd/ccd.c
@@ -1,4 +1,4 @@
-/* $Id: ccd.c,v 1.4 1996/01/02 23:32:54 asami Exp $ */
+/* $Id: ccd.c,v 1.5 1996/01/30 22:34:53 asami Exp $ */
/* $NetBSD: ccd.c,v 1.22 1995/12/08 19:13:26 thorpej Exp $ */
@@ -166,8 +166,8 @@ static void ccdinterleave __P((struct ccd_softc *, int));
static void ccdintr __P((struct ccd_softc *, struct buf *));
static int ccdinit __P((struct ccddevice *, char **, struct proc *));
static int ccdlookup __P((char *, struct proc *p, struct vnode **));
-static struct ccdbuf *ccdbuffer __P((struct ccd_softc *, struct buf *,
- daddr_t, caddr_t, long));
+static void ccdbuffer __P((struct ccdbuf **ret, struct ccd_softc *,
+ struct buf *, daddr_t, caddr_t, long));
static void ccdgetdisklabel __P((dev_t));
static void ccdmakedisklabel __P((struct ccd_softc *));
static int ccdlock __P((struct ccd_softc *));
@@ -701,7 +701,10 @@ ccdstrategy(bp)
if (bounds_check_with_label(bp, lp, wlabel) <= 0)
goto done;
- bp->b_resid = bp->b_bcount;
+ if (cs->sc_cflags & CCDF_MIRROR && (bp->b_flags & B_READ) == 0)
+ bp->b_resid = bp->b_bcount*2;
+ else
+ bp->b_resid = bp->b_bcount;
/*
* "Start" the unit.
@@ -720,7 +723,8 @@ ccdstart(cs, bp)
register struct buf *bp;
{
register long bcount, rcount;
- struct ccdbuf *cbp;
+ struct ccdbuf *cbp[4];
+ /* XXX! : 2 reads and 2 writes for RAID 4/5 */
caddr_t addr;
daddr_t bn;
struct partition *pp;
@@ -756,11 +760,17 @@ ccdstart(cs, bp)
*/
addr = bp->b_data;
for (bcount = bp->b_bcount; bcount > 0; bcount -= rcount) {
- cbp = ccdbuffer(cs, bp, bn, addr, bcount);
- rcount = cbp->cb_buf.b_bcount;
- if ((cbp->cb_buf.b_flags & B_READ) == 0)
- cbp->cb_buf.b_vp->v_numoutput++;
- VOP_STRATEGY(&cbp->cb_buf);
+ ccdbuffer(cbp, cs, bp, bn, addr, bcount);
+ rcount = cbp[0]->cb_buf.b_bcount;
+ if ((cbp[0]->cb_buf.b_flags & B_READ) == 0)
+ cbp[0]->cb_buf.b_vp->v_numoutput++;
+ VOP_STRATEGY(&cbp[0]->cb_buf);
+ if (cs->sc_cflags & CCDF_MIRROR &&
+ (cbp[0]->cb_buf.b_flags & B_READ) == 0) {
+ /* mirror, start another write */
+ cbp[1]->cb_buf.b_vp->v_numoutput++;
+ VOP_STRATEGY(&cbp[1]->cb_buf);
+ }
bn += btodb(rcount);
addr += rcount;
}
@@ -769,15 +779,16 @@ ccdstart(cs, bp)
/*
* Build a component buffer header.
*/
-static struct ccdbuf *
-ccdbuffer(cs, bp, bn, addr, bcount)
+void
+ccdbuffer(cb, cs, bp, bn, addr, bcount)
+ register struct ccdbuf **cb;
register struct ccd_softc *cs;
struct buf *bp;
daddr_t bn;
caddr_t addr;
long bcount;
{
- register struct ccdcinfo *ci;
+ register struct ccdcinfo *ci, *ci2;
register struct ccdbuf *cbp;
register daddr_t cbn, cboff;
@@ -824,6 +835,8 @@ ccdbuffer(cs, bp, bn, addr, bcount)
if (cs->sc_cflags & CCDF_MIRROR) {
ccdisk = ii->ii_index[off % (ii->ii_ndisk/2)];
cbn = ii->ii_startoff + off / (ii->ii_ndisk/2);
+ /* mirrored data */
+ ci2 = &cs->sc_cinfo[ccdisk + ii->ii_ndisk/2];
}
else if (cs->sc_cflags & CCDF_PARITY) {
ccdisk = ii->ii_index[off % (ii->ii_ndisk-1)];
@@ -871,7 +884,17 @@ ccdbuffer(cs, bp, bn, addr, bcount)
ci->ci_dev, ci-cs->sc_cinfo, cbp, cbp->cb_buf.b_blkno,
cbp->cb_buf.b_data, cbp->cb_buf.b_bcount);
#endif
- return (cbp);
+ cb[0] = cbp;
+ if (cs->sc_cflags & CCDF_MIRROR &&
+ (cbp->cb_buf.b_flags & B_READ) == 0) {
+ /* mirror, start one more write */
+ cbp = getccdbuf();
+ *cbp = *cb[0];
+ cbp->cb_buf.b_dev = ci2->ci_dev;
+ cbp->cb_buf.b_vp = ci2->ci_vp;
+ cbp->cb_comp = ci2 - cs->sc_cinfo;
+ cb[1] = cbp;
+ }
}
static void
@@ -898,7 +921,10 @@ ccdintr(cs, bp)
dk_busy &= ~(1 << cs->sc_dk);
#endif
if (bp->b_flags & B_ERROR)
- bp->b_resid = bp->b_bcount;
+ if (cs->sc_cflags & CCDF_MIRROR && (bp->b_flags & B_READ) == 0)
+ bp->b_resid = bp->b_bcount*2;
+ else
+ bp->b_resid = bp->b_bcount;
biodone(bp);
}