:IIUC, in old-ATA, ad_strategy took care of transfer sizes larger than
:the maximum I/O size of the device, but not in NATA (I guess GEOM layer
:is handling it, right?).  Adjusting si_iosize_max (initially faked to
:be 131072 when attached) in ccdinit() seems to work around this problem.
:
:Cheers.

    There's even an XXX comment next to that assignment.  At the time
    that assignment is made the CCD hasn't loaded its components yet
    so we do not know what the actual limitations are.

    CCD has an iterator in ccdstart() to deal with components.  I think
    what we need to do is to add some logic to ccdbuffer() to incorporate
    the limits of the lower level device. 

    So, please try this patch.  I've included a kprintf() so we can get
    positive confirmation that it actually does what it is supposed to.

    The advantage of this patch is that it does not artificially limit
    the max iosize for the CCD request itself.  e.g. if a person happens
    to configure an interleave of 64K across two disks CCD which are
    each limited to 64K I/O's, CCD will still process a 128K I/O in
    parallel.

    Please note this patch is almost completely untested.

                                                -Matt


Index: sys/ccdvar.h
===================================================================
RCS file: /cvs/src/sys/sys/ccdvar.h,v
retrieving revision 1.6
diff -u -p -r1.6 ccdvar.h
--- sys/ccdvar.h        17 May 2007 03:20:11 -0000      1.6
+++ sys/ccdvar.h        9 Jul 2007 17:29:55 -0000
@@ -206,6 +206,7 @@     int              sc_flags;              /* flags */
        int              sc_cflags;             /* configuration flags */
        u_int64_t        sc_size;               /* size of ccd in sectors */
        int              sc_ileave;             /* interleave */
+       int              sc_maxiosize;          /* maximum I/O size */
        u_int            sc_nccdisks;           /* number of components */
 #define        CCD_MAXNDISKS    65536
        struct ccdcinfo  *sc_cinfo;             /* component info */
Index: dev/disk/ccd/ccd.c
===================================================================
RCS file: /cvs/src/sys/dev/disk/ccd/ccd.c,v
retrieving revision 1.48
diff -u -p -r1.48 ccd.c
--- dev/disk/ccd/ccd.c  19 Jun 2007 19:09:46 -0000      1.48
+++ dev/disk/ccd/ccd.c  9 Jul 2007 17:42:52 -0000
@@ -398,6 +398,7 @@ 
        /* Allocate space for the component info. */
        cs->sc_cinfo = kmalloc(cs->sc_nccdisks * sizeof(struct ccdcinfo),
                                M_DEVBUF, M_WAITOK);
+       cs->sc_maxiosize = MAXPHYS;
 
        /*
         * Verify that each component piece exists and record
@@ -427,6 +428,10 @@            ci->ci_path = kmalloc(ci->ci_pathlen, 
                bcopy(tmppath, ci->ci_path, ci->ci_pathlen);
 
                ci->ci_dev = vn_todev(vp);
+               if (ci->ci_dev->si_iosize_max &&
+                   cs->sc_maxiosize > ci->ci_dev->si_iosize_max) {
+                       cs->sc_maxiosize = ci->ci_dev->si_iosize_max;
+               }
 
                /*
                 * Get partition information for the component.
@@ -489,6 +494,8 @@             ci->ci_skip = skip;
                ci->ci_size = size;
                cs->sc_size += size;
        }
+       kprintf("ccd%d: max component iosize is %d\n",
+               cs->sc_unit, cs->sc_maxiosize);
 
        /*
         * Don't allow the interleave to be smaller than
@@ -1048,9 +1055,11 @@  cbp->cb_buf.b_flags |= bio->bio_buf->b_
        cbp->cb_buf.b_data = addr;
        cbp->cb_vp = ci->ci_vp;
        if (cs->sc_ileave == 0)
-              cbc = dbtob((off_t)(ci->ci_size - cbn));
+               cbc = dbtob((off_t)(ci->ci_size - cbn));
        else
-              cbc = dbtob((off_t)(cs->sc_ileave - cboff));
+               cbc = dbtob((off_t)(cs->sc_ileave - cboff));
+       if (cbc > cs->sc_maxiosize)
+               cbc = cs->sc_maxiosize;
        cbp->cb_buf.b_bcount = (cbc < bcount) ? cbc : bcount;
        cbp->cb_buf.b_bufsize = cbp->cb_buf.b_bcount;
 
@@ -1090,6 +1099,8 @@           if (cs->sc_ileave == 0)
                      cbc = dbtob((off_t)(ci->ci_size - cbn));
                else
                      cbc = dbtob((off_t)(cs->sc_ileave - cboff));
+               if (cbc > cs->sc_maxiosize)
+                       cbc = cs->sc_maxiosize;
                cbp->cb_buf.b_bcount = (cbc < bcount) ? cbc : bcount;
                cbp->cb_buf.b_bufsize = cbp->cb_buf.b_bcount;
 

Reply via email to