static int cgd_diskstart(device_t dev, struct buf *bp) { struct cgd_softc *cs = device_private(dev); struct dk_softc *dksc = &cs->sc_dksc; struct buf *nbp; void * addr; void * newaddr; daddr_t bn; struct vnode *vp; DPRINTF_FOLLOW(("cgd_diskstart(%p, %p)\n", dksc, bp)); bn = bp->b_rawblkno; /* * We attempt to allocate all of our resources up front, so that * we can fail quickly if they are unavailable. */ nbp = getiobuf(cs->sc_tvn, false); if (nbp == NULL) return EAGAIN; /* * If we are writing, then we need to encrypt the outgoing * block into a new block of memory. */ newaddr = addr = bp->b_data; if ((bp->b_flags & B_READ) == 0) { newaddr = cgd_getdata(dksc, bp->b_bcount); if (!newaddr) { putiobuf(nbp); return EAGAIN; } cgd_cipher(cs, newaddr, addr, bp->b_bcount, bn, DEV_BSIZE, CGD_CIPHER_ENCRYPT); } nbp->b_data = newaddr; nbp->b_flags = bp->b_flags; nbp->b_oflags = bp->b_oflags; nbp->b_cflags = bp->b_cflags; nbp->b_iodone = cgdiodone; nbp->b_proc = bp->b_proc; nbp->b_blkno = bn; nbp->b_bcount = bp->b_bcount; nbp->b_private = bp; BIO_COPYPRIO(nbp, bp); if ((nbp->b_flags & B_READ) == 0) { vp = nbp->b_vp; mutex_enter(vp->v_interlock); vp->v_numoutput++; mutex_exit(vp->v_interlock); } VOP_STRATEGY(cs->sc_tvn, nbp); return 0; }
static void cgdiodone(struct buf *nbp) { struct buf *obp = nbp->b_private; struct cgd_softc *cs = getcgd_softc(obp->b_dev); struct dk_softc *dksc = &cs->sc_dksc; struct disk_geom *dg = &dksc->sc_dkdev.dk_geom; daddr_t bn; KDASSERT(cs); DPRINTF_FOLLOW(("cgdiodone(%p)\n", nbp)); DPRINTF(CGDB_IO, ("cgdiodone: bp %p bcount %d resid %d\n", obp, obp->b_bcount, obp->b_resid)); DPRINTF(CGDB_IO, (" dev 0x%"PRIx64", nbp %p bn %" PRId64 " addr %p bcnt %d\n", nbp->b_dev, nbp, nbp->b_blkno, nbp->b_data, nbp->b_bcount)); if (nbp->b_error != 0) { obp->b_error = nbp->b_error; DPRINTF(CGDB_IO, ("%s: error %d\n", dksc->sc_xname, obp->b_error)); } /* Perform the decryption if we are reading. * * Note: use the blocknumber from nbp, since it is what * we used to encrypt the blocks. */ if (nbp->b_flags & B_READ) { bn = dbtob(nbp->b_blkno) / dg->dg_secsize; cgd_cipher(cs, obp->b_data, obp->b_data, obp->b_bcount, bn, dg->dg_secsize, CGD_CIPHER_DECRYPT); } /* If we allocated memory, free it now... */ if (nbp->b_data != obp->b_data) cgd_putdata(dksc, nbp->b_data); putiobuf(nbp); /* Request is complete for whatever reason */ obp->b_resid = 0; if (obp->b_error != 0) obp->b_resid = obp->b_bcount; dk_done(dksc, obp); dk_start(dksc, NULL); }