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));
        }

Reply via email to