Revision 1.58 of ccd.c (a mere six years ago...) introduced an
unintialized variable usage, in the case of an interleaved and mirrored
ccd; read access could favor the mirror instead of the main ccd by
incorrectly considering the main ccd is in the failure state.
The following diff ought to fix this.
Index: dev/ccd.c
===================================================================
RCS file: /cvs/src/sys/dev/ccd.c,v
retrieving revision 1.92
diff -u -p -r1.92 ccd.c
--- dev/ccd.c 22 Sep 2010 01:18:57 -0000 1.92
+++ dev/ccd.c 7 Apr 2011 15:32:52 -0000
@@ -795,6 +795,7 @@ ccdbuffer(struct ccd_softc *cs, struct b
ccdisk = ii->ii_index[off % ii->ii_ndisk];
cbn = ii->ii_startoff + off / ii->ii_ndisk;
}
+ ci = &cs->sc_cinfo[ccdisk];
if (cs->sc_cflags & CCDF_MIRROR) {
/* Mirrored data */
ccdisk2 = ccdisk + ii->ii_ndisk;
@@ -803,11 +804,12 @@ ccdbuffer(struct ccd_softc *cs, struct b
if (bp->b_flags & B_READ &&
bcount > bp->b_bcount / 2 &&
(!(ci2->ci_flags & CCIF_FAILED) ||
- ci->ci_flags & CCIF_FAILED))
+ ci->ci_flags & CCIF_FAILED)) {
ccdisk = ccdisk2;
+ ci = ci2;
+ }
}
cbn *= cs->sc_ileave;
- ci = &cs->sc_cinfo[ccdisk];
CCD_DPRINTF(CCDB_IO, ("ccdisk %d cbn %lld ci %p ci2 %p\n",
ccdisk, cbn, ci, ci2));
}