To deal with an issue jordan found and to be able to boot softraid the code needs to start using the vnode api.
Please test. I am particularly interested in rebuilds and hotspares that initiate a rebuild. Index: softraid.c =================================================================== RCS file: /cvs/src/sys/dev/softraid.c,v retrieving revision 1.169 diff -u -p -r1.169 softraid.c --- softraid.c 31 Jul 2009 16:05:25 -0000 1.169 +++ softraid.c 4 Aug 2009 23:12:37 -0000 @@ -273,7 +273,7 @@ int sr_meta_probe(struct sr_discipline *sd, dev_t *dt, int no_chunk) { struct sr_softc *sc = sd->sd_sc; - struct bdevsw *bdsw; + struct vnode *vn; struct sr_chunk *ch_entry, *ch_prev = NULL; struct sr_chunk_head *cl; char devname[32]; @@ -305,23 +305,28 @@ sr_meta_probe(struct sr_discipline *sd, continue; } else { sr_meta_getdevname(sc, dev, devname, sizeof(devname)); - bdsw = bdevsw_lookup(dev); + if (bdevvp(dev, &vn)) { + printf("%s:, sr_meta_probe: can't allocate " + "vnode\n"); + goto unwind; + } /* * XXX leaving dev open for now; move this to attach * and figure out the open/close dance for unwind. */ - error = bdsw->d_open(dev, FREAD | FWRITE, S_IFBLK, - curproc); + error = VOP_OPEN(vn, FREAD | FWRITE, NOCRED, 0); if (error) { DNPRINTF(SR_D_META,"%s: sr_meta_probe can't " "open %s\n", DEVNAME(sc), devname); /* dev isn't open but will be closed anyway */ + vput(vn); goto unwind; } strlcpy(ch_entry->src_devname, devname, - sizeof(ch_entry->src_devname)); + sizeof(ch_entry->src_devname)); + ch_entry->src_vn = vn; } /* determine if this is a device we understand */ @@ -385,12 +390,12 @@ sr_meta_rw(struct sr_discipline *sd, dev DNPRINTF(SR_D_META, "%s: sr_meta_rw(0x%x, %p, %d, %llu 0x%x)\n", DEVNAME(sc), dev, md, sz, ofs, flags); + bzero(&b, sizeof(b)); + if (md == NULL) { printf("%s: read invalid metadata pointer\n", DEVNAME(sc)); goto done; } - - bzero(&b, sizeof(b)); b.b_flags = flags | B_PHYS; b.b_blkno = ofs; b.b_bcount = sz; @@ -400,10 +405,16 @@ sr_meta_rw(struct sr_discipline *sd, dev b.b_error = 0; b.b_proc = curproc; b.b_dev = dev; - b.b_vp = NULL; b.b_iodone = NULL; + if (bdevvp(dev, &b.b_vp)) { + printf("%s:, sr_meta_native_bootprobe: can't allocate vnode\n"); + goto done; + } + if ((b.b_flags & B_READ) == 0) + b.b_vp->v_numoutput++; + LIST_INIT(&b.b_dep); - bdevsw_lookup(b.b_dev)->d_strategy(&b); + VOP_STRATEGY(&b); biowait(&b); if (b.b_flags & B_ERROR) { @@ -413,6 +424,9 @@ sr_meta_rw(struct sr_discipline *sd, dev } rv = 0; done: + if (b.b_vp) + vput(b.b_vp); + return (rv); } @@ -837,7 +851,7 @@ int sr_meta_native_bootprobe(struct sr_softc *sc, struct device *dv, struct sr_metadata_list_head *mlh) { - struct bdevsw *bdsw; + struct vnode *vn; struct disklabel label; struct sr_metadata *md; struct sr_discipline *fake_sd; @@ -853,40 +867,38 @@ sr_meta_native_bootprobe(struct sr_softc if (majdev == -1) goto done; dev = MAKEDISKDEV(majdev, dv->dv_unit, RAW_PART); - bdsw = &bdevsw[majdev]; - - /* - * The devices are being opened with S_IFCHR instead of - * S_IFBLK so that the SCSI mid-layer does not whine when - * media is not inserted in certain devices like zip drives - * and such. - */ + if (bdevvp(dev, &vn)) { + printf("%s:, sr_meta_native_bootprobe: can't allocate vnode\n"); + goto done; + } /* open device */ - error = (*bdsw->d_open)(dev, FREAD, S_IFCHR, curproc); + error = VOP_OPEN(vn, FREAD, NOCRED, 0); if (error) { DNPRINTF(SR_D_META, "%s: sr_meta_native_bootprobe open " "failed\n", DEVNAME(sc)); + vput(vn); goto done; } /* get disklabel */ - error = (*bdsw->d_ioctl)(dev, DIOCGDINFO, (void *)&label, FREAD, - curproc); + error = VOP_IOCTL(vn, DIOCGDINFO, (caddr_t)&label, FREAD, NOCRED, 0); if (error) { DNPRINTF(SR_D_META, "%s: sr_meta_native_bootprobe ioctl " "failed\n", DEVNAME(sc)); - error = (*bdsw->d_close)(dev, FREAD, S_IFCHR, curproc); + VOP_CLOSE(vn, FREAD | FWRITE, NOCRED, 0); + vrele(vn); goto done; } /* we are done, close device */ - error = (*bdsw->d_close)(dev, FREAD, S_IFCHR, curproc); + error = VOP_CLOSE(vn, FREAD | FWRITE, NOCRED, 0); if (error) { DNPRINTF(SR_D_META, "%s: sr_meta_native_bootprobe close " "failed\n", DEVNAME(sc)); goto done; } + vrele(vn); md = malloc(SR_META_SIZE * 512, M_DEVBUF, M_ZERO); if (md == NULL) { @@ -911,23 +923,35 @@ sr_meta_native_bootprobe(struct sr_softc /* open partition */ devr = MAKEDISKDEV(majdev, dv->dv_unit, i); - error = (*bdsw->d_open)(devr, FREAD, S_IFCHR, curproc); + if (bdevvp(devr, &vn)) { + printf("%s:, sr_meta_native_bootprobe: can't allocate " + "vnode for partition\n"); + goto done; + } + error = VOP_OPEN(vn, FREAD, NOCRED, 0); if (error) { DNPRINTF(SR_D_META, "%s: sr_meta_native_bootprobe " "open failed, partition %d\n", DEVNAME(sc), i); + vput(vn); continue; } if (sr_meta_native_read(fake_sd, devr, md, NULL)) { printf("%s: native bootprobe could not read native " "metadata\n", DEVNAME(sc)); + VOP_CLOSE(vn, FREAD, NOCRED, 0); + vrele(vn); continue; } /* are we a softraid partition? */ - if (md->ssdi.ssd_magic != SR_MAGIC) + if (md->ssdi.ssd_magic != SR_MAGIC) { + VOP_CLOSE(vn, FREAD, NOCRED, 0); + vrele(vn); continue; + } + sr_meta_getdevname(sc, devr, devname, sizeof(devname)); if (sr_meta_validate(fake_sd, devr, md, NULL) == 0) { if (md->ssdi.ssd_flags & BIOC_SCNOAUTOASSEMBLE) { @@ -940,18 +964,20 @@ sr_meta_native_bootprobe(struct sr_softc bcopy(md, &mle->sml_metadata, SR_META_SIZE * 512); mle->sml_mm = devr; + mle->sml_vn = vn; SLIST_INSERT_HEAD(mlh, mle, sml_link); rv = SR_META_CLAIMED; } } /* we are done, close partition */ - error = (*bdsw->d_close)(devr, FREAD, S_IFCHR, curproc); + error = VOP_CLOSE(vn, FREAD, NOCRED, 0); if (error) { DNPRINTF(SR_D_META, "%s: sr_meta_native_bootprobe " "close failed\n", DEVNAME(sc)); continue; } + vrele(vn); } free(fake_sd, M_DEVBUF); @@ -1121,6 +1147,7 @@ sr_boot_assembly(struct sr_softc *sc) mle = SLIST_FIRST(&vol->sml); sr_meta_getdevname(sc, mle->sml_mm, devname, sizeof(devname)); hotspare->src_dev_mm = mle->sml_mm; + hotspare->src_vn = mle->sml_vn; strlcpy(hotspare->src_devname, devname, sizeof(hotspare->src_devname)); hotspare->src_size = metadata->ssdi.ssd_size; @@ -1252,19 +1279,16 @@ sr_meta_native_probe(struct sr_softc *sc char *devname; int error, part; daddr64_t size; - struct bdevsw *bdsw; - dev_t dev; DNPRINTF(SR_D_META, "%s: sr_meta_native_probe(%s)\n", DEVNAME(sc), ch_entry->src_devname); - dev = ch_entry->src_dev_mm; devname = ch_entry->src_devname; - bdsw = bdevsw_lookup(dev); - part = DISKPART(dev); + part = DISKPART(ch_entry->src_dev_mm); /* get disklabel */ - error = bdsw->d_ioctl(dev, DIOCGDINFO, (void *)&label, FREAD, curproc); + error = VOP_IOCTL(ch_entry->src_vn, DIOCGDINFO, (caddr_t)&label, FREAD, + NOCRED, 0); if (error) { DNPRINTF(SR_D_META, "%s: %s can't obtain disklabel\n", DEVNAME(sc), devname); @@ -2186,7 +2210,7 @@ sr_hotspare(struct sr_softc *sc, dev_t d struct sr_chunk *hotspare, *chunk, *last; struct sr_uuid uuid; struct disklabel label; - struct bdevsw *bdsw; + struct vnode *vn; daddr64_t size; char devname[32]; int rv = EINVAL; @@ -2213,20 +2237,25 @@ sr_hotspare(struct sr_softc *sc, dev_t d /* XXX - See if there is an existing degraded volume... */ /* Open device. */ - bdsw = bdevsw_lookup(dev); - if (bdsw->d_open(dev, FREAD | FWRITE, S_IFBLK, curproc)) { + if (bdevvp(dev, &vn)) { + printf("%s:, sr_meta_native_bootprobe: can't allocate vnode\n"); + goto done; + } + if (VOP_OPEN(vn, FREAD | FWRITE, NOCRED, 0)) { DNPRINTF(SR_D_META,"%s: sr_hotspare cannot open %s\n", DEVNAME(sc), devname); + vput(vn); goto fail; } open = 1; /* close dev on error */ /* Get partition details. */ part = DISKPART(dev); - if ((*bdsw->d_ioctl)(dev, DIOCGDINFO, (void *)&label, FREAD, - curproc)) { + if (VOP_IOCTL(vn, DIOCGDINFO, (caddr_t)&label, FREAD, NOCRED, 0)) { DNPRINTF(SR_D_META, "%s: sr_hotspare ioctl failed\n", DEVNAME(sc)); + VOP_CLOSE(vn, FREAD | FWRITE, NOCRED, 0); + vrele(vn); goto fail; } if (label.d_partitions[part].p_fstype != FS_RAID) { @@ -2248,6 +2277,7 @@ sr_hotspare(struct sr_softc *sc, dev_t d hotspare = malloc(sizeof(struct sr_chunk), M_DEVBUF, M_WAITOK | M_ZERO); hotspare->src_dev_mm = dev; + hotspare->src_vn = vn; strlcpy(hotspare->src_devname, devname, sizeof(hm->scmi.scm_devname)); hotspare->src_size = size; @@ -2334,8 +2364,10 @@ done: free(sd, M_DEVBUF); if (sm) free(sm, M_DEVBUF); - if (open) - (*bdsw->d_close)(dev, FREAD | FWRITE, S_IFCHR, curproc); + if (open) { + VOP_CLOSE(vn, FREAD | FWRITE, NOCRED, 0); + vrele(vn); + } return (rv); } @@ -2452,7 +2484,7 @@ sr_rebuild_init(struct sr_discipline *sd int rv = EINVAL, part; int c, found, open = 0; char devname[32]; - struct bdevsw *bdsw; + struct vnode *vn; daddr64_t size, csize; struct disklabel label; struct sr_meta_chunk *old, *new; @@ -2500,19 +2532,22 @@ sr_rebuild_init(struct sr_discipline *sd /* populate meta entry */ sr_meta_getdevname(sc, dev, devname, sizeof(devname)); - bdsw = bdevsw_lookup(dev); + if (bdevvp(dev, &vn)) { + printf("%s:, sr_ioctl_setstate: can't allocate vnode\n"); + goto done; + } - if (bdsw->d_open(dev, FREAD | FWRITE, S_IFBLK, curproc)) { + if (VOP_OPEN(vn, FREAD | FWRITE, NOCRED, 0)) { DNPRINTF(SR_D_META,"%s: sr_ioctl_setstate can't " "open %s\n", DEVNAME(sc), devname); + vput(vn); goto done; } open = 1; /* close dev on error */ /* get partition */ part = DISKPART(dev); - if ((*bdsw->d_ioctl)(dev, DIOCGDINFO, (void *)&label, FREAD, - curproc)) { + if (VOP_IOCTL(vn, DIOCGDINFO, (caddr_t)&label, FREAD, NOCRED, 0)) { DNPRINTF(SR_D_META, "%s: sr_ioctl_setstate ioctl failed\n", DEVNAME(sc)); goto done; @@ -2548,6 +2583,7 @@ sr_rebuild_init(struct sr_discipline *sd /* recreate metadata */ open = 0; /* leave dev open from here on out */ sd->sd_vol.sv_chunks[found]->src_dev_mm = dev; + sd->sd_vol.sv_chunks[found]->src_vn = vn; new->scmi.scm_volid = old->scmi.scm_volid; new->scmi.scm_chunk_id = found; strlcpy(new->scmi.scm_devname, devname, @@ -2574,8 +2610,10 @@ sr_rebuild_init(struct sr_discipline *sd rv = 0; done: - if (open) - (*bdsw->d_close)(dev, FREAD | FWRITE, S_IFCHR, curproc); + if (open) { + VOP_CLOSE(vn, FREAD | FWRITE, NOCRED, 0); + vrele(vn); + } return (rv); } @@ -3049,10 +3087,10 @@ sr_chunks_unwind(struct sr_softc *sc, st dev = ch_entry->src_dev_mm; DNPRINTF(SR_D_IOCTL, "%s: sr_chunks_unwind closing: %s\n", DEVNAME(sc), ch_entry->src_devname); - if (dev != NODEV) - bdevsw_lookup(dev)->d_close(dev, FWRITE, S_IFBLK, - curproc); - + if (dev != NODEV) { + VOP_CLOSE(ch_entry->src_vn, FREAD | FWRITE, NOCRED, 0); + vrele(ch_entry->src_vn); + } free(ch_entry, M_DEVBUF); } SLIST_INIT(cl); @@ -3362,7 +3400,7 @@ sr_raid_startwu(struct sr_workunit *wu) /* start all individual ios */ TAILQ_FOREACH(ccb, &wu->swu_ccb, ccb_link) { - bdevsw_lookup(ccb->ccb_buf.b_dev)->d_strategy(&ccb->ccb_buf); + VOP_STRATEGY(&ccb->ccb_buf); } } Index: softraid_aoe.c =================================================================== RCS file: /cvs/src/sys/dev/softraid_aoe.c,v retrieving revision 1.8 diff -u -p -r1.8 softraid_aoe.c --- softraid_aoe.c 24 Jul 2009 14:13:28 -0000 1.8 +++ softraid_aoe.c 4 Aug 2009 23:12:37 -0000 @@ -745,10 +745,13 @@ resleep: buf.b_error = 0; buf.b_proc = curproc; buf.b_dev = sd->sd_vol.sv_chunks[0]->src_dev_mm; + buf.b_vp = sd->sd_vol.sv_chunks[0]->src_vn; + if ((buf.b_flags & B_READ) == 0) + buf.b_vp->v_numoutput++; LIST_INIT(&buf.b_dep); s = splbio(); - bdevsw_lookup(buf.b_dev)->d_strategy(&buf); + VOP_STRATEGY(&buf); biowait(&buf); splx(s); @@ -808,10 +811,13 @@ resleep: buf.b_error = 0; buf.b_proc = curproc; buf.b_dev = sd->sd_vol.sv_chunks[0]->src_dev_mm; + buf.b_vp = sd->sd_vol.sv_chunks[0]->src_vn; + if ((buf.b_flags & B_READ) == 0) + buf.b_vp->v_numoutput++; LIST_INIT(&buf.b_dep); s = splbio(); - bdevsw_lookup(buf.b_dev)->d_strategy(&buf); + VOP_STRATEGY(&buf); biowait(&buf); splx(s); Index: softraid_crypto.c =================================================================== RCS file: /cvs/src/sys/dev/softraid_crypto.c,v retrieving revision 1.39 diff -u -p -r1.39 softraid_crypto.c --- softraid_crypto.c 11 Jun 2009 19:42:59 -0000 1.39 +++ softraid_crypto.c 4 Aug 2009 23:12:37 -0000 @@ -597,7 +597,9 @@ sr_crypto_rw2(struct sr_workunit *wu, st ccb->ccb_wu = wu; ccb->ccb_target = 0; ccb->ccb_buf.b_dev = sd->sd_vol.sv_chunks[0]->src_dev_mm; - ccb->ccb_buf.b_vp = NULL; + ccb->ccb_buf.b_vp = sd->sd_vol.sv_chunks[0]->src_vn; + if ((ccb->ccb_buf.b_flags & B_READ) == 0) + ccb->ccb_buf.b_vp->v_numoutput++; LIST_INIT(&ccb->ccb_buf.b_dep); Index: softraid_raid0.c =================================================================== RCS file: /cvs/src/sys/dev/softraid_raid0.c,v retrieving revision 1.15 diff -u -p -r1.15 softraid_raid0.c --- softraid_raid0.c 2 Jun 2009 21:23:11 -0000 1.15 +++ softraid_raid0.c 4 Aug 2009 23:12:37 -0000 @@ -303,7 +303,9 @@ sr_raid0_rw(struct sr_workunit *wu) B_READ : B_WRITE; ccb->ccb_target = chunk; ccb->ccb_buf.b_dev = sd->sd_vol.sv_chunks[chunk]->src_dev_mm; - ccb->ccb_buf.b_vp = NULL; + ccb->ccb_buf.b_vp = sd->sd_vol.sv_chunks[chunk]->src_vn; + if ((ccb->ccb_buf.b_flags & B_READ) == 0) + ccb->ccb_buf.b_vp->v_numoutput++; LIST_INIT(&ccb->ccb_buf.b_dep); TAILQ_INSERT_TAIL(&wu->swu_ccb, ccb, ccb_link); Index: softraid_raid1.c =================================================================== RCS file: /cvs/src/sys/dev/softraid_raid1.c,v retrieving revision 1.18 diff -u -p -r1.18 softraid_raid1.c --- softraid_raid1.c 12 Jul 2009 16:34:58 -0000 1.18 +++ softraid_raid1.c 4 Aug 2009 23:12:37 -0000 @@ -339,6 +339,7 @@ sr_raid1_rw(struct sr_workunit *wu) struct sr_discipline *sd = wu->swu_dis; struct scsi_xfer *xs = wu->swu_xs; struct sr_ccb *ccb; + struct buf *b; struct sr_chunk *scp; int ios, x, i, s, rt; daddr64_t blk; @@ -365,23 +366,24 @@ sr_raid1_rw(struct sr_workunit *wu) sd->sd_meta->ssd_devname); goto bad; } + b = &ccb->ccb_buf; if (xs->flags & SCSI_POLL) { - ccb->ccb_buf.b_flags = 0; - ccb->ccb_buf.b_iodone = NULL; + b->b_flags = 0; + b->b_iodone = NULL; } else { - ccb->ccb_buf.b_flags = B_CALL; - ccb->ccb_buf.b_iodone = sr_raid1_intr; + b->b_flags = B_CALL; + b->b_iodone = sr_raid1_intr; } - ccb->ccb_buf.b_flags |= B_PHYS; - ccb->ccb_buf.b_blkno = blk; - ccb->ccb_buf.b_bcount = xs->datalen; - ccb->ccb_buf.b_bufsize = xs->datalen; - ccb->ccb_buf.b_resid = xs->datalen; - ccb->ccb_buf.b_data = xs->data; - ccb->ccb_buf.b_error = 0; - ccb->ccb_buf.b_proc = curproc; + b->b_flags |= B_PHYS; + b->b_blkno = blk; + b->b_bcount = xs->datalen; + b->b_bufsize = xs->datalen; + b->b_resid = xs->datalen; + b->b_data = xs->data; + b->b_error = 0; + b->b_proc = curproc; ccb->ccb_wu = wu; if (xs->flags & SCSI_DATA_IN) { @@ -394,7 +396,7 @@ ragain: switch (scp->src_meta.scm_status) { case BIOC_SDONLINE: case BIOC_SDSCRUB: - ccb->ccb_buf.b_flags |= B_READ; + b->b_flags |= B_READ; break; case BIOC_SDOFFLINE: @@ -419,7 +421,7 @@ ragain: case BIOC_SDONLINE: case BIOC_SDSCRUB: case BIOC_SDREBUILD: - ccb->ccb_buf.b_flags |= B_WRITE; + b->b_flags |= B_WRITE; break; case BIOC_SDHOTSPARE: /* should never happen */ @@ -434,18 +436,20 @@ ragain: } ccb->ccb_target = x; - ccb->ccb_buf.b_dev = sd->sd_vol.sv_chunks[x]->src_dev_mm; - ccb->ccb_buf.b_vp = NULL; + b->b_dev = sd->sd_vol.sv_chunks[x]->src_dev_mm; + b->b_vp = sd->sd_vol.sv_chunks[x]->src_vn; + if ((b->b_flags & B_READ) == 0) + b->b_vp->v_numoutput++; - LIST_INIT(&ccb->ccb_buf.b_dep); + LIST_INIT(&b->b_dep); TAILQ_INSERT_TAIL(&wu->swu_ccb, ccb, ccb_link); DNPRINTF(SR_D_DIS, "%s: %s: sr_raid1: b_bcount: %d " "b_blkno: %x b_flags 0x%0x b_data %p\n", DEVNAME(sd->sd_sc), sd->sd_meta->ssd_devname, - ccb->ccb_buf.b_bcount, ccb->ccb_buf.b_blkno, - ccb->ccb_buf.b_flags, ccb->ccb_buf.b_data); + b->b_bcount, b->b_blkno, + b->b_flags, b->b_data); } s = splbio(); @@ -483,21 +487,22 @@ sr_raid1_intr(struct buf *bp) struct sr_discipline *sd = wu->swu_dis; struct scsi_xfer *xs = wu->swu_xs; struct sr_softc *sc = sd->sd_sc; + struct buf *b; int s, pend; DNPRINTF(SR_D_INTR, "%s: sr_intr bp %x xs %x\n", DEVNAME(sc), bp, xs); + b = &ccb->ccb_buf; DNPRINTF(SR_D_INTR, "%s: sr_intr: b_bcount: %d b_resid: %d" " b_flags: 0x%0x block: %lld target: %d\n", DEVNAME(sc), - ccb->ccb_buf.b_bcount, ccb->ccb_buf.b_resid, ccb->ccb_buf.b_flags, - ccb->ccb_buf.b_blkno, ccb->ccb_target); + b->b_bcount, b->b_resid, b->b_flags, b->b_blkno, ccb->ccb_target); s = splbio(); - if (ccb->ccb_buf.b_flags & B_ERROR) { + if (b->b_flags & B_ERROR) { DNPRINTF(SR_D_INTR, "%s: i/o error on block %lld target: %d\n", - DEVNAME(sc), ccb->ccb_buf.b_blkno, ccb->ccb_target); + DEVNAME(sc), b->b_blkno, ccb->ccb_target); wu->swu_ios_failed++; ccb->ccb_state = SR_CCB_FAILED; if (ccb->ccb_target != -1) @@ -520,7 +525,7 @@ sr_raid1_intr(struct buf *bp) if (wu->swu_ios_failed == wu->swu_ios_complete) { if (xs->flags & SCSI_DATA_IN) { printf("%s: retrying read on block %lld\n", - DEVNAME(sc), ccb->ccb_buf.b_blkno); + DEVNAME(sc), b->b_blkno); sr_ccb_put(ccb); TAILQ_INIT(&wu->swu_ccb); wu->swu_state = SR_WU_RESTART; @@ -530,8 +535,7 @@ sr_raid1_intr(struct buf *bp) goto retry; } else { printf("%s: permanently fail write on block " - "%lld\n", DEVNAME(sc), - ccb->ccb_buf.b_blkno); + "%lld\n", DEVNAME(sc), b->b_blkno); xs->error = XS_DRIVER_STUFFUP; goto bad; } Index: softraid_raid6.c =================================================================== RCS file: /cvs/src/sys/dev/softraid_raid6.c,v retrieving revision 1.2 diff -u -p -r1.2 softraid_raid6.c --- softraid_raid6.c 4 Aug 2009 20:17:14 -0000 1.2 +++ softraid_raid6.c 4 Aug 2009 23:12:37 -0000 @@ -394,6 +394,8 @@ sr_raid6_rw(struct sr_workunit *wu) datalen = xs->datalen; lbaoffs = blk << DEV_BSHIFT; + pbuf = NULL; + qbuf = NULL; if (xs->flags & SCSI_DATA_OUT) /* create write workunit */ if ((wu_w = sr_wu_get(sd, 0)) == NULL) { @@ -529,6 +531,16 @@ sr_raid6_rw(struct sr_workunit *wu) } /* XXX: bag of fail */ +#if 0 + if (wu_w == NULL) + if ((wu_w = sr_wu_get(sd, 0)) == NULL) + goto bad; + wu->swu_flags |= SR_WUF_FAIL; + if (sr_raid6_addio(wu_w, 0, 0, 0, pbuf, 0, + SR_CCBF_FREEBUF, NULL, data, + gf_inv(gf_pow[chunk]))) + goto bad; +#else wu->swu_flags |= SR_WUF_FAIL; sr_raid_startwu(wu); while ((wu->swu_flags & SR_WUF_FAILIOCOMP) == 0) { @@ -542,17 +554,10 @@ sr_raid6_rw(struct sr_workunit *wu) sr_wu_put(wu); scsi_done(xs); return(0); - +#endif break; case SR_FAILX+SR_FAILY: /* Dx, Dy failed */ - - /* cheat.. get other failed drive */ - for (fchunk=0; fchunk<no_chunk+2; fchunk++) { - if (fchunk != chunk && fchunk != qchunk && fchunk != pchunk) - break; - } - printf("Disk %llx & %llx offline, " "regenerating Dx+Dy\n", chunk, fchunk); qbuf = sr_get_block(sd, length); @@ -593,6 +598,20 @@ sr_raid6_rw(struct sr_workunit *wu) /* XXX: bag of fail */ +#if 0 + if (wu_w == NULL) + if ((wu_w = sr_wu_get(sd, 0)) == NULL) + goto bad; + wu->swu_flags |= SR_WUF_FAIL; + if (sr_raid6_addio(wu_w, 0, 0, 0, pbuf, 0, + SR_CCBF_FREEBUF, NULL, data, + gf_inv(gf_pow[255+chunk-fchunk] ^ 1))) + goto bad; + if (sr_raid6_addio(wu_w, 0, 0, 0, qbuf, 0, + SR_CCBF_FREEBUF, NULL, data, + gf_inv(gf_pow[chunk] ^ gf_pow[fchunk]))) + goto bad; +#else wu->swu_flags |= SR_WUF_FAIL; sr_raid_startwu(wu); while ((wu->swu_flags & SR_WUF_FAILIOCOMP) == 0) { @@ -611,7 +630,7 @@ sr_raid6_rw(struct sr_workunit *wu) sr_wu_put(wu); scsi_done(xs); return(0); - +#endif break; default: printf("%s: is offline, can't read\n", @@ -719,6 +738,10 @@ queued: return (0); bad: /* wu is unwound by sr_wu_put */ + if (pbuf) + sr_put_block(sd, pbuf); + if (qbuf) + sr_put_block(sd, qbuf); if (wu_w) sr_wu_put(wu_w); return (1); @@ -952,7 +975,9 @@ sr_raid6_addio(struct sr_workunit *wu, i ccb->ccb_buf.b_error = 0; ccb->ccb_buf.b_proc = curproc; ccb->ccb_buf.b_dev = sd->sd_vol.sv_chunks[dsk]->src_dev_mm; - ccb->ccb_buf.b_vp = NULL; + ccb->ccb_buf.b_vp = sd->sd_vol.sv_chunks[dsk]->src_vn; + if ((ccb->ccb_buf.b_flags & B_READ) == 0) + ccb->ccb_buf.b_vp->v_numoutput++; ccb->ccb_wu = wu; ccb->ccb_target = dsk; @@ -1003,6 +1028,11 @@ sr_raid6_xorq(void *q, void *d, int len, /* Have to do this a byte at a time */ while (len--) qbuf[len] ^= gf_mul(data[len], gn); + + /* Fast mode: + * gpow = gf_pow + index; + * while (len--) qbuf[len] ^= gpow[gf_log[data[len]]]; + */ } /* Create GF256 log/pow tables: polynomial = 0x11D */ Index: softraid_raidp.c =================================================================== RCS file: /cvs/src/sys/dev/softraid_raidp.c,v retrieving revision 1.9 diff -u -p -r1.9 softraid_raidp.c --- softraid_raidp.c 4 Aug 2009 20:17:14 -0000 1.9 +++ softraid_raidp.c 4 Aug 2009 23:12:38 -0000 @@ -729,7 +729,9 @@ sr_raidp_addio(struct sr_workunit *wu, i ccb->ccb_buf.b_error = 0; ccb->ccb_buf.b_proc = curproc; ccb->ccb_buf.b_dev = sd->sd_vol.sv_chunks[dsk]->src_dev_mm; - ccb->ccb_buf.b_vp = NULL; + ccb->ccb_buf.b_vp = sd->sd_vol.sv_chunks[dsk]->src_vn; + if ((ccb->ccb_buf.b_flags & B_READ) == 0) + ccb->ccb_buf.b_vp->v_numoutput++; ccb->ccb_wu = wu; ccb->ccb_target = dsk; Index: softraidvar.h =================================================================== RCS file: /cvs/src/sys/dev/softraidvar.h,v retrieving revision 1.80 diff -u -p -r1.80 softraidvar.h --- softraidvar.h 23 Jul 2009 15:15:25 -0000 1.80 +++ softraidvar.h 4 Aug 2009 23:12:38 -0000 @@ -20,6 +20,7 @@ #define SOFTRAIDVAR_H #include <crypto/md5.h> +#include <sys/vnode.h> #define SR_UUID_MAX 16 struct sr_uuid { @@ -341,6 +342,7 @@ struct sr_aoe { struct sr_metadata_list { u_int8_t sml_metadata[SR_META_SIZE * 512]; dev_t sml_mm; + struct vnode *sml_vn; u_int32_t sml_chunk_id; int sml_used; @@ -369,6 +371,7 @@ struct sr_chunk { /* runtime data */ dev_t src_dev_mm; /* major/minor */ + struct vnode *src_vn; /* vnode */ /* helper members before metadata makes it onto the chunk */ int src_meta_ondisk;/* set when meta is on disk */