From 81b5c339e872cfa95a68273b02d8eccb639741a9 Mon Sep 17 00:00:00 2001 From: Matthew Dillon Date: Fri, 17 Feb 2006 19:18:08 +0000 Subject: [PATCH] Make the entire BUF/BIO system BIO-centric instead of BUF-centric. Vnode and device strategy routines now take a BIO and must pass that BIO to biodone(). All code which previously managed a BUF undergoing I/O now manages a BIO. The new BIO-centric algorithms allow BIOs to be stacked, where each layer represents a block translation, completion callback, or caller or device private data. This information is no longer overloaded within the BUF. Translation layer linkages remain intact as a 'cache' after I/O has completed. The VOP and DEV strategy routines no longer make assumptions as to which translated block number applies to them. The use the block number in the BIO specifically passed to them. Change the 'untranslated' constant to NOOFFSET (for bio_offset), and (daddr_t)-1 (for bio_blkno). Rip out all code that previously set the translated block number to the untranslated block number to indicate that the translation had not been made. Rip out all the cluster linkage fields for clustered VFS and clustered paging operations. Clustering now occurs in a private BIO layer using private fields within the BIO. Reformulate the vn_strategy() and dev_dstrategy() abstraction(s). These routines no longer assume that bp->b_vp == the vp of the VOP operation, and the dev_t is no longer stored in the struct buf. Instead, only the vp passed to vn_strategy() (and related *_strategy() routines for VFS ops), and the dev_t passed to dev_dstrateg() (and related *_strategy() routines for device ops) is used by the VFS or DEV code. This will allow an arbitrary number of translation layers in the future. Create an independant per-BIO tracking entity, struct bio_track, which is used to determine when I/O is in-progress on the associated device or vnode. NOTE: Unlike FreeBSD's BIO work, our struct BUF is still used to hold the fields describing the data buffer, resid, and error state. Major-testing-by: Stefan Krueger --- sys/bus/cam/scsi/scsi_cd.c | 66 ++-- sys/bus/cam/scsi/scsi_ch.c | 6 +- sys/bus/cam/scsi/scsi_da.c | 64 ++-- sys/bus/cam/scsi/scsi_pass.c | 51 ++-- sys/bus/cam/scsi/scsi_pt.c | 54 ++-- sys/bus/cam/scsi/scsi_sa.c | 78 ++--- sys/bus/cam/scsi/scsi_ses.c | 4 +- sys/bus/firewire/firewirereg.h | 18 +- sys/bus/firewire/fwdev.c | 18 +- sys/bus/firewire/fwmem.c | 73 ++--- sys/contrib/dev/fla/fla.c | 45 +-- sys/dev/disk/ata/ata-disk.c | 74 +++-- sys/dev/disk/ata/ata-disk.h | 6 +- sys/dev/disk/ata/ata-raid.c | 111 +++---- sys/dev/disk/ata/ata-raid.h | 5 +- sys/dev/disk/ata/atapi-all.c | 10 +- sys/dev/disk/ata/atapi-cd.c | 87 +++--- sys/dev/disk/ata/atapi-cd.h | 4 +- sys/dev/disk/ata/atapi-fd.c | 42 +-- sys/dev/disk/ata/atapi-fd.h | 4 +- sys/dev/disk/ata/atapi-tape.c | 46 +-- sys/dev/disk/ata/atapi-tape.h | 4 +- sys/dev/disk/ccd/ccd.c | 135 ++++---- sys/dev/disk/fd/fd.c | 84 ++--- sys/dev/disk/fd/fdc.h | 6 +- sys/dev/disk/mcd/mcd.c | 70 +++-- sys/dev/disk/md/md.c | 78 ++--- sys/dev/disk/scd/scd.c | 58 ++-- sys/dev/disk/vn/vn.c | 60 ++-- sys/dev/disk/wt/wt.c | 9 +- sys/dev/misc/labpc/labpc.c | 148 ++++----- sys/dev/netif/de/if_de.c | 26 +- sys/dev/netif/de/if_devar.h | 3 +- sys/dev/raid/aac/aac.c | 40 +-- sys/dev/raid/aac/aac_compat.h | 10 +- sys/dev/raid/aac/aac_disk.c | 33 +- sys/dev/raid/aac/aacvar.h | 22 +- sys/dev/raid/amr/amr.c | 22 +- sys/dev/raid/amr/amr_compat.h | 52 +--- sys/dev/raid/amr/amr_disk.c | 29 +- sys/dev/raid/amr/amrvar.h | 4 +- sys/dev/raid/ida/ida.c | 28 +- sys/dev/raid/ida/ida_disk.c | 21 +- sys/dev/raid/ida/idavar.h | 10 +- sys/dev/raid/ips/ips.h | 10 +- sys/dev/raid/ips/ips_commands.c | 58 ++-- sys/dev/raid/ips/ips_disk.c | 28 +- sys/dev/raid/ips/ips_pci.c | 4 +- sys/dev/raid/mlx/mlx.c | 46 +-- sys/dev/raid/mlx/mlx_compat.h | 16 +- sys/dev/raid/mlx/mlx_disk.c | 39 +-- sys/dev/raid/mlx/mlxvar.h | 6 +- sys/dev/raid/pst/pst-raid.c | 71 +++-- sys/dev/raid/twe/twe.c | 36 ++- sys/dev/raid/twe/twe_compat.h | 16 +- sys/dev/raid/twe/twe_freebsd.c | 31 +- sys/dev/raid/twe/twevar.h | 19 +- sys/dev/raid/vinum/.gdbinit.crash | 1 + sys/dev/raid/vinum/.gdbinit.kernel | 13 +- sys/dev/raid/vinum/.gdbinit.vinum | 27 +- sys/dev/raid/vinum/request.h | 13 +- sys/dev/raid/vinum/vinumdaemon.c | 17 +- sys/dev/raid/vinum/vinumext.h | 6 +- sys/dev/raid/vinum/vinuminterrupt.c | 102 ++++--- sys/dev/raid/vinum/vinumio.c | 12 +- sys/dev/raid/vinum/vinumlock.c | 8 +- sys/dev/raid/vinum/vinumraid5.c | 8 +- sys/dev/raid/vinum/vinumrequest.c | 233 ++++++++------ sys/dev/raid/vinum/vinumrevive.c | 55 ++-- sys/dev/raid/vinum/vinumstate.c | 4 +- sys/dev/raid/vinum/vinumvar.h | 4 +- sys/i386/i386/machdep.c | 34 ++- sys/kern/kern_device.c | 39 ++- sys/kern/kern_physio.c | 29 +- sys/kern/kern_shutdown.c | 14 +- sys/kern/subr_disk.c | 116 +++---- sys/kern/subr_diskmbr.c | 22 +- sys/kern/subr_diskslice.c | 81 +++-- sys/kern/subr_xxx.c | 10 +- sys/kern/tty_cons.c | 4 +- sys/kern/vfs_aio.c | 26 +- sys/kern/vfs_bio.c | 439 ++++++++++++++------------- sys/kern/vfs_cluster.c | 132 ++++---- sys/kern/vfs_default.c | 12 +- sys/kern/vfs_lock.c | 4 +- sys/kern/vfs_subr.c | 55 +--- sys/kern/vfs_vopops.c | 8 +- sys/platform/pc32/i386/machdep.c | 34 ++- sys/sys/bio.h | 50 ++- sys/sys/biotrack.h | 18 ++ sys/sys/buf.h | 103 ++++--- sys/sys/buf2.h | 36 +-- sys/sys/conf.h | 17 +- sys/sys/device.h | 9 +- sys/sys/disklabel.h | 15 +- sys/sys/disklabel32.h | 15 +- sys/sys/diskslice.h | 5 +- sys/sys/odisklabel.h | 15 +- sys/sys/vfsops.h | 9 +- sys/sys/vnode.h | 11 +- sys/vfs/coda/coda_vnops.c | 10 +- sys/vfs/coda/coda_vnops.h | 4 +- sys/vfs/gnu/ext2fs/ext2_alloc.c | 12 +- sys/vfs/gnu/ext2fs/ext2_balloc.c | 14 +- sys/vfs/gnu/ext2fs/ext2_inode.c | 8 +- sys/vfs/gnu/ext2fs/ext2_subr.c | 16 +- sys/vfs/gnu/ext2fs/ext2_vnops.c | 8 +- sys/vfs/hpfs/hpfs_vnops.c | 31 +- sys/vfs/isofs/cd9660/cd9660_lookup.c | 17 +- sys/vfs/isofs/cd9660/cd9660_vnops.c | 33 +- sys/vfs/mfs/mfs_extern.h | 4 +- sys/vfs/mfs/mfs_vfsops.c | 32 +- sys/vfs/mfs/mfs_vnops.c | 50 +-- sys/vfs/mfs/mfsnode.h | 4 +- sys/vfs/msdosfs/msdosfs_fat.c | 11 +- sys/vfs/msdosfs/msdosfs_vfsops.c | 4 +- sys/vfs/msdosfs/msdosfs_vnops.c | 44 +-- sys/vfs/nfs/nfs.h | 7 +- sys/vfs/nfs/nfs_bio.c | 115 ++++--- sys/vfs/nfs/nfs_syscalls.c | 33 +- sys/vfs/nfs/nfs_vfsops.c | 4 +- sys/vfs/nfs/nfs_vnops.c | 59 ++-- sys/vfs/nfs/nfsmount.h | 10 +- sys/vfs/ntfs/ntfs_vnops.c | 27 +- sys/vfs/nwfs/nwfs.h | 4 +- sys/vfs/nwfs/nwfs_io.c | 21 +- sys/vfs/nwfs/nwfs_vnops.c | 9 +- sys/vfs/smbfs/smbfs.h | 4 +- sys/vfs/smbfs/smbfs_io.c | 18 +- sys/vfs/smbfs/smbfs_vnops.c | 9 +- sys/vfs/specfs/spec_vnops.c | 40 ++- sys/vfs/udf/udf_vnops.c | 35 +-- sys/vfs/ufs/ffs_alloc.c | 30 +- sys/vfs/ufs/ffs_balloc.c | 34 +-- sys/vfs/ufs/ffs_inode.c | 18 +- sys/vfs/ufs/ffs_rawread.c | 72 +++-- sys/vfs/ufs/ffs_softdep.c | 26 +- sys/vfs/ufs/ffs_subr.c | 14 +- sys/vfs/ufs/ffs_vfsops.c | 7 +- sys/vfs/ufs/ufs_bmap.c | 6 +- sys/vfs/ufs/ufs_vnops.c | 30 +- sys/vfs/union/union_vnops.c | 14 +- sys/vm/swap_pager.c | 282 ++++++++++++----- sys/vm/vm_pager.c | 137 +-------- sys/vm/vm_pager.h | 7 +- sys/vm/vm_swap.c | 66 ++-- sys/vm/vnode_pager.c | 21 +- 147 files changed, 2948 insertions(+), 2576 deletions(-) create mode 100644 sys/sys/biotrack.h diff --git a/sys/bus/cam/scsi/scsi_cd.c b/sys/bus/cam/scsi/scsi_cd.c index f06f982039..0a910d6c87 100644 --- a/sys/bus/cam/scsi/scsi_cd.c +++ b/sys/bus/cam/scsi/scsi_cd.c @@ -25,7 +25,7 @@ * SUCH DAMAGE. * * $FreeBSD: src/sys/cam/scsi/scsi_cd.c,v 1.31.2.16 2003/10/21 22:26:11 thomas Exp $ - * $DragonFly: src/sys/bus/cam/scsi/scsi_cd.c,v 1.19 2005/09/21 18:58:55 hsu Exp $ + * $DragonFly: src/sys/bus/cam/scsi/scsi_cd.c,v 1.20 2006/02/17 19:17:42 dillon Exp $ */ /* * Portions of this driver taken from the original FreeBSD cd driver. @@ -126,7 +126,7 @@ typedef enum { } cd_changer_flags; #define ccb_state ppriv_field0 -#define ccb_bp ppriv_ptr1 +#define ccb_bio ppriv_ptr1 struct cd_tocdata { struct ioc_toc_header header; @@ -147,7 +147,7 @@ struct cd_softc { cam_pinfo pinfo; cd_state state; volatile cd_flags flags; - struct buf_queue_head buf_queue; + struct bio_queue_head bio_queue; LIST_HEAD(, ccb_hdr) pending_ccbs; struct cd_params params; struct disk disk; @@ -405,6 +405,7 @@ cdoninvalidate(struct cam_periph *periph) { struct cd_softc *softc; struct buf *q_bp; + struct bio *q_bio; struct ccb_setasync csa; softc = (struct cd_softc *)periph->softc; @@ -434,12 +435,13 @@ cdoninvalidate(struct cam_periph *periph) * XXX Handle any transactions queued to the card * with XPT_ABORT_CCB. */ - while ((q_bp = bufq_first(&softc->buf_queue)) != NULL){ - bufq_remove(&softc->buf_queue, q_bp); + while ((q_bio = bioq_first(&softc->bio_queue)) != NULL){ + bioq_remove(&softc->bio_queue, q_bio); + q_bp = q_bio->bio_buf; q_bp->b_resid = q_bp->b_bcount; q_bp->b_error = ENXIO; q_bp->b_flags |= B_ERROR; - biodone(q_bp); + biodone(q_bio); } crit_exit(); @@ -705,7 +707,7 @@ cdregister(struct cam_periph *periph, void *arg) LIST_INIT(&softc->pending_ccbs); STAILQ_INIT(&softc->mode_queue); softc->state = CD_STATE_PROBE; - bufq_init(&softc->buf_queue); + bioq_init(&softc->bio_queue); if (SID_IS_REMOVABLE(&cgd->inq_data)) softc->flags |= CD_FLAG_DISC_REMOVABLE; if ((cgd->inq_data.flags & SID_CmdQue) != 0) @@ -1119,7 +1121,7 @@ cdshorttimeout(void *arg) * Check to see if there is any more pending or outstanding I/O for * this device. If not, move it out of the active slot. */ - if ((bufq_first(&changer->cur_device->buf_queue) == NULL) + if ((bioq_first(&changer->cur_device->bio_queue) == NULL) && (changer->cur_device->device_stats.busy_count == 0)) { changer->flags |= CHANGER_MANUAL_CALL; cdrunchangerqueue(changer); @@ -1242,7 +1244,7 @@ cdrunchangerqueue(void *arg) * to do. If so, requeue it at the end of the queue. If * not, there is no need to requeue it. */ - if (bufq_first(&changer->cur_device->buf_queue) != NULL) { + if (bioq_first(&changer->cur_device->bio_queue) != NULL) { changer->cur_device->pinfo.generation = ++changer->devq.generation; @@ -1323,7 +1325,7 @@ cdchangerschedule(struct cd_softc *softc) softc->flags &= ~CD_FLAG_SCHED_ON_COMP; cdrunchangerqueue(softc->changer); } - } else if ((bufq_first(&softc->buf_queue) == NULL) + } else if ((bioq_first(&softc->bio_queue) == NULL) && (softc->device_stats.busy_count == 0)) { softc->changer->flags |= CHANGER_MANUAL_CALL; cdrunchangerqueue(softc->changer); @@ -1431,14 +1433,15 @@ cdgetccb(struct cam_periph *periph, u_int32_t priority) * only one physical transfer. */ static void -cdstrategy(struct buf *bp) +cdstrategy(dev_t dev, struct bio *bio) { + struct buf *bp = bio->bio_buf; struct cam_periph *periph; struct cd_softc *softc; u_int unit, part; - unit = dkunit(bp->b_dev); - part = dkpart(bp->b_dev); + unit = dkunit(dev); + part = dkpart(dev); periph = cam_extend_get(cdperiphs, unit); if (periph == NULL) { bp->b_error = ENXIO; @@ -1483,7 +1486,7 @@ cdstrategy(struct buf *bp) /* * Place it in the queue of disk activities for this disk */ - bufqdisksort(&softc->buf_queue, bp); + bioqdisksort(&softc->bio_queue, bio); crit_exit(); @@ -1503,14 +1506,14 @@ bad: * Correctly set the buf to indicate a completed xfer */ bp->b_resid = bp->b_bcount; - biodone(bp); - return; + biodone(bio); } static void cdstart(struct cam_periph *periph, union ccb *start_ccb) { struct cd_softc *softc; + struct bio *bio; struct buf *bp; struct ccb_scsiio *csio; struct scsi_read_capacity_data *rcap; @@ -1523,7 +1526,7 @@ cdstart(struct cam_periph *periph, union ccb *start_ccb) case CD_STATE_NORMAL: { crit_enter(); - bp = bufq_first(&softc->buf_queue); + bio = bioq_first(&softc->bio_queue); if (periph->immediate_priority <= periph->pinfo.priority) { start_ccb->ccb_h.ccb_state = CD_CCB_WAITING; @@ -1532,11 +1535,12 @@ cdstart(struct cam_periph *periph, union ccb *start_ccb) periph->immediate_priority = CAM_PRIORITY_NONE; crit_exit(); wakeup(&periph->ccb_list); - } else if (bp == NULL) { + } else if (bio == NULL) { crit_exit(); xpt_release_ccb(start_ccb); } else { - bufq_remove(&softc->buf_queue, bp); + bp = bio->bio_buf; + bioq_remove(&softc->bio_queue, bio); devstat_start_transaction(&softc->device_stats); @@ -1549,7 +1553,7 @@ cdstart(struct cam_periph *periph, union ccb *start_ccb) /* read */bp->b_flags & B_READ, /* byte2 */ 0, /* minimum_cmd_size */ 10, - /* lba */ bp->b_pblkno, + /* lba */ bio->bio_blkno, bp->b_bcount / softc->params.blksize, /* data_ptr */ bp->b_data, /* dxfer_len */ bp->b_bcount, @@ -1571,13 +1575,13 @@ cdstart(struct cam_periph *periph, union ccb *start_ccb) softc->flags &= ~CD_FLAG_RETRY_UA; } - start_ccb->ccb_h.ccb_bp = bp; - bp = bufq_first(&softc->buf_queue); + start_ccb->ccb_h.ccb_bio = bio; + bio = bioq_first(&softc->bio_queue); crit_exit(); xpt_action(start_ccb); } - if (bp != NULL) { + if (bio != NULL) { /* Have more work to do, so ensure we stay scheduled */ xpt_schedule(periph, /* XXX priority */1); } @@ -1595,7 +1599,7 @@ cdstart(struct cam_periph *periph, union ccb *start_ccb) rcap, SSD_FULL_SIZE, /*timeout*/20000); - start_ccb->ccb_h.ccb_bp = NULL; + start_ccb->ccb_h.ccb_bio = NULL; start_ccb->ccb_h.ccb_state = CD_CCB_PROBE; xpt_action(start_ccb); break; @@ -1618,9 +1622,11 @@ cddone(struct cam_periph *periph, union ccb *done_ccb) case CD_CCB_BUFFER_IO: { struct buf *bp; + struct bio *bio; int error; - bp = (struct buf *)done_ccb->ccb_h.ccb_bp; + bio = (struct bio *)done_ccb->ccb_h.ccb_bio; + bp = bio->bio_buf; error = 0; if ((done_ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) { @@ -1644,17 +1650,19 @@ cddone(struct cam_periph *periph, union ccb *done_ccb) } if (error != 0) { + struct bio *q_bio; struct buf *q_bp; xpt_print_path(periph->path); printf("cddone: got error %#x back\n", error); crit_enter(); - while ((q_bp = bufq_first(&softc->buf_queue)) != NULL) { - bufq_remove(&softc->buf_queue, q_bp); + while ((q_bio = bioq_first(&softc->bio_queue)) != NULL) { + bioq_remove(&softc->bio_queue, q_bio); + q_bp = q_bio->bio_buf; q_bp->b_resid = q_bp->b_bcount; q_bp->b_error = EIO; q_bp->b_flags |= B_ERROR; - biodone(q_bp); + biodone(q_bio); } crit_exit(); bp->b_resid = bp->b_bcount; @@ -1687,7 +1695,7 @@ cddone(struct cam_periph *periph, union ccb *done_ccb) cdchangerschedule(softc); devstat_end_transaction_buf(&softc->device_stats, bp); - biodone(bp); + biodone(bio); break; } case CD_CCB_PROBE: diff --git a/sys/bus/cam/scsi/scsi_ch.c b/sys/bus/cam/scsi/scsi_ch.c index 36cce368bd..e72ad5e7bd 100644 --- a/sys/bus/cam/scsi/scsi_ch.c +++ b/sys/bus/cam/scsi/scsi_ch.c @@ -25,7 +25,7 @@ * SUCH DAMAGE. * * $FreeBSD: src/sys/cam/scsi/scsi_ch.c,v 1.20.2.2 2000/10/31 08:09:49 dwmalone Exp $ - * $DragonFly: src/sys/bus/cam/scsi/scsi_ch.c,v 1.12 2006/01/22 14:03:51 swildner Exp $ + * $DragonFly: src/sys/bus/cam/scsi/scsi_ch.c,v 1.13 2006/02/17 19:17:42 dillon Exp $ */ /* * Derived from the NetBSD SCSI changer driver. @@ -131,7 +131,7 @@ typedef enum { } ch_quirks; #define ccb_state ppriv_field0 -#define ccb_bp ppriv_ptr1 +#define ccb_bio ppriv_ptr1 struct scsi_mode_sense_data { struct scsi_mode_header_6 header; @@ -549,7 +549,7 @@ chstart(struct cam_periph *periph, union ccb *start_ccb) /* sense_len */ SSD_FULL_SIZE, /* timeout */ CH_TIMEOUT_MODE_SENSE); - start_ccb->ccb_h.ccb_bp = NULL; + start_ccb->ccb_h.ccb_bio = NULL; start_ccb->ccb_h.ccb_state = CH_CCB_PROBE; xpt_action(start_ccb); break; diff --git a/sys/bus/cam/scsi/scsi_da.c b/sys/bus/cam/scsi/scsi_da.c index 45bfe72ea9..a6890f5ddb 100644 --- a/sys/bus/cam/scsi/scsi_da.c +++ b/sys/bus/cam/scsi/scsi_da.c @@ -26,7 +26,7 @@ * SUCH DAMAGE. * * $FreeBSD: src/sys/cam/scsi/scsi_da.c,v 1.42.2.46 2003/10/21 22:18:19 thomas Exp $ - * $DragonFly: src/sys/bus/cam/scsi/scsi_da.c,v 1.26 2006/01/22 14:03:51 swildner Exp $ + * $DragonFly: src/sys/bus/cam/scsi/scsi_da.c,v 1.27 2006/02/17 19:17:42 dillon Exp $ */ #ifdef _KERNEL @@ -119,7 +119,7 @@ typedef enum { /* Offsets into our private area for storing information */ #define ccb_state ppriv_field0 -#define ccb_bp ppriv_ptr1 +#define ccb_bio ppriv_ptr1 struct disk_params { u_int8_t heads; @@ -130,7 +130,7 @@ struct disk_params { }; struct da_softc { - struct buf_queue_head buf_queue; + struct bio_queue_head bio_queue; struct devstat device_stats; SLIST_ENTRY(da_softc) links; LIST_HEAD(, ccb_hdr) pending_ccbs; @@ -573,7 +573,7 @@ daopen(dev_t dev, int flags, int fmt, struct thread *td) rcap, SSD_FULL_SIZE, /*timeout*/60000); - ccb->ccb_h.ccb_bp = NULL; + ccb->ccb_h.ccb_bio = NULL; error = cam_periph_runccb(ccb, daerror, /*cam_flags*/0, /*sense_flags*/SF_RETRY_UA | @@ -736,15 +736,16 @@ daclose(dev_t dev, int flag, int fmt, struct thread *td) * only one physical transfer. */ static void -dastrategy(struct buf *bp) +dastrategy(dev_t dev, struct bio *bio) { + struct buf *bp = bio->bio_buf; struct cam_periph *periph; struct da_softc *softc; u_int unit; u_int part; - unit = dkunit(bp->b_dev); - part = dkpart(bp->b_dev); + unit = dkunit(dev); + part = dkpart(dev); periph = cam_extend_get(daperiphs, unit); if (periph == NULL) { bp->b_error = ENXIO; @@ -755,7 +756,7 @@ dastrategy(struct buf *bp) /* * check it's not too big a transfer for our adapter */ - scsi_minphys(bp,&sd_switch); + scsi_minphys(bp, &sd_switch); #endif /* @@ -777,7 +778,7 @@ dastrategy(struct buf *bp) /* * Place it in the queue of disk activities for this disk */ - bufqdisksort(&softc->buf_queue, bp); + bioqdisksort(&softc->bio_queue, bio); crit_exit(); @@ -794,8 +795,7 @@ bad: * Correctly set the buf to indicate a completed xfer */ bp->b_resid = bp->b_bcount; - biodone(bp); - return; + biodone(bio); } /* For 2.2-stable support */ @@ -1013,6 +1013,7 @@ static void daoninvalidate(struct cam_periph *periph) { struct da_softc *softc; + struct bio *q_bio; struct buf *q_bp; struct ccb_setasync csa; @@ -1042,12 +1043,13 @@ daoninvalidate(struct cam_periph *periph) * XXX Handle any transactions queued to the card * with XPT_ABORT_CCB. */ - while ((q_bp = bufq_first(&softc->buf_queue)) != NULL){ - bufq_remove(&softc->buf_queue, q_bp); + while ((q_bio = bioq_first(&softc->bio_queue)) != NULL){ + bioq_remove(&softc->bio_queue, q_bio); + q_bp = q_bio->bio_buf; q_bp->b_resid = q_bp->b_bcount; q_bp->b_error = ENXIO; q_bp->b_flags |= B_ERROR; - biodone(q_bp); + biodone(q_bio); } crit_exit(); @@ -1233,7 +1235,7 @@ daregister(struct cam_periph *periph, void *arg) softc = malloc(sizeof(*softc), M_DEVBUF, M_INTWAIT | M_ZERO); LIST_INIT(&softc->pending_ccbs); softc->state = DA_STATE_PROBE; - bufq_init(&softc->buf_queue); + bioq_init(&softc->bio_queue); if (SID_IS_REMOVABLE(&cgd->inq_data)) softc->flags |= DA_FLAG_PACK_REMOVABLE; if ((cgd->inq_data.flags & SID_CmdQue) != 0) @@ -1354,13 +1356,14 @@ dastart(struct cam_periph *periph, union ccb *start_ccb) case DA_STATE_NORMAL: { /* Pull a buffer from the queue and get going on it */ + struct bio *bio; struct buf *bp; /* * See if there is a buf with work for us to do.. */ crit_enter(); - bp = bufq_first(&softc->buf_queue); + bio = bioq_first(&softc->bio_queue); if (periph->immediate_priority <= periph->pinfo.priority) { CAM_DEBUG_PRINT(CAM_DEBUG_SUBTRACE, ("queuing for immediate ccb\n")); @@ -1370,13 +1373,14 @@ dastart(struct cam_periph *periph, union ccb *start_ccb) periph->immediate_priority = CAM_PRIORITY_NONE; crit_exit(); wakeup(&periph->ccb_list); - } else if (bp == NULL) { + } else if (bio == NULL) { crit_exit(); xpt_release_ccb(start_ccb); } else { u_int8_t tag_code; - bufq_remove(&softc->buf_queue, bp); + bioq_remove(&softc->bio_queue, bio); + bp = bio->bio_buf; devstat_start_transaction(&softc->device_stats); @@ -1395,7 +1399,7 @@ dastart(struct cam_periph *periph, union ccb *start_ccb) bp->b_flags & B_READ, /*byte2*/0, softc->minimum_cmd_size, - bp->b_pblkno, + bio->bio_blkno, bp->b_bcount / softc->params.secsize, bp->b_data, bp->b_bcount, @@ -1416,14 +1420,14 @@ dastart(struct cam_periph *periph, union ccb *start_ccb) softc->flags &= ~DA_FLAG_RETRY_UA; } - start_ccb->ccb_h.ccb_bp = bp; - bp = bufq_first(&softc->buf_queue); + start_ccb->ccb_h.ccb_bio = bio; + bio = bioq_first(&softc->bio_queue); crit_exit(); xpt_action(start_ccb); } - if (bp != NULL) { + if (bio != NULL) { /* Have more work to do, so ensure we stay scheduled */ xpt_schedule(periph, /* XXX priority */1); } @@ -1443,7 +1447,7 @@ dastart(struct cam_periph *periph, union ccb *start_ccb) rcap, SSD_FULL_SIZE, /*timeout*/5000); - start_ccb->ccb_h.ccb_bp = NULL; + start_ccb->ccb_h.ccb_bio = NULL; start_ccb->ccb_h.ccb_state = DA_CCB_PROBE; xpt_action(start_ccb); break; @@ -1509,8 +1513,10 @@ dadone(struct cam_periph *periph, union ccb *done_ccb) case DA_CCB_BUFFER_IO: { struct buf *bp; + struct bio *bio; - bp = (struct buf *)done_ccb->ccb_h.ccb_bp; + bio = (struct bio *)done_ccb->ccb_h.ccb_bio; + bp = bio->bio_buf; if ((done_ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) { int error; int sf; @@ -1531,6 +1537,7 @@ dadone(struct cam_periph *periph, union ccb *done_ccb) return; } if (error != 0) { + struct bio *q_bio; struct buf *q_bp; crit_enter(); @@ -1553,13 +1560,14 @@ dadone(struct cam_periph *periph, union ccb *done_ccb) * the client can retry these I/Os in the * proper order should it attempt to recover. */ - while ((q_bp = bufq_first(&softc->buf_queue)) + while ((q_bio = bioq_first(&softc->bio_queue)) != NULL) { - bufq_remove(&softc->buf_queue, q_bp); + bioq_remove(&softc->bio_queue, q_bio); + q_bp = q_bio->bio_buf; q_bp->b_resid = q_bp->b_bcount; q_bp->b_error = EIO; q_bp->b_flags |= B_ERROR; - biodone(q_bp); + biodone(q_bio); } crit_exit(); bp->b_error = error; @@ -1595,7 +1603,7 @@ dadone(struct cam_periph *periph, union ccb *done_ccb) softc->flags |= DA_FLAG_WENT_IDLE; devstat_end_transaction_buf(&softc->device_stats, bp); - biodone(bp); + biodone(bio); break; } case DA_CCB_PROBE: diff --git a/sys/bus/cam/scsi/scsi_pass.c b/sys/bus/cam/scsi/scsi_pass.c index 1e73fc24f9..8be0a7988c 100644 --- a/sys/bus/cam/scsi/scsi_pass.c +++ b/sys/bus/cam/scsi/scsi_pass.c @@ -25,7 +25,7 @@ * SUCH DAMAGE. * * $FreeBSD: src/sys/cam/scsi/scsi_pass.c,v 1.19 2000/01/17 06:27:37 mjacob Exp $ - * $DragonFly: src/sys/bus/cam/scsi/scsi_pass.c,v 1.13 2005/06/02 20:40:31 dillon Exp $ + * $DragonFly: src/sys/bus/cam/scsi/scsi_pass.c,v 1.14 2006/02/17 19:17:42 dillon Exp $ */ #include @@ -73,13 +73,13 @@ typedef enum { } pass_ccb_types; #define ccb_type ppriv_field0 -#define ccb_bp ppriv_ptr1 +#define ccb_bio ppriv_ptr1 struct pass_softc { pass_state state; pass_flags flags; u_int8_t pd_type; - struct buf_queue_head buf_queue; + struct bio_queue_head bio_queue; union ccb saved_ccb; struct devstat device_stats; }; @@ -181,6 +181,7 @@ passoninvalidate(struct cam_periph *periph) { struct pass_softc *softc; struct buf *q_bp; + struct bio *q_bio; struct ccb_setasync csa; softc = (struct pass_softc *)periph->softc; @@ -209,12 +210,13 @@ passoninvalidate(struct cam_periph *periph) * XXX Handle any transactions queued to the card * with XPT_ABORT_CCB. */ - while ((q_bp = bufq_first(&softc->buf_queue)) != NULL){ - bufq_remove(&softc->buf_queue, q_bp); + while ((q_bio = bioq_first(&softc->bio_queue)) != NULL){ + bioq_remove(&softc->bio_queue, q_bio); + q_bp = q_bio->bio_buf; q_bp->b_resid = q_bp->b_bcount; q_bp->b_error = ENXIO; q_bp->b_flags |= B_ERROR; - biodone(q_bp); + biodone(q_bio); } crit_exit(); @@ -304,7 +306,7 @@ passregister(struct cam_periph *periph, void *arg) softc = malloc(sizeof(*softc), M_DEVBUF, M_INTWAIT | M_ZERO); softc->state = PASS_STATE_NORMAL; softc->pd_type = SID_TYPE(&cgd->inq_data); - bufq_init(&softc->buf_queue); + bioq_init(&softc->bio_queue); periph->softc = softc; @@ -448,8 +450,9 @@ passclose(dev_t dev, int flag, int fmt, struct thread *td) * only one physical transfer. */ static void -passstrategy(struct buf *bp) +passstrategy(dev_t dev, struct bio *bio) { + struct buf *bp = bio->bio_buf; struct cam_periph *periph; struct pass_softc *softc; u_int unit; @@ -462,9 +465,9 @@ passstrategy(struct buf *bp) bp->b_error = EINVAL; goto bad; - /* unit = dkunit(bp->b_dev); */ + /* unit = dkunit(dev); */ /* XXX KDM fix this */ - unit = minor(bp->b_dev) & 0xff; + unit = minor(dev) & 0xff; periph = cam_extend_get(passperiphs, unit); if (periph == NULL) { @@ -477,7 +480,7 @@ passstrategy(struct buf *bp) * Odd number of bytes or negative offset */ /* valid request? */ - if (bp->b_blkno < 0) { + if (bio->bio_blkno < 0) { bp->b_error = EINVAL; goto bad; } @@ -488,7 +491,7 @@ passstrategy(struct buf *bp) * clean up one of the buffers. */ crit_enter(); - bufq_insert_tail(&softc->buf_queue, bp); + bioq_insert_tail(&softc->bio_queue, bio); crit_exit(); /* @@ -504,8 +507,7 @@ bad: * Correctly set the buf to indicate a completed xfer */ bp->b_resid = bp->b_bcount; - biodone(bp); - return; + biodone(bio); } static void @@ -519,9 +521,10 @@ passstart(struct cam_periph *periph, union ccb *start_ccb) case PASS_STATE_NORMAL: { struct buf *bp; + struct bio *bio; crit_enter(); - bp = bufq_first(&softc->buf_queue); + bio = bioq_first(&softc->bio_queue); if (periph->immediate_priority <= periph->pinfo.priority) { start_ccb->ccb_h.ccb_type = PASS_CCB_WAITING; SLIST_INSERT_HEAD(&periph->ccb_list, &start_ccb->ccb_h, @@ -529,12 +532,13 @@ passstart(struct cam_periph *periph, union ccb *start_ccb) periph->immediate_priority = CAM_PRIORITY_NONE; crit_exit(); wakeup(&periph->ccb_list); - } else if (bp == NULL) { + } else if (bio == NULL) { crit_exit(); xpt_release_ccb(start_ccb); } else { - bufq_remove(&softc->buf_queue, bp); + bioq_remove(&softc->bio_queue, bio); + bp = bio->bio_buf; devstat_start_transaction(&softc->device_stats); @@ -549,14 +553,14 @@ passstart(struct cam_periph *periph, union ccb *start_ccb) bp->b_error = EIO; bp->b_flags |= B_ERROR; bp->b_resid = bp->b_bcount; - biodone(bp); - bp = bufq_first(&softc->buf_queue); + biodone(bio); + bio = bioq_first(&softc->bio_queue); crit_exit(); xpt_action(start_ccb); } - if (bp != NULL) { + if (bio != NULL) { /* Have more work to do, so ensure we stay scheduled */ xpt_schedule(periph, /* XXX priority */1); } @@ -575,6 +579,7 @@ passdone(struct cam_periph *periph, union ccb *done_ccb) switch (csio->ccb_h.ccb_type) { case PASS_CCB_BUFFER_IO: { + struct bio *bio; struct buf *bp; cam_status status; u_int8_t scsi_status; @@ -582,7 +587,9 @@ passdone(struct cam_periph *periph, union ccb *done_ccb) status = done_ccb->ccb_h.status; scsi_status = done_ccb->csio.scsi_status; - bp = (struct buf *)done_ccb->ccb_h.ccb_bp; + bio = (struct bio *)done_ccb->ccb_h.ccb_bio; + bp = bio->bio_buf; + /* XXX handle errors */ if (!(((status & CAM_STATUS_MASK) == CAM_REQ_CMP) && (scsi_status == SCSI_STATUS_OK))) { @@ -612,7 +619,7 @@ passdone(struct cam_periph *periph, union ccb *done_ccb) ds_flags = DEVSTAT_NO_DATA; devstat_end_transaction_buf(&softc->device_stats, bp); - biodone(bp); + biodone(bio); break; } case PASS_CCB_WAITING: diff --git a/sys/bus/cam/scsi/scsi_pt.c b/sys/bus/cam/scsi/scsi_pt.c index f7ec350ab3..0c8c472883 100644 --- a/sys/bus/cam/scsi/scsi_pt.c +++ b/sys/bus/cam/scsi/scsi_pt.c @@ -26,7 +26,7 @@ * SUCH DAMAGE. * * $FreeBSD: src/sys/cam/scsi/scsi_pt.c,v 1.17 2000/01/17 06:27:37 mjacob Exp $ - * $DragonFly: src/sys/bus/cam/scsi/scsi_pt.c,v 1.12 2005/06/02 20:40:31 dillon Exp $ + * $DragonFly: src/sys/bus/cam/scsi/scsi_pt.c,v 1.13 2006/02/17 19:17:42 dillon Exp $ */ #include @@ -76,10 +76,10 @@ typedef enum { /* Offsets into our private area for storing information */ #define ccb_state ppriv_field0 -#define ccb_bp ppriv_ptr1 +#define ccb_bio ppriv_ptr1 struct pt_softc { - struct buf_queue_head buf_queue; + struct bio_queue_head bio_queue; struct devstat device_stats; LIST_HEAD(, ccb_hdr) pending_ccbs; pt_state state; @@ -219,13 +219,14 @@ ptclose(dev_t dev, int flag, int fmt, struct thread *td) * only one physical transfer. */ static void -ptstrategy(struct buf *bp) +ptstrategy(dev_t dev, struct bio *bio) { + struct buf *bp = bio->bio_buf; struct cam_periph *periph; struct pt_softc *softc; u_int unit; - unit = minor(bp->b_dev); + unit = minor(dev); periph = cam_extend_get(ptperiphs, unit); if (periph == NULL) { bp->b_error = ENXIO; @@ -252,7 +253,7 @@ ptstrategy(struct buf *bp) /* * Place it in the queue of disk activities for this disk */ - bufq_insert_tail(&softc->buf_queue, bp); + bioq_insert_tail(&softc->bio_queue, bio); crit_exit(); @@ -269,7 +270,7 @@ bad: * Correctly set the buf to indicate a completed xfer */ bp->b_resid = bp->b_bcount; - biodone(bp); + biodone(bio); } static void @@ -334,7 +335,7 @@ ptctor(struct cam_periph *periph, void *arg) softc = malloc(sizeof(*softc), M_DEVBUF, M_INTWAIT | M_ZERO); LIST_INIT(&softc->pending_ccbs); softc->state = PT_STATE_NORMAL; - bufq_init(&softc->buf_queue); + bioq_init(&softc->bio_queue); softc->io_timeout = SCSI_PT_DEFAULT_TIMEOUT * 1000; @@ -377,6 +378,7 @@ static void ptoninvalidate(struct cam_periph *periph) { struct pt_softc *softc; + struct bio *q_bio; struct buf *q_bp; struct ccb_setasync csa; @@ -406,12 +408,13 @@ ptoninvalidate(struct cam_periph *periph) * XXX Handle any transactions queued to the card * with XPT_ABORT_CCB. */ - while ((q_bp = bufq_first(&softc->buf_queue)) != NULL){ - bufq_remove(&softc->buf_queue, q_bp); + while ((q_bio = bioq_first(&softc->bio_queue)) != NULL){ + bioq_remove(&softc->bio_queue, q_bio); + q_bp = q_bio->bio_buf; q_bp->b_resid = q_bp->b_bcount; q_bp->b_error = ENXIO; q_bp->b_flags |= B_ERROR; - biodone(q_bp); + biodone(q_bio); } crit_exit(); @@ -499,6 +502,7 @@ ptstart(struct cam_periph *periph, union ccb *start_ccb) { struct pt_softc *softc; struct buf *bp; + struct bio *bio; softc = (struct pt_softc *)periph->softc; @@ -506,7 +510,7 @@ ptstart(struct cam_periph *periph, union ccb *start_ccb) * See if there is a buf with work for us to do.. */ crit_enter(); - bp = bufq_first(&softc->buf_queue); + bio = bioq_first(&softc->bio_queue); if (periph->immediate_priority <= periph->pinfo.priority) { CAM_DEBUG_PRINT(CAM_DEBUG_SUBTRACE, ("queuing for immediate ccb\n")); @@ -516,11 +520,12 @@ ptstart(struct cam_periph *periph, union ccb *start_ccb) periph->immediate_priority = CAM_PRIORITY_NONE; crit_exit(); wakeup(&periph->ccb_list); - } else if (bp == NULL) { + } else if (bio == NULL) { crit_exit(); xpt_release_ccb(start_ccb); } else { - bufq_remove(&softc->buf_queue, bp); + bioq_remove(&softc->bio_queue, bio); + bp = bio->bio_buf; devstat_start_transaction(&softc->device_stats); @@ -544,13 +549,13 @@ ptstart(struct cam_periph *periph, union ccb *start_ccb) LIST_INSERT_HEAD(&softc->pending_ccbs, &start_ccb->ccb_h, periph_links.le); - start_ccb->ccb_h.ccb_bp = bp; - bp = bufq_first(&softc->buf_queue); + start_ccb->ccb_h.ccb_bio = bio; + bio = bioq_first(&softc->bio_queue); crit_exit(); xpt_action(start_ccb); - if (bp != NULL) { + if (bio != NULL) { /* Have more work to do, so ensure we stay scheduled */ xpt_schedule(periph, /* XXX priority */1); } @@ -570,8 +575,11 @@ ptdone(struct cam_periph *periph, union ccb *done_ccb) case PT_CCB_BUFFER_IO_UA: { struct buf *bp; + struct bio *bio; + + bio = (struct bio *)done_ccb->ccb_h.ccb_bio; + bp = bio->bio_buf; - bp = (struct buf *)done_ccb->ccb_h.ccb_bp; if ((done_ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) { int error; int sf; @@ -592,6 +600,7 @@ ptdone(struct cam_periph *periph, union ccb *done_ccb) } if (error != 0) { struct buf *q_bp; + struct bio *q_bio; crit_enter(); @@ -610,13 +619,14 @@ ptdone(struct cam_periph *periph, union ccb *done_ccb) * the client can retry these I/Os in the * proper order should it attempt to recover. */ - while ((q_bp = bufq_first(&softc->buf_queue)) + while ((q_bio = bioq_first(&softc->bio_queue)) != NULL) { - bufq_remove(&softc->buf_queue, q_bp); + bioq_remove(&softc->bio_queue, q_bio); + q_bp = q_bio->bio_buf; q_bp->b_resid = q_bp->b_bcount; q_bp->b_error = EIO; q_bp->b_flags |= B_ERROR; - biodone(q_bp); + biodone(q_bio); } crit_exit(); bp->b_error = error; @@ -651,7 +661,7 @@ ptdone(struct cam_periph *periph, union ccb *done_ccb) crit_exit(); devstat_end_transaction_buf(&softc->device_stats, bp); - biodone(bp); + biodone(bio); break; } case PT_CCB_WAITING: diff --git a/sys/bus/cam/scsi/scsi_sa.c b/sys/bus/cam/scsi/scsi_sa.c index 97a75e709a..cc4a32870d 100644 --- a/sys/bus/cam/scsi/scsi_sa.c +++ b/sys/bus/cam/scsi/scsi_sa.c @@ -1,6 +1,6 @@ /* * $FreeBSD: src/sys/cam/scsi/scsi_sa.c,v 1.45.2.13 2002/12/17 17:08:50 trhodes Exp $ - * $DragonFly: src/sys/bus/cam/scsi/scsi_sa.c,v 1.14 2006/01/22 14:03:51 swildner Exp $ + * $DragonFly: src/sys/bus/cam/scsi/scsi_sa.c,v 1.15 2006/02/17 19:17:42 dillon Exp $ * * Implementation of SCSI Sequential Access Peripheral driver for CAM. * @@ -113,7 +113,7 @@ typedef enum { } sa_state; #define ccb_pflags ppriv_field0 -#define ccb_bp ppriv_ptr1 +#define ccb_bio ppriv_ptr1 #define SA_CCB_BUFFER_IO 0x0 #define SA_CCB_WAITING 0x1 @@ -205,7 +205,7 @@ struct sa_softc { sa_state state; sa_flags flags; sa_quirks quirks; - struct buf_queue_head buf_queue; + struct bio_queue_head bio_queue; int queue_count; struct devstat device_stats; int blk_gran; @@ -661,17 +661,18 @@ saclose(dev_t dev, int flag, int fmt, struct thread *td) * only one physical transfer. */ static void -sastrategy(struct buf *bp) +sastrategy(dev_t dev, struct bio *bio) { + struct buf *bp = bio->bio_buf; struct cam_periph *periph; struct sa_softc *softc; u_int unit; - if (SA_IS_CTRL(bp->b_dev)) { + if (SA_IS_CTRL(dev)) { bp->b_error = EINVAL; goto bad; } - unit = SAUNIT(bp->b_dev); + unit = SAUNIT(dev); periph = cam_extend_get(saperiphs, unit); if (periph == NULL) { bp->b_error = ENXIO; @@ -744,7 +745,7 @@ sastrategy(struct buf *bp) /* * Place it at the end of the queue. */ - bufq_insert_tail(&softc->buf_queue, bp); + bioq_insert_tail(&softc->bio_queue, bio); softc->queue_count++; CAM_DEBUG(periph->path, CAM_DEBUG_INFO, ("sastrategy: enqueuing a %d " @@ -768,7 +769,7 @@ done: * Correctly set the buf to indicate a completed xfer */ bp->b_resid = bp->b_bcount; - biodone(bp); + biodone(bio); } static int @@ -1307,6 +1308,7 @@ saoninvalidate(struct cam_periph *periph) { struct sa_softc *softc; struct buf *q_bp; + struct bio *q_bio; struct ccb_setasync csa; softc = (struct sa_softc *)periph->softc; @@ -1335,12 +1337,13 @@ saoninvalidate(struct cam_periph *periph) * XXX Handle any transactions queued to the card * with XPT_ABORT_CCB. */ - while ((q_bp = bufq_first(&softc->buf_queue)) != NULL){ - bufq_remove(&softc->buf_queue, q_bp); + while ((q_bio = bioq_first(&softc->bio_queue)) != NULL){ + bioq_remove(&softc->bio_queue, q_bio); + q_bp = q_bio->bio_buf; q_bp->b_resid = q_bp->b_bcount; q_bp->b_error = ENXIO; q_bp->b_flags |= B_ERROR; - biodone(q_bp); + biodone(q_bio); } softc->queue_count = 0; crit_exit(); @@ -1434,7 +1437,7 @@ saregister(struct cam_periph *periph, void *arg) softc->fileno = (daddr_t) -1; softc->blkno = (daddr_t) -1; - bufq_init(&softc->buf_queue); + bioq_init(&softc->bio_queue); periph->softc = softc; cam_extend_set(saperiphs, periph->unit_number, periph); @@ -1534,12 +1537,13 @@ sastart(struct cam_periph *periph, union ccb *start_ccb) { /* Pull a buffer from the queue and get going on it */ struct buf *bp; + struct bio *bio; /* * See if there is a buf with work for us to do.. */ crit_enter(); - bp = bufq_first(&softc->buf_queue); + bio = bioq_first(&softc->bio_queue); if (periph->immediate_priority <= periph->pinfo.priority) { CAM_DEBUG_PRINT(CAM_DEBUG_SUBTRACE, ("queuing for immediate ccb\n")); @@ -1549,16 +1553,17 @@ sastart(struct cam_periph *periph, union ccb *start_ccb) periph->immediate_priority = CAM_PRIORITY_NONE; crit_exit(); wakeup(&periph->ccb_list); - } else if (bp == NULL) { + } else if (bio == NULL) { crit_exit(); xpt_release_ccb(start_ccb); } else if ((softc->flags & SA_FLAG_ERR_PENDING) != 0) { - struct buf *done_bp; + struct bio *done_bio; again: softc->queue_count--; - bufq_remove(&softc->buf_queue, bp); + bioq_remove(&softc->bio_queue, bio); + bp = bio->bio_buf; bp->b_resid = bp->b_bcount; - done_bp = bp; + done_bio = bio; if ((softc->flags & SA_FLAG_EOM_PENDING) != 0) { /* * We now just clear errors in this case @@ -1573,33 +1578,34 @@ again: * same way. */ bp->b_error = 0; - if (bufq_first(&softc->buf_queue) != NULL) { - biodone(done_bp); + if (bioq_first(&softc->bio_queue) != NULL) { + biodone(done_bio); goto again; } } else if ((softc->flags & SA_FLAG_EIO_PENDING) != 0) { bp->b_error = EIO; bp->b_flags |= B_ERROR; } - bp = bufq_first(&softc->buf_queue); + bio = bioq_first(&softc->bio_queue); /* * Only if we have no other buffers queued up * do we clear the pending error flag. */ - if (bp == NULL) + if (bio == NULL) softc->flags &= ~SA_FLAG_ERR_PENDING; CAM_DEBUG(periph->path, CAM_DEBUG_INFO, - ("sastart- ERR_PENDING now 0x%x, bp is %sNULL, " + ("sastart- ERR_PENDING now 0x%x, bio is %sNULL, " "%d more buffers queued up\n", (softc->flags & SA_FLAG_ERR_PENDING), - (bp != NULL)? "not " : " ", softc->queue_count)); + (bio != NULL)? "not " : " ", softc->queue_count)); crit_exit(); xpt_release_ccb(start_ccb); - biodone(done_bp); + biodone(done_bio); } else { u_int32_t length; - bufq_remove(&softc->buf_queue, bp); + bioq_remove(&softc->bio_queue, bio); + bp = bio->bio_buf; softc->queue_count--; if ((softc->flags & SA_FLAG_FIXED) != 0) { @@ -1615,7 +1621,7 @@ again: printf("zero blocksize for " "FIXED length writes?\n"); crit_exit(); - biodone(bp); + biodone(bio); break; } CAM_DEBUG(periph->path, CAM_DEBUG_INFO, @@ -1655,13 +1661,13 @@ again: IO_TIMEOUT); start_ccb->ccb_h.ccb_pflags &= ~SA_POSITION_UPDATED; Set_CCB_Type(start_ccb, SA_CCB_BUFFER_IO); - start_ccb->ccb_h.ccb_bp = bp; - bp = bufq_first(&softc->buf_queue); + start_ccb->ccb_h.ccb_bio = bio; + bio = bioq_first(&softc->bio_queue); crit_exit(); xpt_action(start_ccb); } - if (bp != NULL) { + if (bio != NULL) { /* Have more work to do, so ensure we stay scheduled */ xpt_schedule(periph, 1); } @@ -1687,10 +1693,12 @@ sadone(struct cam_periph *periph, union ccb *done_ccb) case SA_CCB_BUFFER_IO: { struct buf *bp; + struct bio *bio; int error; softc->dsreg = MTIO_DSREG_REST; - bp = (struct buf *)done_ccb->ccb_h.ccb_bp; + bio = (struct bio *)done_ccb->ccb_h.ccb_bio; + bp = bio->bio_buf; error = 0; if ((done_ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) { if ((error = saerror(done_ccb, 0, 0)) == ERESTART) { @@ -1703,6 +1711,7 @@ sadone(struct cam_periph *periph, union ccb *done_ccb) if (error == EIO) { struct buf *q_bp; + struct bio *q_bio; /* * Catastrophic error. Mark the tape as frozen @@ -1717,12 +1726,13 @@ sadone(struct cam_periph *periph, union ccb *done_ccb) crit_enter(); softc->flags |= SA_FLAG_TAPE_FROZEN; - while ((q_bp = bufq_first(&softc->buf_queue)) != NULL) { - bufq_remove(&softc->buf_queue, q_bp); + while ((q_bio = bioq_first(&softc->bio_queue)) != NULL) { + bioq_remove(&softc->bio_queue, q_bio); + q_bp = q_bio->bio_buf; q_bp->b_resid = q_bp->b_bcount; q_bp->b_error = EIO; q_bp->b_flags |= B_ERROR; - biodone(q_bp); + biodone(q_bio); } crit_exit(); } @@ -1774,7 +1784,7 @@ sadone(struct cam_periph *periph, union ccb *done_ccb) } #endif devstat_end_transaction_buf(&softc->device_stats, bp); - biodone(bp); + biodone(bio); break; } case SA_CCB_WAITING: diff --git a/sys/bus/cam/scsi/scsi_ses.c b/sys/bus/cam/scsi/scsi_ses.c index c249bae508..7fa821a0b0 100644 --- a/sys/bus/cam/scsi/scsi_ses.c +++ b/sys/bus/cam/scsi/scsi_ses.c @@ -1,5 +1,5 @@ /* $FreeBSD: src/sys/cam/scsi/scsi_ses.c,v 1.8.2.2 2000/08/08 23:19:21 mjacob Exp $ */ -/* $DragonFly: src/sys/bus/cam/scsi/scsi_ses.c,v 1.13 2006/01/22 14:03:51 swildner Exp $ */ +/* $DragonFly: src/sys/bus/cam/scsi/scsi_ses.c,v 1.14 2006/02/17 19:17:42 dillon Exp $ */ /* * Copyright (c) 2000 Matthew Jacob * All rights reserved. @@ -139,7 +139,7 @@ static void ses_log(struct ses_softc *, const char *, ...); #define ccb_state ppriv_field0 -#define ccb_bp ppriv_ptr1 +#define ccb_bio ppriv_ptr1 struct ses_softc { enctyp ses_type; /* type of enclosure */ diff --git a/sys/bus/firewire/firewirereg.h b/sys/bus/firewire/firewirereg.h index 73f3a57998..3d64bdc182 100644 --- a/sys/bus/firewire/firewirereg.h +++ b/sys/bus/firewire/firewirereg.h @@ -32,7 +32,7 @@ * POSSIBILITY OF SUCH DAMAGE. * * $FreeBSD: src/sys/dev/firewire/firewirereg.h,v 1.33 2004/01/06 14:30:46 simokawa Exp $ - * $DragonFly: src/sys/bus/firewire/firewirereg.h,v 1.8 2005/06/02 20:40:33 dillon Exp $ + * $DragonFly: src/sys/bus/firewire/firewirereg.h,v 1.9 2006/02/17 19:17:44 dillon Exp $ * */ @@ -317,21 +317,7 @@ extern devclass_t firewire_devclass; #define CALLOUT_INIT(x) callout_init(x, 0 /* mpsafe */) #endif -#if defined(__DragonFly__) || __FreeBSD_version < 500000 -/* compatibility shim for 4.X */ -#define bio buf -#define bio_bcount b_bcount -#define bio_cmd b_flags -#define bio_count b_count -#define bio_data b_data -#define bio_dev b_dev -#define bio_error b_error -#define bio_flags b_flags -#define bio_offset b_offset -#define bio_resid b_resid -#define BIO_ERROR B_ERROR -#define BIO_READ B_READ -#define BIO_WRITE B_WRITE +#if defined(__DragonFly__) #define MIN(a,b) (((a)<(b))?(a):(b)) #define MAX(a,b) (((a)>(b))?(a):(b)) #endif diff --git a/sys/bus/firewire/fwdev.c b/sys/bus/firewire/fwdev.c index 4055688998..93290e37aa 100644 --- a/sys/bus/firewire/fwdev.c +++ b/sys/bus/firewire/fwdev.c @@ -32,7 +32,7 @@ * POSSIBILITY OF SUCH DAMAGE. * * $FreeBSD: src/sys/dev/firewire/fwdev.c,v 1.36 2004/01/22 14:41:17 simokawa Exp $ - * $DragonFly: src/sys/bus/firewire/fwdev.c,v 1.10 2005/06/02 20:40:33 dillon Exp $ + * $DragonFly: src/sys/bus/firewire/fwdev.c,v 1.11 2006/02/17 19:17:44 dillon Exp $ * */ @@ -771,20 +771,18 @@ fw_mmap (dev_t dev, vm_offset_t offset, vm_paddr_t *paddr, int nproto) } static void -fw_strategy(struct bio *bp) +fw_strategy(dev_t dev, struct bio *bio) { - dev_t dev; + struct buf *bp = bio->bio_buf; - dev = bp->bio_dev; if (DEV_FWMEM(dev)) { - fwmem_strategy(bp); + fwmem_strategy(dev, bio); return; } - - bp->bio_error = EOPNOTSUPP; - bp->bio_flags |= BIO_ERROR; - bp->bio_resid = bp->bio_bcount; - biodone(bp); + bp->b_error = EOPNOTSUPP; + bp->b_flags |= B_ERROR; + bp->b_resid = bp->b_bcount; + biodone(bio); } int diff --git a/sys/bus/firewire/fwmem.c b/sys/bus/firewire/fwmem.c index 331c91d9dc..3d632d0ccc 100644 --- a/sys/bus/firewire/fwmem.c +++ b/sys/bus/firewire/fwmem.c @@ -31,7 +31,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $DragonFly: src/sys/bus/firewire/fwmem.c,v 1.7 2005/06/02 20:40:33 dillon Exp $ + * $DragonFly: src/sys/bus/firewire/fwmem.c,v 1.8 2006/02/17 19:17:44 dillon Exp $ */ #ifndef __DragonFly__ @@ -322,33 +322,33 @@ fwmem_close (dev_t dev, int flags, int fmt, fw_proc *td) static void fwmem_biodone(struct fw_xfer *xfer) { - struct bio *bp; + struct bio *bio; + struct buf *bp; - bp = (struct bio *)xfer->sc; - bp->bio_error = xfer->resp; + bio = (struct bio *)xfer->sc; + bp = bio->bio_buf; + bp->b_error = xfer->resp; - if (bp->bio_error != 0) { + if (bp->b_error != 0) { if (fwmem_debug) - printf("%s: err=%d\n", __func__, bp->bio_error); - bp->bio_flags |= BIO_ERROR; - bp->bio_resid = bp->bio_bcount; + printf("%s: err=%d\n", __func__, bp->b_error); + bp->b_flags |= B_ERROR; + bp->b_resid = bp->b_bcount; } - fw_xfer_free(xfer); - biodone(bp); + biodone(bio); } void -fwmem_strategy(struct bio *bp) +fwmem_strategy(dev_t dev, struct bio *bio) { + struct buf *bp = bio->bio_buf; struct firewire_softc *sc; struct fwmem_softc *fms; struct fw_device *fwdev; struct fw_xfer *xfer; - dev_t dev; int unit, err=0, iolen; - dev = bp->bio_dev; /* XXX check request length */ unit = DEV2UNIT(dev); @@ -364,46 +364,51 @@ fwmem_strategy(struct bio *bp) err = EINVAL; goto error; } + if (bio->bio_offset == NOOFFSET) { + printf("fwmem: offset was not set bp %p\n", bp); + err = EINVAL; + goto error; + } - iolen = MIN(bp->bio_bcount, MAXLEN); - if ((bp->bio_cmd & BIO_READ) == BIO_READ) { - if (iolen == 4 && (bp->bio_offset & 3) == 0) + iolen = MIN(bp->b_bcount, MAXLEN); + if (bp->b_flags & B_READ) { + if (iolen == 4 && (bio->bio_offset & 3) == 0) xfer = fwmem_read_quad(fwdev, - (void *) bp, fwmem_speed, - bp->bio_offset >> 32, bp->bio_offset & 0xffffffff, - bp->bio_data, fwmem_biodone); + (void *) bio, fwmem_speed, + bio->bio_offset >> 32, bio->bio_offset & 0xffffffff, + bp->b_data, fwmem_biodone); else xfer = fwmem_read_block(fwdev, - (void *) bp, fwmem_speed, - bp->bio_offset >> 32, bp->bio_offset & 0xffffffff, - iolen, bp->bio_data, fwmem_biodone); + (void *) bio, fwmem_speed, + bio->bio_offset >> 32, bio->bio_offset & 0xffffffff, + iolen, bp->b_data, fwmem_biodone); } else { - if (iolen == 4 && (bp->bio_offset & 3) == 0) + if (iolen == 4 && (bio->bio_offset & 3) == 0) xfer = fwmem_write_quad(fwdev, - (void *)bp, fwmem_speed, - bp->bio_offset >> 32, bp->bio_offset & 0xffffffff, - bp->bio_data, fwmem_biodone); + (void *)bio, fwmem_speed, + bio->bio_offset >> 32, bio->bio_offset & 0xffffffff, + bp->b_data, fwmem_biodone); else xfer = fwmem_write_block(fwdev, - (void *)bp, fwmem_speed, - bp->bio_offset >> 32, bp->bio_offset & 0xffffffff, - iolen, bp->bio_data, fwmem_biodone); + (void *)bio, fwmem_speed, + bio->bio_offset >> 32, bio->bio_offset & 0xffffffff, + iolen, bp->b_data, fwmem_biodone); } if (xfer == NULL) { err = EIO; goto error; } /* XXX */ - bp->bio_resid = bp->bio_bcount - iolen; + bp->b_resid = bp->b_bcount - iolen; error: crit_exit(); if (err != 0) { if (fwmem_debug) printf("%s: err=%d\n", __func__, err); - bp->bio_error = err; - bp->bio_flags |= BIO_ERROR; - bp->bio_resid = bp->bio_bcount; - biodone(bp); + bp->b_error = err; + bp->b_flags |= B_ERROR; + bp->b_resid = bp->b_bcount; + biodone(bio); } } diff --git a/sys/contrib/dev/fla/fla.c b/sys/contrib/dev/fla/fla.c index fe488a396b..2a59d8d8a3 100644 --- a/sys/contrib/dev/fla/fla.c +++ b/sys/contrib/dev/fla/fla.c @@ -7,7 +7,7 @@ * ---------------------------------------------------------------------------- * * $FreeBSD: src/sys/contrib/dev/fla/fla.c,v 1.16 1999/12/08 04:45:16 ken Exp $ - * $DragonFly: src/sys/contrib/dev/fla/Attic/fla.c,v 1.9 2005/06/09 20:47:37 swildner Exp $ + * $DragonFly: src/sys/contrib/dev/fla/Attic/fla.c,v 1.10 2006/02/17 19:17:52 dillon Exp $ * */ @@ -122,7 +122,7 @@ static struct fla_s { int unit; unsigned nsect; struct doc2k_stat ds; - struct buf_queue_head buf_queue; + struct bio_queue_head bio_queue; struct devstat stats; struct disk disk; dev_t dev; @@ -190,41 +190,42 @@ flaioctl(dev_t dev, u_long cmd, caddr_t addr, int flags, struct thread *td) } static void -flastrategy(struct buf *bp) +flastrategy(dev_t dev, struct bio *bio) { + struct buf *bp = bio->bio_buf; int unit, error; struct fla_s *sc; enum doc2k_work what; - if (fla_debug > 1) + if (fla_debug > 1) { printf("flastrategy(%p) %s %lx, %d, %ld, %p)\n", - bp, devtoname(bp->b_dev), bp->b_flags, bp->b_blkno, + bp, devtoname(dev), bp->b_flags, bio->bio_blkno, bp->b_bcount / DEV_BSIZE, bp->b_data); + } - sc = bp->b_dev->si_drv1; - + sc = dev->si_drv1; + bio->bio_driver_info = dev; crit_enter(); - - bufqdisksort(&sc->buf_queue, bp); - + bioqdisksort(&sc->bio_queue, bio); if (sc->busy) { crit_exit(); return; } - sc->busy++; while (1) { - bp = bufq_first(&sc->buf_queue); - if (bp) - bufq_remove(&sc->buf_queue, bp); - crit_exit(); - if (!bp) + bio = bioq_first(&sc->bio_queue); + if (bio == NULL) { + crit_exit(); break; + } + bioq_remove(&sc->bio_queue, bio); + bp = bio->bio_buf; + dev = bio->bio_driver_info; devstat_start_transaction(&sc->stats); bp->b_resid = bp->b_bcount; - unit = dkunit(bp->b_dev); + unit = dkunit(dev); if (bp->b_flags & B_FREEBUF) what = DOC2K_ERASE; @@ -235,14 +236,14 @@ flastrategy(struct buf *bp) LEAVE(); - error = doc2k_rwe( unit, what, bp->b_pblkno, - bp->b_bcount / DEV_BSIZE, bp->b_data); + error = doc2k_rwe(unit, what, bio->bio_blkno, + bp->b_bcount / DEV_BSIZE, bp->b_data); ENTER(); if (fla_debug > 1 || error) { printf("fla%d: %d = rwe(%p, %d, %d, %d, %ld, %p)\n", - unit, error, bp, unit, what, bp->b_pblkno, + unit, error, bp, unit, what, bio->bio_blkno, bp->b_bcount / DEV_BSIZE, bp->b_data); } if (error) { @@ -252,7 +253,7 @@ flastrategy(struct buf *bp) bp->b_resid = 0; } devstat_end_transaction_buf(&sc->stats, bp); - biodone(bp); + biodone(bio); crit_enter(); } @@ -327,7 +328,7 @@ flaattach (device_t dev) unit, sc->ds.type, sc->ds.unitSize, sc->ds.mediaSize, sc->ds.chipSize, sc->ds.interleaving, sc->ds.window); - bufq_init(&sc->buf_queue); + bioq_init(&sc->bio_queue); devstat_add_entry(&softc[unit].stats, "fla", unit, DEV_BSIZE, DEVSTAT_NO_ORDERED_TAGS, diff --git a/sys/dev/disk/ata/ata-disk.c b/sys/dev/disk/ata/ata-disk.c index 082985de78..81a2348680 100644 --- a/sys/dev/disk/ata/ata-disk.c +++ b/sys/dev/disk/ata/ata-disk.c @@ -26,7 +26,7 @@ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * $FreeBSD: src/sys/dev/ata/ata-disk.c,v 1.60.2.24 2003/01/30 07:19:59 sos Exp $ - * $DragonFly: src/sys/dev/disk/ata/ata-disk.c,v 1.25 2005/08/26 14:26:45 hmp Exp $ + * $DragonFly: src/sys/dev/disk/ata/ata-disk.c,v 1.26 2006/02/17 19:17:54 dillon Exp $ */ #include "opt_ata.h" @@ -131,7 +131,7 @@ ad_attach(struct ata_device *atadev, int alreadylocked) adp->heads = atadev->param->heads; adp->sectors = atadev->param->sectors; adp->total_secs = atadev->param->cylinders * adp->heads * adp->sectors; - bufq_init(&adp->queue); + bioq_init(&adp->bio_queue); /* does this device need oldstyle CHS addressing */ if (!ad_version(atadev->param->version_major) || @@ -237,6 +237,7 @@ ad_detach(struct ata_device *atadev, int flush) /* get rid of flush XXX SOS */ { struct ad_softc *adp = atadev->driver; struct ad_request *request; + struct bio *bio; struct buf *bp; atadev->flags |= ATA_D_DETACHING; @@ -246,17 +247,18 @@ ad_detach(struct ata_device *atadev, int flush) /* get rid of flush XXX SOS */ if (request->softc != adp) continue; TAILQ_REMOVE(&atadev->channel->ata_queue, request, chain); - request->bp->b_error = ENXIO; - request->bp->b_flags |= B_ERROR; - biodone(request->bp); + request->bio->bio_buf->b_error = ENXIO; + request->bio->bio_buf->b_flags |= B_ERROR; + biodone(request->bio); ad_free(request); } ata_dmafree(atadev); - while ((bp = bufq_first(&adp->queue))) { - bufq_remove(&adp->queue, bp); + while ((bio = bioq_first(&adp->bio_queue))) { + bioq_remove(&adp->bio_queue, bio); + bp = bio->bio_buf; bp->b_error = ENXIO; bp->b_flags |= B_ERROR; - biodone(bp); + biodone(bio); } disk_invalidate(&adp->disk); devstat_remove_entry(&adp->stats); @@ -303,18 +305,20 @@ adclose(dev_t dev, int flags, int fmt, struct thread *td) * may have been translated through several layers. */ static void -adstrategy(struct buf *bp) +adstrategy(dev_t dev, struct bio *bio) { - struct ad_softc *adp = bp->b_dev->si_drv1; + struct buf *bp = bio->bio_buf; + struct ad_softc *adp = dev->si_drv1; if (adp->device->flags & ATA_D_DETACHING) { bp->b_error = ENXIO; bp->b_flags |= B_ERROR; - biodone(bp); + biodone(bio); return; } + bio->bio_driver_info = dev; crit_enter(); - bufqdisksort(&adp->queue, bp); + bioqdisksort(&adp->bio_queue, bio); crit_exit(); ata_start(adp->device->channel); } @@ -390,12 +394,14 @@ void ad_start(struct ata_device *atadev) { struct ad_softc *adp = atadev->driver; - struct buf *bp = bufq_first(&adp->queue); + struct bio *bio = bioq_first(&adp->bio_queue); + struct buf *bp; struct ad_request *request; int tag = 0; - if (!bp) + if (bio == NULL) return; + bp = bio->bio_buf; /* if tagged queueing enabled get next free tag */ if (adp->flags & AD_F_TAG_ENABLED) { @@ -418,8 +424,8 @@ ad_start(struct ata_device *atadev) /* setup request */ request->softc = adp; - request->bp = bp; - request->blockaddr = bp->b_pblkno; + request->bio = bio; + request->blockaddr = bio->bio_blkno; request->bytecount = bp->b_bcount; request->data = bp->b_data; request->tag = tag; @@ -439,7 +445,7 @@ ad_start(struct ata_device *atadev) adp->tags[tag] = request; /* remove from drive queue */ - bufq_remove(&adp->queue, bp); + bioq_remove(&adp->bio_queue, bio); /* link onto controller queue */ TAILQ_INSERT_TAIL(&atadev->channel->ata_queue, request, chain); @@ -611,11 +617,11 @@ transfer_failed: ad_requeue(adp->device->channel, request); else { /* retries all used up, return error */ - request->bp->b_error = EIO; - request->bp->b_flags |= B_ERROR; - request->bp->b_resid = request->bytecount; - devstat_end_transaction_buf(&adp->stats, request->bp); - biodone(request->bp); + request->bio->bio_buf->b_error = EIO; + request->bio->bio_buf->b_flags |= B_ERROR; + request->bio->bio_buf->b_resid = request->bytecount; + devstat_end_transaction_buf(&adp->stats, request->bio->bio_buf); + biodone(request->bio); ad_free(request); } ata_reinit(adp->device->channel); @@ -627,14 +633,16 @@ ad_interrupt(struct ad_request *request) { struct ad_softc *adp = request->softc; int dma_stat = 0; + dev_t dev; /* finish DMA transfer */ if (request->flags & ADR_F_DMA_USED) dma_stat = ata_dmadone(adp->device); + dev = request->bio->bio_driver_info; /* do we have a corrected soft error ? */ if (adp->device->channel->status & ATA_S_CORR) - diskerr(request->bp, request->bp->b_dev, + diskerr(request->bio, dev, "soft error (ECC corrected)", LOG_PRINTF, request->blockaddr + (request->donecount / DEV_BSIZE), &adp->disk.d_label); @@ -644,7 +652,7 @@ ad_interrupt(struct ad_request *request) (request->flags & ADR_F_DMA_USED && dma_stat & ATA_BMSTAT_ERROR)) { adp->device->channel->error = ATA_INB(adp->device->channel->r_io, ATA_ERROR); - diskerr(request->bp, request->bp->b_dev, + diskerr(request->bio, dev, (adp->device->channel->error & ATA_E_ICRC) ? "UDMA ICRC error" : "hard error", LOG_PRINTF, request->blockaddr + (request->donecount / DEV_BSIZE), @@ -713,8 +721,8 @@ ad_interrupt(struct ad_request *request) /* finish up transfer */ if (request->flags & ADR_F_ERROR) { - request->bp->b_error = EIO; - request->bp->b_flags |= B_ERROR; + request->bio->bio_buf->b_error = EIO; + request->bio->bio_buf->b_flags |= B_ERROR; } else { request->bytecount -= request->currentsize; @@ -728,10 +736,10 @@ ad_interrupt(struct ad_request *request) /* disarm timeout for this transfer */ callout_stop(&request->callout); - request->bp->b_resid = request->bytecount; + request->bio->bio_buf->b_resid = request->bytecount; - devstat_end_transaction_buf(&adp->stats, request->bp); - biodone(request->bp); + devstat_end_transaction_buf(&adp->stats, request->bio->bio_buf); + biodone(request->bio); ad_free(request); adp->outstanding--; @@ -924,10 +932,10 @@ ad_timeout(struct ad_request *request) } else { /* retries all used up, return error */ - request->bp->b_error = EIO; - request->bp->b_flags |= B_ERROR; - devstat_end_transaction_buf(&adp->stats, request->bp); - biodone(request->bp); + request->bio->bio_buf->b_error = EIO; + request->bio->bio_buf->b_flags |= B_ERROR; + devstat_end_transaction_buf(&adp->stats, request->bio->bio_buf); + biodone(request->bio); ad_free(request); } ata_reinit(adp->device->channel); diff --git a/sys/dev/disk/ata/ata-disk.h b/sys/dev/disk/ata/ata-disk.h index 56a6346966..499f0aed25 100644 --- a/sys/dev/disk/ata/ata-disk.h +++ b/sys/dev/disk/ata/ata-disk.h @@ -26,7 +26,7 @@ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * $FreeBSD: src/sys/dev/ata/ata-disk.h,v 1.22.2.7 2002/03/18 08:37:33 sos Exp $ - * $DragonFly: src/sys/dev/disk/ata/ata-disk.h,v 1.5 2004/09/18 18:33:38 dillon Exp $ + * $DragonFly: src/sys/dev/disk/ata/ata-disk.h,v 1.6 2006/02/17 19:17:54 dillon Exp $ */ /* structure describing an ATA disk request */ @@ -46,7 +46,7 @@ struct ad_request { #define ADR_F_FORCE_PIO 0x0010 caddr_t data; /* pointer to data buf */ - struct buf *bp; /* associated bio ptr */ + struct bio *bio; /* associated bio ptr */ u_int8_t tag; /* tag ID of this request */ int serv; /* request had service */ TAILQ_ENTRY(ad_request) chain; /* list management */ @@ -70,7 +70,7 @@ struct ad_softc { struct ad_request *tags[32]; /* tag array of requests */ int outstanding; /* tags not serviced yet */ - struct buf_queue_head queue; /* head of request queue */ + struct bio_queue_head bio_queue; /* head of request queue */ struct devstat stats; /* devstat entry */ struct disk disk; /* disklabel/slice stuff */ dev_t dev; /* device place holder */ diff --git a/sys/dev/disk/ata/ata-raid.c b/sys/dev/disk/ata/ata-raid.c index e404bba455..84dc08b6f1 100644 --- a/sys/dev/disk/ata/ata-raid.c +++ b/sys/dev/disk/ata/ata-raid.c @@ -26,7 +26,7 @@ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * $FreeBSD: src/sys/dev/ata/ata-raid.c,v 1.3.2.19 2003/01/30 07:19:59 sos Exp $ - * $DragonFly: src/sys/dev/disk/ata/ata-raid.c,v 1.14 2005/08/03 16:36:33 hmp Exp $ + * $DragonFly: src/sys/dev/disk/ata/ata-raid.c,v 1.15 2006/02/17 19:17:54 dillon Exp $ */ #include "opt_ata.h" @@ -75,7 +75,7 @@ static struct cdevsw ar_cdevsw = { /* prototypes */ static void ar_attach_raid(struct ar_softc *, int); -static void ar_done(struct buf *); +static void ar_done(struct bio *); static void ar_config_changed(struct ar_softc *, int); static int ar_rebuild(struct ar_softc *); static int ar_highpoint_read_conf(struct ad_softc *, struct ar_softc **); @@ -480,9 +480,10 @@ aropen(dev_t dev, int flags, int fmt, struct thread *td) } static void -arstrategy(struct buf *bp) +arstrategy(dev_t dev, struct bio *bio) { - struct ar_softc *rdp = bp->b_dev->si_drv1; + struct buf *bp = bio->bio_buf; + struct ar_softc *rdp = dev->si_drv1; int blkno, count, chunk, lba, lbs, tmplba; int drv = 0, change = 0; caddr_t data; @@ -490,12 +491,12 @@ arstrategy(struct buf *bp) if (!(rdp->flags & AR_F_READY)) { bp->b_flags |= B_ERROR; bp->b_error = EIO; - biodone(bp); + biodone(bio); return; } bp->b_resid = bp->b_bcount; - blkno = bp->b_pblkno; + blkno = bio->bio_blkno; data = bp->b_data; for (count = howmany(bp->b_bcount, DEV_BSIZE); count > 0; count -= chunk, blkno += chunk, data += (chunk * DEV_BSIZE)) { @@ -537,22 +538,23 @@ arstrategy(struct buf *bp) printf("ar%d: unknown array type in arstrategy\n", rdp->lun); bp->b_flags |= B_ERROR; bp->b_error = EIO; - biodone(bp); + biodone(bio); return; } buf1 = malloc(sizeof(struct ar_buf), M_AR, M_INTWAIT | M_ZERO); BUF_LOCKINIT(&buf1->bp); BUF_LOCK(&buf1->bp, LK_EXCLUSIVE); - buf1->bp.b_pblkno = lba; + initbufbio(&buf1->bp); + buf1->bp.b_bio1.bio_blkno = lba; if ((buf1->drive = drv) > 0) - buf1->bp.b_pblkno += rdp->offset; - buf1->bp.b_caller1 = (void *)rdp; + buf1->bp.b_bio1.bio_blkno += rdp->offset; + buf1->bp.b_bio1.bio_caller_info1.ptr = (void *)rdp; buf1->bp.b_bcount = chunk * DEV_BSIZE; buf1->bp.b_data = data; buf1->bp.b_flags = bp->b_flags; - buf1->bp.b_iodone = ar_done; - buf1->org = bp; + buf1->bp.b_bio1.bio_done = ar_done; + buf1->org = bio; switch (rdp->flags & (AR_F_RAID0 | AR_F_RAID1 | AR_F_SPAN)) { case AR_F_SPAN: @@ -565,20 +567,20 @@ arstrategy(struct buf *bp) free(buf1, M_AR); bp->b_flags |= B_ERROR; bp->b_error = EIO; - biodone(bp); + biodone(bio); return; } - buf1->bp.b_dev = AD_SOFTC(rdp->disks[buf1->drive])->dev; - AR_STRATEGY((struct buf *)buf1); + dev_dstrategy(AD_SOFTC(rdp->disks[buf1->drive])->dev, + &buf1->bp.b_bio1); break; case AR_F_RAID1: case AR_F_RAID0 | AR_F_RAID1: if ((rdp->flags & AR_F_REBUILDING) && !(bp->b_flags & B_READ)) { - if ((bp->b_pblkno >= rdp->lock_start && - bp->b_pblkno < rdp->lock_end) || - ((bp->b_pblkno + chunk) > rdp->lock_start && - (bp->b_pblkno + chunk) <= rdp->lock_end)) { + if ((bio->bio_blkno >= rdp->lock_start && + bio->bio_blkno < rdp->lock_end) || + ((bio->bio_blkno + chunk) > rdp->lock_start && + (bio->bio_blkno + chunk) <= rdp->lock_end)) { tsleep(rdp, 0, "arwait", 0); } } @@ -601,13 +603,13 @@ arstrategy(struct buf *bp) free(buf1, M_AR); bp->b_flags |= B_ERROR; bp->b_error = EIO; - biodone(bp); + biodone(bio); return; } if (bp->b_flags & B_READ) { - if ((buf1->bp.b_pblkno < + if ((buf1->bp.b_bio1.bio_blkno < (rdp->disks[buf1->drive].last_lba - AR_PROXIMITY) || - buf1->bp.b_pblkno > + buf1->bp.b_bio1.bio_blkno > (rdp->disks[buf1->drive].last_lba + AR_PROXIMITY) || !(rdp->disks[buf1->drive].flags & AR_DF_ONLINE)) && (rdp->disks[buf1->drive+rdp->width].flags & AR_DF_ONLINE)) @@ -617,30 +619,31 @@ arstrategy(struct buf *bp) if ((rdp->disks[buf1->drive+rdp->width].flags & AR_DF_ONLINE) || ((rdp->flags & AR_F_REBUILDING) && (rdp->disks[buf1->drive+rdp->width].flags & AR_DF_SPARE) && - buf1->bp.b_pblkno < rdp->lock_start)) { + buf1->bp.b_bio1.bio_blkno < rdp->lock_start)) { if ((rdp->disks[buf1->drive].flags & AR_DF_ONLINE) || ((rdp->flags & AR_F_REBUILDING) && (rdp->disks[buf1->drive].flags & AR_DF_SPARE) && - buf1->bp.b_pblkno < rdp->lock_start)) { + buf1->bp.b_bio1.bio_blkno < rdp->lock_start)) { buf2 = malloc(sizeof(struct ar_buf), M_AR, M_INTWAIT); bcopy(buf1, buf2, sizeof(struct ar_buf)); BUF_LOCKINIT(&buf2->bp); BUF_LOCK(&buf2->bp, LK_EXCLUSIVE); + initbufbio(&buf2->bp); buf1->mirror = buf2; buf2->mirror = buf1; buf2->drive = buf1->drive + rdp->width; - buf2->bp.b_dev = AD_SOFTC(rdp->disks[buf2->drive])->dev; - AR_STRATEGY((struct buf *)buf2); + dev_dstrategy(AD_SOFTC(rdp->disks[buf2->drive])->dev, + &buf2->bp.b_bio1); rdp->disks[buf2->drive].last_lba = - buf2->bp.b_pblkno + chunk; + buf2->bp.b_bio1.bio_blkno + chunk; } else buf1->drive = buf1->drive + rdp->width; } } - buf1->bp.b_dev = AD_SOFTC(rdp->disks[buf1->drive])->dev; - AR_STRATEGY((struct buf *)buf1); - rdp->disks[buf1->drive].last_lba = buf1->bp.b_pblkno + chunk; + dev_dstrategy(AD_SOFTC(rdp->disks[buf1->drive])->dev, + &buf1->bp.b_bio1); + rdp->disks[buf1->drive].last_lba = buf1->bp.b_bio1.bio_blkno + chunk; break; default: @@ -650,10 +653,10 @@ arstrategy(struct buf *bp) } static void -ar_done(struct buf *bp) +ar_done(struct bio *bio) { - struct ar_softc *rdp = (struct ar_softc *)bp->b_caller1; - struct ar_buf *buf = (struct ar_buf *)bp; + struct ar_softc *rdp = (struct ar_softc *)bio->bio_caller_info1.ptr; + struct ar_buf *buf = (struct ar_buf *)bio->bio_buf; switch (rdp->flags & (AR_F_RAID0 | AR_F_RAID1 | AR_F_SPAN)) { case AR_F_SPAN: @@ -661,13 +664,13 @@ ar_done(struct buf *bp) if (buf->bp.b_flags & B_ERROR) { rdp->disks[buf->drive].flags &= ~AR_DF_ONLINE; ar_config_changed(rdp, 1); - buf->org->b_flags |= B_ERROR; - buf->org->b_error = EIO; + buf->org->bio_buf->b_flags |= B_ERROR; + buf->org->bio_buf->b_error = EIO; biodone(buf->org); } else { - buf->org->b_resid -= buf->bp.b_bcount; - if (buf->org->b_resid == 0) + buf->org->bio_buf->b_resid -= buf->bp.b_bcount; + if (buf->org->bio_buf->b_resid == 0) biodone(buf->org); } break; @@ -683,16 +686,16 @@ ar_done(struct buf *bp) buf->drive = buf->drive + rdp->width; else buf->drive = buf->drive - rdp->width; - buf->bp.b_dev = AD_SOFTC(rdp->disks[buf->drive])->dev; - buf->bp.b_flags = buf->org->b_flags; + buf->bp.b_flags = buf->org->bio_buf->b_flags; buf->bp.b_error = 0; - AR_STRATEGY((struct buf *)buf); + dev_dstrategy(AD_SOFTC(rdp->disks[buf->drive])->dev, + &buf->bp.b_bio1); return; } else { if (buf->flags & AB_F_DONE) { - buf->org->b_resid -= buf->bp.b_bcount; - if (buf->org->b_resid == 0) + buf->org->bio_buf->b_resid -= buf->bp.b_bcount; + if (buf->org->bio_buf->b_resid == 0) biodone(buf->org); } else @@ -700,8 +703,8 @@ ar_done(struct buf *bp) } } else { - buf->org->b_flags |= B_ERROR; - buf->org->b_error = EIO; + buf->org->bio_buf->b_flags |= B_ERROR; + buf->org->bio_buf->b_error = EIO; biodone(buf->org); } } @@ -712,8 +715,8 @@ ar_done(struct buf *bp) break; } } - buf->org->b_resid -= buf->bp.b_bcount; - if (buf->org->b_resid == 0) + buf->org->bio_buf->b_resid -= buf->bp.b_bcount; + if (buf->org->bio_buf->b_resid == 0) biodone(buf->org); } break; @@ -1367,8 +1370,10 @@ ar_promise_write_conf(struct ar_softc *rdp) } static void -ar_rw_done(struct buf *bp) +ar_rw_done(struct bio *bio) { + struct buf *bp = bio->bio_buf; + free(bp->b_data, M_AR); free(bp, M_AR); } @@ -1382,24 +1387,24 @@ ar_rw(struct ad_softc *adp, u_int32_t lba, int count, caddr_t data, int flags) bp = malloc(sizeof(struct buf), M_AR, M_INTWAIT|M_ZERO); BUF_LOCKINIT(bp); BUF_LOCK(bp, LK_EXCLUSIVE); - bp->b_dev = adp->dev; + initbufbio(bp); bp->b_data = data; - bp->b_pblkno = lba; + bp->b_bio1.bio_blkno = lba; bp->b_bcount = count; if (flags & AR_WAIT) - bp->b_iodone = (void *)wakeup; + bp->b_bio1.bio_done = (void *)wakeup; else - bp->b_iodone = ar_rw_done; + bp->b_bio1.bio_done = ar_rw_done; if (flags & AR_READ) bp->b_flags |= B_READ; if (flags & AR_WRITE) bp->b_flags |= B_WRITE; - AR_STRATEGY((struct buf *)bp); + dev_dstrategy(adp->dev, &bp->b_bio1); if (flags & AR_WAIT) { while ((retry++ < (15*hz/10)) && (error = !(bp->b_flags & B_DONE))) - error = tsleep(bp, 0, "arrw", 10); + error = tsleep(&bp->b_bio1, 0, "arrw", 10); if (!error && (bp->b_flags & B_ERROR)) error = bp->b_error; free(bp, M_AR); diff --git a/sys/dev/disk/ata/ata-raid.h b/sys/dev/disk/ata/ata-raid.h index cea51e5dba..e8ceaa119a 100644 --- a/sys/dev/disk/ata/ata-raid.h +++ b/sys/dev/disk/ata/ata-raid.h @@ -26,7 +26,7 @@ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * $FreeBSD: src/sys/dev/ata/ata-raid.h,v 1.2.2.8 2002/04/11 09:31:57 sos Exp $ - * $DragonFly: src/sys/dev/disk/ata/ata-raid.h,v 1.4 2004/05/19 22:52:40 dillon Exp $ + * $DragonFly: src/sys/dev/disk/ata/ata-raid.h,v 1.5 2006/02/17 19:17:54 dillon Exp $ */ /* misc defines */ @@ -36,7 +36,6 @@ #define AR_READ 0x01 #define AR_WRITE 0x02 #define AR_WAIT 0x04 -#define AR_STRATEGY(x) dev_dstrategy((x)->b_dev, x) #define AD_SOFTC(x) ((struct ad_softc *)(x.device->driver)) #define ATA_MAGIC "FreeBSD ATA driver RAID " @@ -86,7 +85,7 @@ struct ar_softc { struct ar_buf { struct buf bp; /* must be first element! */ - struct buf *org; + struct bio *org; struct ar_buf *mirror; int drive; int flags; diff --git a/sys/dev/disk/ata/atapi-all.c b/sys/dev/disk/ata/atapi-all.c index 67743ec6ad..1628702964 100644 --- a/sys/dev/disk/ata/atapi-all.c +++ b/sys/dev/disk/ata/atapi-all.c @@ -26,7 +26,7 @@ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * $FreeBSD: src/sys/dev/ata/atapi-all.c,v 1.46.2.18 2002/10/31 23:10:33 thomas Exp $ - * $DragonFly: src/sys/dev/disk/ata/atapi-all.c,v 1.15 2005/06/03 21:56:23 swildner Exp $ + * $DragonFly: src/sys/dev/disk/ata/atapi-all.c,v 1.16 2006/02/17 19:17:54 dillon Exp $ */ #include "opt_ata.h" @@ -158,10 +158,10 @@ atapi_detach(struct ata_device *atadev) continue; TAILQ_REMOVE(&atadev->channel->atapi_queue, request, chain); if (request->driver) { - struct buf *bp = (struct buf *) request->driver; - bp->b_flags |= B_ERROR; - bp->b_error = ENXIO; - biodone(bp); + struct bio *bio = (struct bio *) request->driver; + bio->bio_buf->b_flags |= B_ERROR; + bio->bio_buf->b_error = ENXIO; + biodone(bio); } ata_dmafree(atadev); free(request, M_ATAPI); diff --git a/sys/dev/disk/ata/atapi-cd.c b/sys/dev/disk/ata/atapi-cd.c index ac58611793..40fa8a7d6f 100644 --- a/sys/dev/disk/ata/atapi-cd.c +++ b/sys/dev/disk/ata/atapi-cd.c @@ -26,7 +26,7 @@ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * $FreeBSD: src/sys/dev/ata/atapi-cd.c,v 1.48.2.20 2002/11/25 05:30:31 njl Exp $ - * $DragonFly: src/sys/dev/disk/ata/atapi-cd.c,v 1.19 2005/06/03 21:56:23 swildner Exp $ + * $DragonFly: src/sys/dev/disk/ata/atapi-cd.c,v 1.20 2006/02/17 19:17:54 dillon Exp $ */ #include "opt_ata.h" @@ -190,18 +190,18 @@ acddetach(struct ata_device *atadev) { struct acd_softc *cdp = atadev->driver; struct acd_devlist *entry; - struct buf *bp; + struct bio *bio; int subdev; if (cdp->changer_info) { for (subdev = 0; subdev < cdp->changer_info->slots; subdev++) { if (cdp->driver[subdev] == cdp) continue; - while ((bp = bufq_first(&cdp->driver[subdev]->queue))) { - bufq_remove(&cdp->driver[subdev]->queue, bp); - bp->b_flags |= B_ERROR; - bp->b_error = ENXIO; - biodone(bp); + while ((bio = bioq_first(&cdp->driver[subdev]->bio_queue))) { + bioq_remove(&cdp->driver[subdev]->bio_queue, bio); + bio->bio_buf->b_flags |= B_ERROR; + bio->bio_buf->b_error = ENXIO; + biodone(bio); } release_dev(cdp->driver[subdev]->dev); while ((entry = TAILQ_FIRST(&cdp->driver[subdev]->dev_list))) { @@ -217,10 +217,10 @@ acddetach(struct ata_device *atadev) free(cdp->driver, M_ACD); free(cdp->changer_info, M_ACD); } - while ((bp = bufq_first(&cdp->queue))) { - bp->b_flags |= B_ERROR; - bp->b_error = ENXIO; - biodone(bp); + while ((bio = bioq_first(&cdp->bio_queue))) { + bio->bio_buf->b_flags |= B_ERROR; + bio->bio_buf->b_error = ENXIO; + biodone(bio); } while ((entry = TAILQ_FIRST(&cdp->dev_list))) { release_dev(entry->dev); @@ -244,7 +244,7 @@ acd_init_lun(struct ata_device *atadev) cdp = malloc(sizeof(struct acd_softc), M_ACD, M_WAITOK | M_ZERO); TAILQ_INIT(&cdp->dev_list); - bufq_init(&cdp->queue); + bioq_init(&cdp->bio_queue); cdp->device = atadev; cdp->lun = ata_get_lun(&acd_lun_map); cdp->block_size = 2048; @@ -1085,29 +1085,31 @@ acdioctl(dev_t dev, u_long cmd, caddr_t addr, int flags, struct thread *td) } static void -acdstrategy(struct buf *bp) +acdstrategy(dev_t dev, struct bio *bio) { - struct acd_softc *cdp = bp->b_dev->si_drv1; + struct buf *bp = bio->bio_buf; + struct acd_softc *cdp = dev->si_drv1; if (cdp->device->flags & ATA_D_DETACHING) { bp->b_flags |= B_ERROR; bp->b_error = ENXIO; - biodone(bp); + biodone(bio); return; } /* if it's a null transfer, return immediatly. */ if (bp->b_bcount == 0) { bp->b_resid = 0; - biodone(bp); + biodone(bio); return; } - - bp->b_pblkno = bp->b_blkno; + + KKASSERT(bio->bio_blkno != (daddr_t)-1); + bio->bio_driver_info = dev; bp->b_resid = bp->b_bcount; crit_enter(); - bufqdisksort(&cdp->queue, bp); + bioqdisksort(&cdp->bio_queue, bio); crit_exit(); ata_start(cdp->device->channel); } @@ -1116,7 +1118,9 @@ void acd_start(struct ata_device *atadev) { struct acd_softc *cdp = atadev->driver; - struct buf *bp = bufq_first(&cdp->queue); + struct bio *bio = bioq_first(&cdp->bio_queue); + struct buf *bp; + dev_t dev; u_int32_t lba, lastlba, count; int8_t ccb[16]; int track, blocksize; @@ -1125,58 +1129,60 @@ acd_start(struct ata_device *atadev) int i; cdp = cdp->driver[cdp->changer_info->current_slot]; - bp = bufq_first(&cdp->queue); + bio = bioq_first(&cdp->bio_queue); /* check for work pending on any other slot */ for (i = 0; i < cdp->changer_info->slots; i++) { if (i == cdp->changer_info->current_slot) continue; - if (bufq_first(&(cdp->driver[i]->queue))) { - if (!bp || time_second > (cdp->timestamp + 10)) { + if (bioq_first(&(cdp->driver[i]->bio_queue))) { + if (bio == NULL || time_second > (cdp->timestamp + 10)) { acd_select_slot(cdp->driver[i]); return; } } } } - if (!bp) + if (bio == NULL) return; - bufq_remove(&cdp->queue, bp); + bioq_remove(&cdp->bio_queue, bio); + dev = bio->bio_driver_info; + bp = bio->bio_buf; /* reject all queued entries if media changed */ if (cdp->device->flags & ATA_D_MEDIA_CHANGED) { bp->b_flags |= B_ERROR; bp->b_error = EIO; - biodone(bp); + biodone(bio); return; } bzero(ccb, sizeof(ccb)); - track = (bp->b_dev->si_udev & 0x00ff0000) >> 16; + track = (dev->si_udev & 0x00ff0000) >> 16; if (track) { blocksize = (cdp->toc.tab[track - 1].control & 4) ? 2048 : 2352; lastlba = ntohl(cdp->toc.tab[track].addr.lba); if (bp->b_flags & B_PHYS) - lba = bp->b_offset / blocksize; + lba = bio->bio_offset / blocksize; else - lba = bp->b_blkno / (blocksize / DEV_BSIZE); + lba = bio->bio_blkno / (blocksize / DEV_BSIZE); lba += ntohl(cdp->toc.tab[track - 1].addr.lba); } else { blocksize = cdp->block_size; lastlba = cdp->disk_size; if (bp->b_flags & B_PHYS) - lba = bp->b_offset / blocksize; + lba = bio->bio_offset / blocksize; else - lba = bp->b_blkno / (blocksize / DEV_BSIZE); + lba = bio->bio_blkno / (blocksize / DEV_BSIZE); } if (bp->b_bcount % blocksize != 0) { bp->b_flags |= B_ERROR; bp->b_error = EINVAL; - biodone(bp); + biodone(bio); return; } count = bp->b_bcount / blocksize; @@ -1187,7 +1193,7 @@ acd_start(struct ata_device *atadev) /* if we are entirely beyond EOM return EOF */ if (lastlba <= lba) { bp->b_resid = bp->b_bcount; - biodone(bp); + biodone(bio); return; } count = lastlba - lba; @@ -1220,26 +1226,27 @@ acd_start(struct ata_device *atadev) ccb[8] = count; devstat_start_transaction(cdp->stats); - bp->b_caller1 = cdp; + bio->bio_caller_info1.ptr = cdp; atapi_queue_cmd(cdp->device, ccb, bp->b_data, count * blocksize, bp->b_flags & B_READ ? ATPR_F_READ : 0, - (ccb[0] == ATAPI_WRITE_BIG) ? 60 : 30, acd_done, bp); + (ccb[0] == ATAPI_WRITE_BIG) ? 60 : 30, acd_done, bio); } static int acd_done(struct atapi_request *request) { - struct buf *bp = request->driver; - struct acd_softc *cdp = bp->b_caller1; + struct bio *bio = request->driver; + struct buf *bp = bio->bio_buf; + struct acd_softc *cdp = bio->bio_caller_info1.ptr; if (request->error) { bp->b_error = request->error; bp->b_flags |= B_ERROR; - } - else + } else { bp->b_resid = bp->b_bcount - request->donecount; + } devstat_end_transaction_buf(cdp->stats, bp); - biodone(bp); + biodone(bio); return 0; } diff --git a/sys/dev/disk/ata/atapi-cd.h b/sys/dev/disk/ata/atapi-cd.h index e4f4351bf6..5bd1bd0588 100644 --- a/sys/dev/disk/ata/atapi-cd.h +++ b/sys/dev/disk/ata/atapi-cd.h @@ -26,7 +26,7 @@ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * $FreeBSD: src/sys/dev/ata/atapi-cd.h,v 1.15.2.9 2002/03/18 08:37:34 sos Exp $ - * $DragonFly: src/sys/dev/disk/ata/atapi-cd.h,v 1.2 2003/06/17 04:28:22 dillon Exp $ + * $DragonFly: src/sys/dev/disk/ata/atapi-cd.h,v 1.3 2006/02/17 19:17:54 dillon Exp $ */ /* CDROM Table Of Contents */ @@ -311,7 +311,7 @@ struct acd_softc { int flags; /* device state flags */ #define F_LOCKED 0x0001 /* this unit is locked */ - struct buf_queue_head queue; /* queue of i/o requests */ + struct bio_queue_head bio_queue; /* queue of i/o requests */ TAILQ_HEAD(, acd_devlist) dev_list; /* list of "track" devices */ struct toc toc; /* table of disc contents */ struct audiopage au; /* audio page info */ diff --git a/sys/dev/disk/ata/atapi-fd.c b/sys/dev/disk/ata/atapi-fd.c index 91e10181c1..7ba44a7b62 100644 --- a/sys/dev/disk/ata/atapi-fd.c +++ b/sys/dev/disk/ata/atapi-fd.c @@ -26,7 +26,7 @@ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * $FreeBSD: src/sys/dev/ata/atapi-fd.c,v 1.44.2.9 2002/07/31 11:19:26 sos Exp $ - * $DragonFly: src/sys/dev/disk/ata/atapi-fd.c,v 1.12 2005/06/03 21:56:23 swildner Exp $ + * $DragonFly: src/sys/dev/disk/ata/atapi-fd.c,v 1.13 2006/02/17 19:17:54 dillon Exp $ */ #include @@ -100,7 +100,7 @@ afdattach(struct ata_device *atadev) fdp->device = atadev; fdp->lun = ata_get_lun(&afd_lun_map); ata_set_name(atadev, "afd", fdp->lun); - bufq_init(&fdp->queue); + bioq_init(&fdp->bio_queue); if (afd_sense(fdp)) { free(fdp, M_AFD); @@ -131,13 +131,15 @@ void afddetach(struct ata_device *atadev) { struct afd_softc *fdp = atadev->driver; + struct bio *bio; struct buf *bp; - while ((bp = bufq_first(&fdp->queue))) { - bufq_remove(&fdp->queue, bp); + while ((bio = bioq_first(&fdp->bio_queue))) { + bioq_remove(&fdp->bio_queue, bio); + bp = bio->bio_buf; bp->b_flags |= B_ERROR; bp->b_error = ENXIO; - biodone(bp); + biodone(bio); } disk_invalidate(&fdp->disk); disk_destroy(&fdp->disk); @@ -292,26 +294,27 @@ afdioctl(dev_t dev, u_long cmd, caddr_t addr, int flag, struct thread *td) } static void -afdstrategy(struct buf *bp) +afdstrategy(dev_t dev, struct bio *bio) { - struct afd_softc *fdp = bp->b_dev->si_drv1; + struct buf *bp = bio->bio_buf; + struct afd_softc *fdp = dev->si_drv1; if (fdp->device->flags & ATA_D_DETACHING) { bp->b_flags |= B_ERROR; bp->b_error = ENXIO; - biodone(bp); + biodone(bio); return; } /* if it's a null transfer, return immediatly. */ if (bp->b_bcount == 0) { bp->b_resid = 0; - biodone(bp); + biodone(bio); return; } crit_enter(); - bufqdisksort(&fdp->queue, bp); + bioqdisksort(&fdp->bio_queue, bio); crit_exit(); ata_start(fdp->device->channel); } @@ -320,26 +323,28 @@ void afd_start(struct ata_device *atadev) { struct afd_softc *fdp = atadev->driver; - struct buf *bp = bufq_first(&fdp->queue); + struct bio *bio = bioq_first(&fdp->bio_queue); + struct buf *bp; u_int32_t lba; u_int16_t count; int8_t ccb[16]; caddr_t data_ptr; - if (!bp) + if (bio == NULL) return; - bufq_remove(&fdp->queue, bp); + bioq_remove(&fdp->bio_queue, bio); + bp = bio->bio_buf; /* should reject all queued entries if media have changed. */ if (fdp->device->flags & ATA_D_MEDIA_CHANGED) { bp->b_flags |= B_ERROR; bp->b_error = EIO; - biodone(bp); + biodone(bio); return; } - lba = bp->b_pblkno; + lba = bio->bio_blkno; count = bp->b_bcount / fdp->cap.sector_size; data_ptr = bp->b_data; bp->b_resid = bp->b_bcount; @@ -362,13 +367,14 @@ afd_start(struct ata_device *atadev) atapi_queue_cmd(fdp->device, ccb, data_ptr, count * fdp->cap.sector_size, (bp->b_flags & B_READ) ? ATPR_F_READ : 0, 30, - afd_done, bp); + afd_done, bio); } static int afd_done(struct atapi_request *request) { - struct buf *bp = request->driver; + struct bio *bio = request->driver; + struct buf *bp = bio->bio_buf; struct afd_softc *fdp = request->device->driver; if (request->error || (bp->b_flags & B_ERROR)) { @@ -378,7 +384,7 @@ afd_done(struct atapi_request *request) else bp->b_resid = bp->b_bcount - request->donecount; devstat_end_transaction_buf(&fdp->stats, bp); - biodone(bp); + biodone(bio); return 0; } diff --git a/sys/dev/disk/ata/atapi-fd.h b/sys/dev/disk/ata/atapi-fd.h index d4ccfec2f6..ebb103c552 100644 --- a/sys/dev/disk/ata/atapi-fd.h +++ b/sys/dev/disk/ata/atapi-fd.h @@ -26,7 +26,7 @@ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * $FreeBSD: src/sys/dev/ata/atapi-fd.h,v 1.10.2.5 2002/07/31 11:19:26 sos Exp $ - * $DragonFly: src/sys/dev/disk/ata/atapi-fd.h,v 1.2 2003/06/17 04:28:22 dillon Exp $ + * $DragonFly: src/sys/dev/disk/ata/atapi-fd.h,v 1.3 2006/02/17 19:17:54 dillon Exp $ */ /* ATAPI Rewriteable drive Capabilities and Mechanical Status Page */ @@ -72,7 +72,7 @@ struct afd_cappage { struct afd_softc { struct ata_device *device; /* device softc */ int lun; /* logical device unit */ - struct buf_queue_head queue; /* queue of i/o requests */ + struct bio_queue_head bio_queue; /* queue of i/o requests */ struct afd_cappage cap; /* capabilities page info */ struct disk disk; /* virtual drives */ struct devstat stats; diff --git a/sys/dev/disk/ata/atapi-tape.c b/sys/dev/disk/ata/atapi-tape.c index d3b7e45f33..8764c435c5 100644 --- a/sys/dev/disk/ata/atapi-tape.c +++ b/sys/dev/disk/ata/atapi-tape.c @@ -26,7 +26,7 @@ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * $FreeBSD: src/sys/dev/ata/atapi-tape.c,v 1.36.2.12 2002/07/31 11:19:26 sos Exp $ - * $DragonFly: src/sys/dev/disk/ata/atapi-tape.c,v 1.12 2005/06/03 21:56:23 swildner Exp $ + * $DragonFly: src/sys/dev/disk/ata/atapi-tape.c,v 1.13 2006/02/17 19:17:54 dillon Exp $ */ #include "opt_ata.h" @@ -110,7 +110,7 @@ astattach(struct ata_device *atadev) stp->device = atadev; stp->lun = ata_get_lun(&ast_lun_map); ata_set_name(atadev, "ast", stp->lun); - bufq_init(&stp->queue); + bioq_init(&stp->bio_queue); if (ast_sense(stp)) { free(stp, M_AST); @@ -157,12 +157,14 @@ astdetach(struct ata_device *atadev) { struct ast_softc *stp = atadev->driver; struct buf *bp; + struct bio *bio; - while ((bp = bufq_first(&stp->queue))) { - bufq_remove(&stp->queue, bp); + while ((bio = bioq_first(&stp->bio_queue))) { + bioq_remove(&stp->bio_queue, bio); + bp = bio->bio_buf; bp->b_flags |= B_ERROR; bp->b_error = ENXIO; - biodone(bp); + biodone(bio); } devstat_remove_entry(&stp->stats); cdevsw_remove(&ast_cdevsw, dkunitmask(), dkmakeunit(stp->lun)); @@ -417,27 +419,28 @@ astioctl(dev_t dev, u_long cmd, caddr_t addr, int flag, struct thread *td) } static void -aststrategy(struct buf *bp) +aststrategy(dev_t dev, struct bio *bio) { - struct ast_softc *stp = bp->b_dev->si_drv1; + struct buf *bp = bio->bio_buf; + struct ast_softc *stp = dev->si_drv1; if (stp->device->flags & ATA_D_DETACHING) { bp->b_flags |= B_ERROR; bp->b_error = ENXIO; - biodone(bp); + biodone(bio); return; } /* if it's a null transfer, return immediatly. */ if (bp->b_bcount == 0) { bp->b_resid = 0; - biodone(bp); + biodone(bio); return; } if (!(bp->b_flags & B_READ) && stp->flags & F_WRITEPROTECT) { bp->b_flags |= B_ERROR; bp->b_error = EPERM; - biodone(bp); + biodone(bio); return; } @@ -447,7 +450,7 @@ aststrategy(struct buf *bp) stp->blksize); bp->b_flags |= B_ERROR; bp->b_error = EIO; - biodone(bp); + biodone(bio); return; } @@ -461,7 +464,7 @@ aststrategy(struct buf *bp) } crit_enter(); - bufq_insert_tail(&stp->queue, bp); + bioq_insert_tail(&stp->bio_queue, bio); crit_exit(); ata_start(stp->device->channel); } @@ -470,21 +473,22 @@ void ast_start(struct ata_device *atadev) { struct ast_softc *stp = atadev->driver; - struct buf *bp = bufq_first(&stp->queue); + struct bio *bio = bioq_first(&stp->bio_queue); + struct buf *bp; u_int32_t blkcount; int8_t ccb[16]; - if (!bp) + if (bio == NULL) return; - bzero(ccb, sizeof(ccb)); + bp = bio->bio_buf; if (bp->b_flags & B_READ) ccb[0] = ATAPI_READ; else ccb[0] = ATAPI_WRITE; - bufq_remove(&stp->queue, bp); + bioq_remove(&stp->bio_queue, bio); blkcount = bp->b_bcount / stp->blksize; ccb[1] = 1; @@ -496,27 +500,27 @@ ast_start(struct ata_device *atadev) atapi_queue_cmd(stp->device, ccb, bp->b_data, blkcount * stp->blksize, (bp->b_flags & B_READ) ? ATPR_F_READ : 0, - 120, ast_done, bp); + 120, ast_done, bio); } static int ast_done(struct atapi_request *request) { - struct buf *bp = request->driver; + struct bio *bio = request->driver; + struct buf *bp = bio->bio_buf; struct ast_softc *stp = request->device->driver; if (request->error) { bp->b_error = request->error; bp->b_flags |= B_ERROR; - } - else { + } else { if (!(bp->b_flags & B_READ)) stp->flags |= F_DATA_WRITTEN; bp->b_resid = bp->b_bcount - request->donecount; ast_total += (bp->b_bcount - bp->b_resid); } devstat_end_transaction_buf(&stp->stats, bp); - biodone(bp); + biodone(bio); return 0; } diff --git a/sys/dev/disk/ata/atapi-tape.h b/sys/dev/disk/ata/atapi-tape.h index c81ec63841..8324343e22 100644 --- a/sys/dev/disk/ata/atapi-tape.h +++ b/sys/dev/disk/ata/atapi-tape.h @@ -26,7 +26,7 @@ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * $FreeBSD: src/sys/dev/ata/atapi-tape.h,v 1.11.2.5 2002/03/18 08:37:34 sos Exp $ - * $DragonFly: src/sys/dev/disk/ata/atapi-tape.h,v 1.3 2004/05/19 22:52:41 dillon Exp $ + * $DragonFly: src/sys/dev/disk/ata/atapi-tape.h,v 1.4 2006/02/17 19:17:54 dillon Exp $ */ /* ATAPI tape drive Capabilities and Mechanical Status Page */ @@ -155,7 +155,7 @@ struct ast_softc { #define F_ONSTREAM 0x0100 /* OnStream ADR device */ int blksize; /* block size (512 | 1024) */ - struct buf_queue_head queue; /* queue of i/o requests */ + struct bio_queue_head bio_queue; /* queue of i/o requests */ struct atapi_params *param; /* drive parameters table */ struct ast_cappage cap; /* capabilities page info */ struct devstat stats; /* devstat entry */ diff --git a/sys/dev/disk/ccd/ccd.c b/sys/dev/disk/ccd/ccd.c index f36dceb388..c87219b4f0 100644 --- a/sys/dev/disk/ccd/ccd.c +++ b/sys/dev/disk/ccd/ccd.c @@ -1,5 +1,5 @@ /* $FreeBSD: src/sys/dev/ccd/ccd.c,v 1.73.2.1 2001/09/11 09:49:52 kris Exp $ */ -/* $DragonFly: src/sys/dev/disk/ccd/ccd.c,v 1.21 2005/12/11 01:54:07 swildner Exp $ */ +/* $DragonFly: src/sys/dev/disk/ccd/ccd.c,v 1.22 2006/02/17 19:17:55 dillon Exp $ */ /* $NetBSD: ccd.c,v 1.22 1995/12/08 19:13:26 thorpej Exp $ */ @@ -149,7 +149,7 @@ SYSCTL_INT(_debug, OID_AUTO, ccddebug, CTLFLAG_RW, &ccddebug, 0, ""); struct ccdbuf { struct buf cb_buf; /* new I/O buf */ - struct buf *cb_obp; /* ptr. to original I/O buf */ + struct bio *cb_obio; /* ptr. to original I/O buf */ struct ccdbuf *cb_freenext; /* free list link */ int cb_unit; /* target unit */ int cb_comp; /* target component */ @@ -198,15 +198,15 @@ static void ccdattach (void); static int ccd_modevent (module_t, int, void *); /* called by biodone() at interrupt time */ -static void ccdiodone (struct ccdbuf *cbp); +static void ccdiodone (struct bio *bio); -static void ccdstart (struct ccd_softc *, struct buf *); +static void ccdstart (struct ccd_softc *, struct bio *); static void ccdinterleave (struct ccd_softc *, int); -static void ccdintr (struct ccd_softc *, struct buf *); +static void ccdintr (struct ccd_softc *, struct bio *); static int ccdinit (struct ccddevice *, char **, struct thread *); static int ccdlookup (char *, struct thread *td, struct vnode **); static void ccdbuffer (struct ccdbuf **ret, struct ccd_softc *, - struct buf *, daddr_t, caddr_t, long); + struct bio *, daddr_t, caddr_t, long); static void ccdgetdisklabel (dev_t); static void ccdmakedisklabel (struct ccd_softc *); static int ccdlock (struct ccd_softc *); @@ -241,8 +241,10 @@ getccdbuf(struct ccdbuf *cpy) if ((cbp = ccdfreebufs) != NULL) { ccdfreebufs = cbp->cb_freenext; --numccdfreebufs; + reinitbufbio(&cbp->cb_buf); } else { cbp = malloc(sizeof(struct ccdbuf), M_DEVBUF, M_WAITOK); + initbufbio(&cbp->cb_buf); } /* @@ -749,9 +751,11 @@ ccdclose(dev_t dev, int flags, int fmt, d_thread_t *td) } static void -ccdstrategy(struct buf *bp) +ccdstrategy(dev_t dev, struct bio *bio) { - int unit = ccdunit(bp->b_dev); + int unit = ccdunit(dev); + struct bio *nbio; + struct buf *bp = bio->bio_buf; struct ccd_softc *cs = &ccd_softc[unit]; int wlabel; struct disklabel *lp; @@ -777,14 +781,15 @@ ccdstrategy(struct buf *bp) * error, the bounds check will flag that for us. */ wlabel = cs->sc_flags & (CCDF_WLABEL|CCDF_LABELLING); - if (ccdpart(bp->b_dev) != RAW_PART) { - if (bounds_check_with_label(bp, lp, wlabel) <= 0) + if (ccdpart(dev) != RAW_PART) { + nbio = bounds_check_with_label(dev, bio, lp, wlabel); + if (nbio == NULL) goto done; } else { int pbn; /* in sc_secsize chunks */ long sz; /* in sc_secsize chunks */ - pbn = bp->b_blkno / (cs->sc_geom.ccg_secsize / DEV_BSIZE); + pbn = bio->bio_blkno / (cs->sc_geom.ccg_secsize / DEV_BSIZE); sz = howmany(bp->b_bcount, cs->sc_geom.ccg_secsize); /* @@ -808,26 +813,34 @@ ccdstrategy(struct buf *bp) bp->b_bcount = (cs->sc_size - pbn) * cs->sc_geom.ccg_secsize; } + nbio = bio; } bp->b_resid = bp->b_bcount; + nbio->bio_driver_info = dev; /* * "Start" the unit. */ crit_enter(); - ccdstart(cs, bp); + ccdstart(cs, nbio); crit_exit(); return; + + /* + * note: bio, not nbio, is valid at the done label. + */ done: - biodone(bp); + biodone(bio); } static void -ccdstart(struct ccd_softc *cs, struct buf *bp) +ccdstart(struct ccd_softc *cs, struct bio *bio) { long bcount, rcount; struct ccdbuf *cbp[4]; + struct buf *bp = bio->bio_buf; + dev_t dev = bio->bio_driver_info; /* XXX! : 2 reads and 2 writes for RAID 4/5 */ caddr_t addr; daddr_t bn; @@ -844,9 +857,9 @@ ccdstart(struct ccd_softc *cs, struct buf *bp) /* * Translate the partition-relative block number to an absolute. */ - bn = bp->b_blkno; - if (ccdpart(bp->b_dev) != RAW_PART) { - pp = &cs->sc_label.d_partitions[ccdpart(bp->b_dev)]; + bn = bio->bio_blkno; + if (ccdpart(dev) != RAW_PART) { + pp = &cs->sc_label.d_partitions[ccdpart(dev)]; bn += pp->p_offset; } @@ -855,7 +868,7 @@ ccdstart(struct ccd_softc *cs, struct buf *bp) */ addr = bp->b_data; for (bcount = bp->b_bcount; bcount > 0; bcount -= rcount) { - ccdbuffer(cbp, cs, bp, bn, addr, bcount); + ccdbuffer(cbp, cs, bio, bn, addr, bcount); rcount = cbp[0]->cb_buf.b_bcount; if (cs->sc_cflags & CCDF_MIRROR) { @@ -869,12 +882,10 @@ ccdstart(struct ccd_softc *cs, struct buf *bp) * also try to avoid hogging. */ if ((cbp[0]->cb_buf.b_flags & B_READ) == 0) { - cbp[0]->cb_buf.b_vp->v_numoutput++; - cbp[1]->cb_buf.b_vp->v_numoutput++; - VOP_STRATEGY(cbp[0]->cb_buf.b_vp, - &cbp[0]->cb_buf); - VOP_STRATEGY(cbp[1]->cb_buf.b_vp, - &cbp[1]->cb_buf); + vn_strategy(cbp[0]->cb_buf.b_vp, + &cbp[0]->cb_buf.b_bio1); + vn_strategy(cbp[1]->cb_buf.b_vp, + &cbp[1]->cb_buf.b_bio1); } else { int pick = cs->sc_pick; daddr_t range = cs->sc_size / 16; @@ -885,16 +896,15 @@ ccdstart(struct ccd_softc *cs, struct buf *bp) cs->sc_pick = pick = 1 - pick; } cs->sc_blk[pick] = bn + btodb(rcount); - VOP_STRATEGY(cbp[pick]->cb_buf.b_vp, - &cbp[pick]->cb_buf); + vn_strategy(cbp[pick]->cb_buf.b_vp, + &cbp[pick]->cb_buf.b_bio1); } } else { /* * Not mirroring */ - if ((cbp[0]->cb_buf.b_flags & B_READ) == 0) - cbp[0]->cb_buf.b_vp->v_numoutput++; - VOP_STRATEGY(cbp[0]->cb_buf.b_vp, &cbp[0]->cb_buf); + vn_strategy(cbp[0]->cb_buf.b_vp, + &cbp[0]->cb_buf.b_bio1); } bn += btodb(rcount); addr += rcount; @@ -905,7 +915,7 @@ ccdstart(struct ccd_softc *cs, struct buf *bp) * Build a component buffer header. */ static void -ccdbuffer(struct ccdbuf **cb, struct ccd_softc *cs, struct buf *bp, daddr_t bn, +ccdbuffer(struct ccdbuf **cb, struct ccd_softc *cs, struct bio *bio, daddr_t bn, caddr_t addr, long bcount) { struct ccdcinfo *ci, *ci2 = NULL; /* XXX */ @@ -1026,11 +1036,8 @@ ccdbuffer(struct ccdbuf **cb, struct ccd_softc *cs, struct buf *bp, daddr_t bn, * Fill in the component buf structure. */ cbp = getccdbuf(NULL); - cbp->cb_buf.b_flags = bp->b_flags; - cbp->cb_buf.b_iodone = (void (*)(struct buf *))ccdiodone; - cbp->cb_buf.b_dev = ci->ci_dev; /* XXX */ - cbp->cb_buf.b_blkno = cbn + cboff + CCD_OFFSET; - cbp->cb_buf.b_offset = dbtob(cbn + cboff + CCD_OFFSET); + cbp->cb_buf.b_flags = bio->bio_buf->b_flags; + /*cbp->cb_buf.b_dev = ci->ci_dev; */ cbp->cb_buf.b_data = addr; cbp->cb_buf.b_vp = ci->ci_vp; if (cs->sc_ileave == 0) @@ -1040,17 +1047,23 @@ ccdbuffer(struct ccdbuf **cb, struct ccd_softc *cs, struct buf *bp, daddr_t bn, cbp->cb_buf.b_bcount = (cbc < bcount) ? cbc : bcount; cbp->cb_buf.b_bufsize = cbp->cb_buf.b_bcount; + cbp->cb_buf.b_bio1.bio_done = ccdiodone; + cbp->cb_buf.b_bio1.bio_caller_info1.ptr = cbp; + cbp->cb_buf.b_bio1.bio_blkno = cbn + cboff + CCD_OFFSET; + cbp->cb_buf.b_bio1.bio_offset = dbtob(cbn + cboff + CCD_OFFSET); + /* * context for ccdiodone */ - cbp->cb_obp = bp; + cbp->cb_obio = bio; cbp->cb_unit = cs - ccd_softc; cbp->cb_comp = ci - cs->sc_cinfo; #ifdef DEBUG if (ccddebug & CCDB_IO) printf(" dev %x(u%d): cbp %x bn %d addr %x bcnt %d\n", - ci->ci_dev, ci-cs->sc_cinfo, cbp, cbp->cb_buf.b_blkno, + ci->ci_dev, ci-cs->sc_cinfo, cbp, + cbp->cb_buf.b_bio1.bio_blkno, cbp->cb_buf.b_data, cbp->cb_buf.b_bcount); #endif cb[0] = cbp; @@ -1062,7 +1075,7 @@ ccdbuffer(struct ccdbuf **cb, struct ccd_softc *cs, struct buf *bp, daddr_t bn, if (cs->sc_cflags & CCDF_MIRROR) { /* mirror, setup second I/O */ cbp = getccdbuf(cb[0]); - cbp->cb_buf.b_dev = ci2->ci_dev; + /* cbp->cb_buf.b_dev = ci2->ci_dev; */ cbp->cb_buf.b_vp = ci2->ci_vp; cbp->cb_comp = ci2 - cs->sc_cinfo; cb[1] = cbp; @@ -1075,8 +1088,10 @@ ccdbuffer(struct ccdbuf **cb, struct ccd_softc *cs, struct buf *bp, daddr_t bn, } static void -ccdintr(struct ccd_softc *cs, struct buf *bp) +ccdintr(struct ccd_softc *cs, struct bio *bio) { + struct buf *bp = bio->bio_buf; + #ifdef DEBUG if (ccddebug & CCDB_FOLLOW) printf("ccdintr(%x, %x)\n", cs, bp); @@ -1087,7 +1102,7 @@ ccdintr(struct ccd_softc *cs, struct buf *bp) if (bp->b_flags & B_ERROR) bp->b_resid = bp->b_bcount; devstat_end_transaction_buf(&cs->device_stats, bp); - biodone(bp); + biodone(bio); } /* @@ -1096,22 +1111,30 @@ ccdintr(struct ccd_softc *cs, struct buf *bp) * take a ccd interrupt. */ static void -ccdiodone(struct ccdbuf *cbp) +ccdiodone(struct bio *bio) { - struct buf *bp = cbp->cb_obp; + struct ccdbuf *cbp = bio->bio_caller_info1.ptr; + struct bio *obio = cbp->cb_obio; + struct buf *obp = obio->bio_buf; int unit = cbp->cb_unit; int count; + /* + * Since we do not have exclusive access to underlying devices, + * we can't keep cache translations around. + */ + clearbiocache(bio->bio_next); + crit_enter(); #ifdef DEBUG if (ccddebug & CCDB_FOLLOW) printf("ccdiodone(%x)\n", cbp); if (ccddebug & CCDB_IO) { printf("ccdiodone: bp %x bcount %d resid %d\n", - bp, bp->b_bcount, bp->b_resid); + obp, obp->b_bcount, obp->b_resid); printf(" dev %x(u%d), cbp %x bn %d addr %x bcnt %d\n", cbp->cb_buf.b_dev, cbp->cb_comp, cbp, - cbp->cb_buf.b_blkno, cbp->cb_buf.b_data, + cbp->cb_buf.b_lblkno, cbp->cb_buf.b_data, cbp->cb_buf.b_bcount); } #endif @@ -1121,7 +1144,6 @@ ccdiodone(struct ccdbuf *cbp) * set the error in the bp yet because the second read may * succeed. */ - if (cbp->cb_buf.b_flags & B_ERROR) { const char *msg = ""; @@ -1138,15 +1160,16 @@ ccdiodone(struct ccdbuf *cbp) msg = ", trying other disk"; cs->sc_pick = 1 - cs->sc_pick; - cs->sc_blk[cs->sc_pick] = bp->b_blkno; + cs->sc_blk[cs->sc_pick] = obio->bio_blkno; } else { - bp->b_flags |= B_ERROR; - bp->b_error = cbp->cb_buf.b_error ? + obp->b_flags |= B_ERROR; + obp->b_error = cbp->cb_buf.b_error ? cbp->cb_buf.b_error : EIO; } printf("ccd%d: error %d on component %d block %d (ccd block %d)%s\n", - unit, bp->b_error, cbp->cb_comp, - (int)cbp->cb_buf.b_blkno, bp->b_blkno, msg); + unit, obp->b_error, cbp->cb_comp, + (int)cbp->cb_buf.b_bio2.bio_blkno, + obio->bio_blkno, msg); } /* @@ -1181,9 +1204,9 @@ ccdiodone(struct ccdbuf *cbp) if (cbp->cb_buf.b_flags & B_ERROR) { cbp->cb_mirror->cb_pflags |= CCDPF_MIRROR_DONE; - VOP_STRATEGY( + vn_strategy( cbp->cb_mirror->cb_buf.b_vp, - &cbp->cb_mirror->cb_buf + &cbp->cb_mirror->cb_buf.b_bio1 ); putccdbuf(cbp); crit_exit(); @@ -1211,11 +1234,11 @@ ccdiodone(struct ccdbuf *cbp) /* * If all done, "interrupt". */ - bp->b_resid -= count; - if (bp->b_resid < 0) + obp->b_resid -= count; + if (obp->b_resid < 0) panic("ccdiodone: count"); - if (bp->b_resid == 0) - ccdintr(&ccd_softc[unit], bp); + if (obp->b_resid == 0) + ccdintr(&ccd_softc[unit], obio); crit_exit(); } diff --git a/sys/dev/disk/fd/fd.c b/sys/dev/disk/fd/fd.c index 62bb50e4db..8ce8ffea6c 100644 --- a/sys/dev/disk/fd/fd.c +++ b/sys/dev/disk/fd/fd.c @@ -51,7 +51,7 @@ * * from: @(#)fd.c 7.4 (Berkeley) 5/25/91 * $FreeBSD: src/sys/isa/fd.c,v 1.176.2.8 2002/05/15 21:56:14 joerg Exp $ - * $DragonFly: src/sys/dev/disk/fd/fd.c,v 1.24 2005/11/19 17:58:17 dillon Exp $ + * $DragonFly: src/sys/dev/disk/fd/fd.c,v 1.25 2006/02/17 19:17:57 dillon Exp $ * */ @@ -817,7 +817,7 @@ fdc_attach(device_t dev) /* reset controller, turn motor off, clear fdout mirror reg */ fdout_wr(fdc, ((fdc->fdout = 0))); - bufq_init(&fdc->head); + bioq_init(&fdc->bio_queue); /* * Probe and attach any children. We should probably detect @@ -1381,19 +1381,20 @@ fdclose(dev_t dev, int flags, int mode, struct thread *td) /* fdstrategy */ /****************************************************************************/ void -fdstrategy(struct buf *bp) +fdstrategy(dev_t dev, struct bio *bio) { + struct buf *bp = bio->bio_buf; unsigned nblocks, blknum, cando; fdu_t fdu; fdc_p fdc; fd_p fd; size_t fdblk; - fdu = FDUNIT(minor(bp->b_dev)); + fdu = FDUNIT(minor(dev)); fd = devclass_get_softc(fd_devclass, fdu); if (fd == 0) panic("fdstrategy: buf for nonexistent device (%#lx, %#lx)", - (u_long)major(bp->b_dev), (u_long)minor(bp->b_dev)); + (u_long)major(dev), (u_long)minor(dev)); fdc = fd->fdc; if (fd->type == NO_TYPE) { bp->b_error = ENXIO; @@ -1403,10 +1404,10 @@ fdstrategy(struct buf *bp) fdblk = 128 << (fd->ft->secsize); if (!(bp->b_flags & B_FORMAT)) { - if (bp->b_blkno < 0) { + if (bio->bio_blkno < 0) { printf( "fd%d: fdstrat: bad request blkno = %lu, bcount = %ld\n", - fdu, (u_long)bp->b_blkno, bp->b_bcount); + fdu, (u_long)bio->bio_blkno, bp->b_bcount); bp->b_error = EINVAL; bp->b_flags |= B_ERROR; goto bad; @@ -1421,7 +1422,7 @@ fdstrategy(struct buf *bp) /* * Set up block calculations. */ - if (bp->b_blkno > 20000000) { + if (bio->bio_blkno > 20000000) { /* * Reject unreasonably high block number, prevent the * multiplication below from overflowing. @@ -1430,7 +1431,7 @@ fdstrategy(struct buf *bp) bp->b_flags |= B_ERROR; goto bad; } - blknum = (unsigned) bp->b_blkno * DEV_BSIZE/fdblk; + blknum = (unsigned) bio->bio_blkno * DEV_BSIZE/fdblk; nblocks = fd->ft->size; bp->b_resid = 0; if (blknum + (bp->b_bcount / fdblk) > nblocks) { @@ -1445,9 +1446,9 @@ fdstrategy(struct buf *bp) goto bad; } } - bp->b_pblkno = bp->b_blkno; crit_enter(); - bufqdisksort(&fdc->head, bp); + bio->bio_driver_info = dev; + bioqdisksort(&fdc->bio_queue, bio); callout_stop(&fd->toffhandle); /* Tell devstat we are starting on the transaction */ @@ -1459,7 +1460,7 @@ fdstrategy(struct buf *bp) return; bad: - biodone(bp); + biodone(bio); } /***************************************************************\ @@ -1575,19 +1576,21 @@ fdstate(fdc_p fdc) unsigned blknum = 0, b_cylinder = 0; fdu_t fdu = fdc->fdu; fd_p fd; + struct bio *bio; struct buf *bp; struct fd_formb *finfo = NULL; size_t fdblk; - - bp = fdc->bp; - if (bp == NULL) { - bp = bufq_first(&fdc->head); - if (bp != NULL) { - bufq_remove(&fdc->head, bp); - fdc->bp = bp; + dev_t dev; + + bio = fdc->bio; + if (bio == NULL) { + bio = bioq_first(&fdc->bio_queue); + if (bio != NULL) { + bioq_remove(&fdc->bio_queue, bio); + fdc->bio = bio; } } - if (bp == NULL) { + if (bio == NULL) { /***********************************************\ * nothing left for this controller to do * * Force into the IDLE state, * @@ -1602,7 +1605,10 @@ fdstate(fdc_p fdc) TRACE1("[fdc%d IDLE]", fdc->fdcu); return (0); } - fdu = FDUNIT(minor(bp->b_dev)); + bp = bio->bio_buf; + dev = bio->bio_driver_info; + + fdu = FDUNIT(minor(dev)); fd = devclass_get_softc(fd_devclass, fdu); fdblk = 128 << fd->ft->secsize; if (fdc->fd && (fd != fdc->fd)) @@ -1615,7 +1621,7 @@ fdstate(fdc_p fdc) - (char *)finfo; } if (fdc->state == DOSEEK || fdc->state == SEEKCOMPLETE) { - blknum = (unsigned) bp->b_pblkno * DEV_BSIZE/fdblk + + blknum = (unsigned) bio->bio_blkno * DEV_BSIZE/fdblk + fd->skip/fdblk; b_cylinder = blknum / (fd->ft->sectrac * fd->ft->heads); } @@ -1958,10 +1964,10 @@ fdstate(fdc_p fdc) } else { /* ALL DONE */ fd->skip = 0; - fdc->bp = NULL; + fdc->bio = NULL; device_unbusy(fd->dev); devstat_end_transaction_buf(&fd->device_stats, bp); - biodone(bp); + biodone(bio); fdc->fd = (fd_p) 0; fdc->fdu = -1; fdc->state = FINDWORK; @@ -2071,14 +2077,18 @@ fdstate(fdc_p fdc) static int retrier(struct fdc_data *fdc) { + struct bio *bio; struct buf *bp; struct fd_data *fd; + dev_t dev; int fdu; - bp = fdc->bp; + bio = fdc->bio; + bp = bio->bio_buf; + dev = bio->bio_driver_info; /* XXX shouldn't this be cached somewhere? */ - fdu = FDUNIT(minor(bp->b_dev)); + fdu = FDUNIT(minor(dev)); fd = devclass_get_softc(fd_devclass, fdu); if (fd->options & FDOPT_NORETRY) goto fail; @@ -2107,9 +2117,9 @@ retrier(struct fdc_data *fdc) */ dev_t subdev; - subdev = make_sub_dev(bp->b_dev, - (FDUNIT(minor(bp->b_dev))<<3)|RAW_PART); - diskerr(bp, subdev, + subdev = make_sub_dev(dev, + (FDUNIT(minor(dev))<<3)|RAW_PART); + diskerr(bio, subdev, "hard error", LOG_PRINTF, fdc->fd->skip / DEV_BSIZE, (struct disklabel *)NULL); @@ -2130,11 +2140,11 @@ retrier(struct fdc_data *fdc) bp->b_flags |= B_ERROR; bp->b_error = EIO; bp->b_resid += bp->b_bcount - fdc->fd->skip; - fdc->bp = NULL; + fdc->bio = NULL; fdc->fd->skip = 0; device_unbusy(fd->dev); devstat_end_transaction_buf(&fdc->fd->device_stats, bp); - biodone(bp); + biodone(bio); fdc->state = FINDWORK; fdc->flags |= FDC_NEEDS_RESET; fdc->fd = (fd_p) 0; @@ -2162,26 +2172,24 @@ fdformat(dev_t dev, struct fd_formb *finfo, struct thread *td) /* set up a buffer header for fdstrategy() */ bp = malloc(sizeof(struct buf), M_TEMP, M_WAITOK | M_ZERO); - /* - * keep the process from being swapped - */ BUF_LOCKINIT(bp); BUF_LOCK(bp, LK_EXCLUSIVE); + initbufbio(bp); bp->b_flags = B_PHYS | B_FORMAT; /* * calculate a fake blkno, so fdstrategy() would initiate a * seek to the requested cylinder */ - bp->b_blkno = (finfo->cyl * (fd->ft->sectrac * fd->ft->heads) + bp->b_bio1.bio_blkno = (finfo->cyl * (fd->ft->sectrac * fd->ft->heads) + finfo->head * fd->ft->sectrac) * fdblk / DEV_BSIZE; + bp->b_bio1.bio_driver_info = dev; bp->b_bcount = sizeof(struct fd_idfield_data) * finfo->fd_formb_nsecs; bp->b_data = (caddr_t)finfo; /* now do the format */ - bp->b_dev = dev; - BUF_STRATEGY(bp, 0); + dev_dstrategy(dev, &bp->b_bio1); /* ...and wait for it to complete */ crit_enter(); @@ -2196,7 +2204,7 @@ fdformat(dev_t dev, struct fd_formb *finfo, struct thread *td) /* timed out */ rv = EIO; device_unbusy(fd->dev); - biodone(bp); + biodone(&bp->b_bio1); } if (bp->b_flags & B_ERROR) rv = bp->b_error; diff --git a/sys/dev/disk/fd/fdc.h b/sys/dev/disk/fd/fdc.h index dd9a8e8380..8c70dcfbeb 100644 --- a/sys/dev/disk/fd/fdc.h +++ b/sys/dev/disk/fd/fdc.h @@ -32,7 +32,7 @@ * * from: @(#)fd.c 7.4 (Berkeley) 5/25/91 * $FreeBSD: src/sys/isa/fdc.h,v 1.20.2.3 2002/02/03 14:08:46 nyan Exp $ - * $DragonFly: src/sys/dev/disk/fd/fdc.h,v 1.5 2005/03/05 18:31:52 swildner Exp $ + * $DragonFly: src/sys/dev/disk/fd/fdc.h,v 1.6 2006/02/17 19:17:57 dillon Exp $ * */ @@ -65,8 +65,8 @@ struct fdc_data u_int status[7]; /* copy of the registers */ enum fdc_type fdct; /* chip version of FDC */ int fdc_errs; /* number of logged errors */ - struct buf_queue_head head; - struct buf *bp; /* active buffer */ + struct bio_queue_head bio_queue; + struct bio *bio; /* active buffer */ int dma_overruns; /* number of DMA overruns */ struct resource *res_ioport, *res_ctl, *res_irq, *res_drq; int rid_ioport, rid_ctl, rid_irq, rid_drq; diff --git a/sys/dev/disk/mcd/mcd.c b/sys/dev/disk/mcd/mcd.c index d1ef48a016..3b93a24fd5 100644 --- a/sys/dev/disk/mcd/mcd.c +++ b/sys/dev/disk/mcd/mcd.c @@ -41,7 +41,7 @@ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * $FreeBSD: src/sys/i386/isa/mcd.c,v 1.115 2000/01/29 16:17:34 peter Exp $ - * $DragonFly: src/sys/dev/disk/mcd/Attic/mcd.c,v 1.14 2005/10/13 08:50:33 sephe Exp $ + * $DragonFly: src/sys/dev/disk/mcd/Attic/mcd.c,v 1.15 2006/02/17 19:17:59 dillon Exp $ */ static const char COPYRIGHT[] = "mcd-driver (C)1993 by H.Veit & B.Moore"; @@ -120,7 +120,7 @@ struct mcd_mbx { short nblk; int sz; u_long skip; - struct buf *bp; + struct bio *bio; int p_offset; short count; short mode; @@ -145,7 +145,7 @@ static struct mcd_data { short curr_mode; struct mcd_read2 lastpb; short debug; - struct buf_queue_head head; /* head of buf queue */ + struct bio_queue_head bio_queue; /* head of buf queue */ struct mcd_mbx mbx; struct callout callout; } mcd_data[NMCD]; @@ -253,7 +253,7 @@ int mcd_attach(struct isa_device *dev) cd->flags |= MCDINIT; callout_init(&cd->callout); mcd_soft_reset(unit); - bufq_init(&cd->head); + bioq_init(&cd->bio_queue); #ifdef NOTYET /* wire controller for interrupts and dma */ @@ -389,20 +389,22 @@ int mcdclose(dev_t dev, int flags, int fmt, struct thread *td) } void -mcdstrategy(struct buf *bp) +mcdstrategy(dev_t dev, struct bio *bio) { + struct bio *nbio; + struct buf *bp = bio->bio_buf; struct mcd_data *cd; - - int unit = mcd_unit(bp->b_dev); + int unit = mcd_unit(dev); cd = mcd_data + unit; + bio->bio_driver_info = dev; /* test validity */ /*MCD_TRACE("strategy: buf=0x%lx, unit=%ld, block#=%ld bcount=%ld\n", - bp,unit,bp->b_blkno,bp->b_bcount);*/ - if (unit >= NMCD || bp->b_blkno < 0) { + bp,unit,bio->bio_blkno,bp->b_bcount);*/ + if (unit >= NMCD || bio->bio_blkno < 0) { printf("mcdstrategy: unit = %d, blkno = %ld, bcount = %ld\n", - unit, (long)bp->b_blkno, bp->b_bcount); + unit, (long)bio->bio_blkno, bp->b_bcount); printf("mcd: mcdstratregy failure"); bp->b_error = EINVAL; bp->b_flags |= B_ERROR; @@ -427,34 +429,37 @@ MCD_TRACE("strategy: drive not valid\n"); goto done; /* for non raw access, check partition limits */ - if (mcd_part(bp->b_dev) != RAW_PART) { + if (mcd_part(dev) != RAW_PART) { if (!(cd->flags & MCDLABEL)) { bp->b_error = EIO; goto bad; } /* adjust transfer if necessary */ - if (bounds_check_with_label(bp,&cd->dlabel,1) <= 0) { + nbio = bounds_check_with_label(dev, bio, &cd->dlabel, 1); + if (nbio == NULL) goto done; - } } else { - bp->b_pblkno = bp->b_blkno; + nbio = bio; bp->b_resid = 0; } /* queue it */ crit_enter(); - bufqdisksort(&cd->head, bp); + bioqdisksort(&cd->bio_queue, nbio); crit_exit(); /* now check whether we can perform processing */ mcd_start(unit); return; + /* + * These cases occur before nbio is set, use bio. + */ bad: bp->b_flags |= B_ERROR; done: bp->b_resid = bp->b_bcount; - biodone(bp); + biodone(bio); return; } @@ -462,7 +467,9 @@ static void mcd_start(int unit) { struct mcd_data *cd = mcd_data + unit; struct partition *p; + struct bio *bio; struct buf *bp; + dev_t dev; crit_enter(); if (cd->flags & MCDMBXBSY) { @@ -470,17 +477,19 @@ static void mcd_start(int unit) return; } - bp = bufq_first(&cd->head); - if (bp != 0) { - /* block found to process, dequeue */ - /*MCD_TRACE("mcd_start: found block bp=0x%x\n",bp,0,0,0);*/ - bufq_remove(&cd->head, bp); - crit_exit(); - } else { + bio = bioq_first(&cd->bio_queue); + if (bio == NULL) { /* nothing to do */ crit_exit(); return; } + bp = bio->bio_buf; + dev = bio->bio_driver_info; + + /* block found to process, dequeue */ + /*MCD_TRACE("mcd_start: found block bp=0x%x\n",bp,0,0,0);*/ + bioq_remove(&cd->bio_queue, bio); + crit_exit(); /* changed media? */ if (!(cd->flags & MCDVALID)) { @@ -488,15 +497,15 @@ static void mcd_start(int unit) return; } - p = cd->dlabel.d_partitions + mcd_part(bp->b_dev); + p = cd->dlabel.d_partitions + mcd_part(dev); cd->flags |= MCDMBXBSY; - if (cd->partflags[mcd_part(bp->b_dev)] & MCDREADRAW) + if (cd->partflags[mcd_part(dev)] & MCDREADRAW) cd->flags |= MCDREADRAW; cd->mbx.unit = unit; cd->mbx.port = cd->iobase; cd->mbx.retry = MCD_RETRYS; - cd->mbx.bp = bp; + cd->mbx.bio = bio; cd->mbx.p_offset = p->p_offset; /* calling the read routine */ @@ -991,7 +1000,8 @@ mcd_doread(int state, struct mcd_mbx *mbxin) int port = mbx->port; int com_port = mbx->port + mcd_command; int data_port = mbx->port + mcd_rdata; - struct buf *bp = mbx->bp; + struct bio *bio = mbx->bio; + struct buf *bp = bio->bio_buf; struct mcd_data *cd = mcd_data + unit; int rm,i,k; @@ -1089,7 +1099,7 @@ modedone: mbx->skip = 0; nextblock: - blknum = (bp->b_blkno / (mbx->sz/DEV_BSIZE)) + blknum = (bio->bio_blkno / (mbx->sz/DEV_BSIZE)) + mbx->p_offset + mbx->skip/mbx->sz; MCD_TRACE("mcd_doread: read blknum=%d for bp=%p\n", @@ -1153,7 +1163,7 @@ retry_read: /* return buffer */ bp->b_resid = 0; - biodone(bp); + biodone(bio); cd->flags &= ~(MCDMBXBSY|MCDREADRAW); mcd_start(mbx->unit); @@ -1185,7 +1195,7 @@ harderr: /* invalidate the buffer */ bp->b_flags |= B_ERROR; bp->b_resid = bp->b_bcount; - biodone(bp); + biodone(bio); cd->flags &= ~(MCDMBXBSY|MCDREADRAW); mcd_start(mbx->unit); diff --git a/sys/dev/disk/md/md.c b/sys/dev/disk/md/md.c index 737787dbf3..64a938ec78 100644 --- a/sys/dev/disk/md/md.c +++ b/sys/dev/disk/md/md.c @@ -7,7 +7,7 @@ * ---------------------------------------------------------------------------- * * $FreeBSD: src/sys/dev/md/md.c,v 1.8.2.2 2002/08/19 17:43:34 jdp Exp $ - * $DragonFly: src/sys/dev/disk/md/md.c,v 1.8 2005/06/06 22:51:54 corecode Exp $ + * $DragonFly: src/sys/dev/disk/md/md.c,v 1.9 2006/02/17 19:18:00 dillon Exp $ * */ @@ -88,7 +88,7 @@ static struct cdevsw md_cdevsw = { struct md_s { int unit; struct devstat stats; - struct buf_queue_head buf_queue; + struct bio_queue_head bio_queue; struct disk disk; dev_t dev; int busy; @@ -143,44 +143,46 @@ mdioctl(dev_t dev, u_long cmd, caddr_t addr, int flags, struct thread *td) } static void -mdstrategy(struct buf *bp) +mdstrategy(dev_t dev, struct bio *bio) { + struct buf *bp = bio->bio_buf; struct md_s *sc; - if (md_debug > 1) + if (md_debug > 1) { printf("mdstrategy(%p) %s %lx, %d, %ld, %p)\n", - bp, devtoname(bp->b_dev), bp->b_flags, bp->b_blkno, + bp, devtoname(dev), bp->b_flags, bio->bio_blkno, bp->b_bcount / DEV_BSIZE, bp->b_data); - - sc = bp->b_dev->si_drv1; + } + bio->bio_driver_info = dev; + sc = dev->si_drv1; if (sc->type == MD_MALLOC) { - mdstrategy_malloc(bp); + mdstrategy_malloc(dev, bio); } else { - mdstrategy_preload(bp); + mdstrategy_preload(dev, bio); } - return; } static void -mdstrategy_malloc(struct buf *bp) +mdstrategy_malloc(dev_t dev, struct bio *bio) { - int i; - struct md_s *sc; - devstat_trans_flags dop; - u_char *secp, **secpp, *dst; + struct buf *bp = bio->bio_buf; unsigned secno, nsec, secval, uc; + u_char *secp, **secpp, *dst; + devstat_trans_flags dop; + struct md_s *sc; + int i; if (md_debug > 1) printf("mdstrategy_malloc(%p) %s %lx, %d, %ld, %p)\n", - bp, devtoname(bp->b_dev), bp->b_flags, bp->b_blkno, + bp, devtoname(dev), bp->b_flags, bio->bio_blkno, bp->b_bcount / DEV_BSIZE, bp->b_data); - sc = bp->b_dev->si_drv1; + sc = dev->si_drv1; crit_enter(); - bufqdisksort(&sc->buf_queue, bp); + bioqdisksort(&sc->bio_queue, bio); if (sc->busy) { crit_exit(); @@ -190,11 +192,11 @@ mdstrategy_malloc(struct buf *bp) sc->busy++; while (1) { - bp = bufq_first(&sc->buf_queue); + bio = bioq_first(&sc->bio_queue); if (bp) - bufq_remove(&sc->buf_queue, bp); + bioq_remove(&sc->bio_queue, bio); crit_exit(); - if (!bp) + if (bio == NULL) break; devstat_start_transaction(&sc->stats); @@ -207,10 +209,9 @@ mdstrategy_malloc(struct buf *bp) dop = DEVSTAT_WRITE; nsec = bp->b_bcount / DEV_BSIZE; - secno = bp->b_pblkno; + secno = bio->bio_blkno; dst = bp->b_data; while (nsec--) { - if (secno < sc->nsecp) { secpp = &sc->secp[secno]; if ((u_int)*secpp > 255) { @@ -281,30 +282,30 @@ mdstrategy_malloc(struct buf *bp) } bp->b_resid = 0; devstat_end_transaction_buf(&sc->stats, bp); - biodone(bp); + biodone(bio); crit_enter(); } sc->busy = 0; - return; } static void -mdstrategy_preload(struct buf *bp) +mdstrategy_preload(dev_t dev, struct bio *bio) { - struct md_s *sc; + struct buf *bp = bio->bio_buf; devstat_trans_flags dop; + struct md_s *sc; if (md_debug > 1) printf("mdstrategy_preload(%p) %s %lx, %d, %ld, %p)\n", - bp, devtoname(bp->b_dev), bp->b_flags, bp->b_blkno, + bp, devtoname(dev), bp->b_flags, bio->bio_blkno, bp->b_bcount / DEV_BSIZE, bp->b_data); - sc = bp->b_dev->si_drv1; + sc = dev->si_drv1; crit_enter(); - bufqdisksort(&sc->buf_queue, bp); + bioqdisksort(&sc->bio_queue, bio); if (sc->busy) { crit_exit(); @@ -314,11 +315,11 @@ mdstrategy_preload(struct buf *bp) sc->busy++; while (1) { - bp = bufq_first(&sc->buf_queue); - if (bp) - bufq_remove(&sc->buf_queue, bp); + bio = bioq_first(&sc->bio_queue); + if (bio) + bioq_remove(&sc->bio_queue, bio); crit_exit(); - if (!bp) + if (bio == NULL) break; devstat_start_transaction(&sc->stats); @@ -327,18 +328,17 @@ mdstrategy_preload(struct buf *bp) dop = DEVSTAT_NO_DATA; } else if (bp->b_flags & B_READ) { dop = DEVSTAT_READ; - bcopy(sc->pl_ptr + (bp->b_pblkno << DEV_BSHIFT), bp->b_data, bp->b_bcount); + bcopy(sc->pl_ptr + (bio->bio_blkno << DEV_BSHIFT), bp->b_data, bp->b_bcount); } else { dop = DEVSTAT_WRITE; - bcopy(bp->b_data, sc->pl_ptr + (bp->b_pblkno << DEV_BSHIFT), bp->b_bcount); + bcopy(bp->b_data, sc->pl_ptr + (bio->bio_blkno << DEV_BSHIFT), bp->b_bcount); } bp->b_resid = 0; devstat_end_transaction_buf(&sc->stats, bp); - biodone(bp); + biodone(bio); crit_enter(); } sc->busy = 0; - return; } static struct md_s * @@ -349,7 +349,7 @@ mdcreate(void) MALLOC(sc, struct md_s *,sizeof(*sc), M_MD, M_WAITOK); bzero(sc, sizeof(*sc)); sc->unit = mdunits++; - bufq_init(&sc->buf_queue); + bioq_init(&sc->bio_queue); devstat_add_entry(&sc->stats, "md", sc->unit, DEV_BSIZE, DEVSTAT_NO_ORDERED_TAGS, DEVSTAT_TYPE_DIRECT | DEVSTAT_TYPE_IF_OTHER, diff --git a/sys/dev/disk/scd/scd.c b/sys/dev/disk/scd/scd.c index 7e4cbbdf67..c2920df259 100644 --- a/sys/dev/disk/scd/scd.c +++ b/sys/dev/disk/scd/scd.c @@ -42,7 +42,7 @@ /* $FreeBSD: src/sys/i386/isa/scd.c,v 1.54 2000/01/29 16:00:30 peter Exp $ */ -/* $DragonFly: src/sys/dev/disk/scd/Attic/scd.c,v 1.13 2005/06/06 21:48:16 eirikn Exp $ */ +/* $DragonFly: src/sys/dev/disk/scd/Attic/scd.c,v 1.14 2006/02/17 19:18:01 dillon Exp $ */ /* Please send any comments to micke@dynas.se */ @@ -107,7 +107,7 @@ struct scd_mbx { short nblk; int sz; u_long skip; - struct buf *bp; + struct bio *bio; int p_offset; short count; }; @@ -131,7 +131,7 @@ static struct scd_data { struct ioc_play_msf last_play; short audio_status; - struct buf_queue_head head; /* head of buf queue */ + struct bio_queue_head bio_queue; /* head of bio queue */ struct scd_mbx mbx; struct callout callout; } scd_data[NSCD]; @@ -217,7 +217,7 @@ scd_attach(struct isa_device *dev) cd->flags = SCDINIT; cd->audio_status = CD_AS_AUDIO_INVALID; - bufq_init(&cd->head); + bioq_init(&cd->bio_queue); cdevsw_add(&scd_cdevsw, dkunitmask(), dkmakeunit(unit)); make_dev(&scd_cdevsw, dkmakeminor(unit, 0, 0), @@ -315,19 +315,21 @@ scdclose(dev_t dev, int flags, int fmt, struct thread *td) } static void -scdstrategy(struct buf *bp) +scdstrategy(dev_t dev, struct bio *bio) { + struct buf *bp = bio->bio_buf; + struct bio *nbio; struct scd_data *cd; - int unit = scd_unit(bp->b_dev); + int unit = scd_unit(dev); cd = scd_data + unit; XDEBUG(2, ("scd%d: DEBUG: strategy: block=%ld, bcount=%ld\n", - unit, (long)bp->b_blkno, bp->b_bcount)); + unit, (long)bio->bio_blkno, bp->b_bcount)); - if (unit >= NSCD || bp->b_blkno < 0 || (bp->b_bcount % SCDBLKSIZE)) { + if (unit >= NSCD || bio->bio_blkno < 0 || (bp->b_bcount % SCDBLKSIZE)) { printf("scd%d: strategy failure: blkno = %ld, bcount = %ld\n", - unit, (long)bp->b_blkno, bp->b_bcount); + unit, (long)bio->bio_blkno, bp->b_bcount); bp->b_error = EINVAL; bp->b_flags |= B_ERROR; goto bad; @@ -355,15 +357,16 @@ scdstrategy(struct buf *bp) goto bad; } /* adjust transfer if necessary */ - if (bounds_check_with_label(bp,&cd->dlabel,1) <= 0) + nbio = bounds_check_with_label(dev, bio, &cd->dlabel, 1); + if (nbio == NULL) goto done; - bp->b_pblkno = bp->b_blkno; + nbio->bio_driver_info = dev; bp->b_resid = 0; /* queue it */ crit_enter(); - bufqdisksort(&cd->head, bp); + bioqdisksort(&cd->bio_queue, nbio); crit_exit(); /* now check whether we can perform processing */ @@ -374,16 +377,16 @@ bad: bp->b_flags |= B_ERROR; done: bp->b_resid = bp->b_bcount; - biodone(bp); - return; + biodone(bio); } static void scd_start(int unit) { struct scd_data *cd = scd_data + unit; - struct buf *bp; + struct bio *bio; struct partition *p; + dev_t dev; crit_enter(); if (cd->flags & SCDMBXBSY) { @@ -391,23 +394,23 @@ scd_start(int unit) return; } - bp = bufq_first(&cd->head); - if (bp != 0) { - /* block found to process, dequeue */ - bufq_remove(&cd->head, bp); - cd->flags |= SCDMBXBSY; - } else { + bio = bioq_first(&cd->bio_queue); + if (bio == NULL) { /* nothing to do */ crit_exit(); return; } + /* block found to process, dequeue */ + bioq_remove(&cd->bio_queue, bio); + cd->flags |= SCDMBXBSY; + dev = bio->bio_driver_info; - p = cd->dlabel.d_partitions + scd_part(bp->b_dev); + p = cd->dlabel.d_partitions + scd_part(dev); cd->mbx.unit = unit; cd->mbx.port = cd->iobase; cd->mbx.retry = 3; - cd->mbx.bp = bp; + cd->mbx.bio = bio; cd->mbx.p_offset = p->p_offset; crit_exit(); @@ -792,7 +795,8 @@ scd_doread(int state, struct scd_mbx *mbxin) struct scd_mbx *mbx = (state!=SCD_S_BEGIN) ? mbxsave : mbxin; int unit = mbx->unit; int port = mbx->port; - struct buf *bp = mbx->bp; + struct bio *bio = mbx->bio; + struct buf *bp = bio->bio_buf; struct scd_data *cd = scd_data + unit; int reg,i; int blknum; @@ -843,7 +847,7 @@ nextblock: if (!(cd->flags & SCDVALID)) goto changed; - blknum = (bp->b_blkno / (mbx->sz/DEV_BSIZE)) + blknum = (bio->bio_blkno / (mbx->sz/DEV_BSIZE)) + mbx->p_offset + mbx->skip/mbx->sz; XDEBUG(2, ("scd%d: scd_doread: read blknum=%d\n", unit, blknum)); @@ -1026,7 +1030,7 @@ got_param: /* return buffer */ bp->b_resid = 0; - biodone(bp); + biodone(bio); cd->flags &= ~SCDMBXBSY; scd_start(mbx->unit); @@ -1044,7 +1048,7 @@ harderr: bp->b_error = EIO; bp->b_flags |= B_ERROR; bp->b_resid = bp->b_bcount; - biodone(bp); + biodone(bio); cd->flags &= ~SCDMBXBSY; scd_start(mbx->unit); diff --git a/sys/dev/disk/vn/vn.c b/sys/dev/disk/vn/vn.c index a9ba6f9388..7a55443365 100644 --- a/sys/dev/disk/vn/vn.c +++ b/sys/dev/disk/vn/vn.c @@ -39,7 +39,7 @@ * * from: @(#)vn.c 8.6 (Berkeley) 4/1/94 * $FreeBSD: src/sys/dev/vn/vn.c,v 1.105.2.4 2001/11/18 07:11:00 dillon Exp $ - * $DragonFly: src/sys/dev/disk/vn/vn.c,v 1.15 2005/12/11 01:54:08 swildner Exp $ + * $DragonFly: src/sys/dev/disk/vn/vn.c,v 1.16 2006/02/17 19:18:02 dillon Exp $ */ /* @@ -123,12 +123,6 @@ static struct cdevsw vn_cdevsw = { /* psize */ vnsize }; -#define getvnbuf() \ - ((struct buf *)malloc(sizeof(struct buf), M_DEVBUF, M_WAITOK)) - -#define putvnbuf(bp) \ - free((caddr_t)(bp), M_DEVBUF) - struct vn_softc { int sc_unit; int sc_flags; /* flags */ @@ -285,20 +279,24 @@ vnopen(dev_t dev, int flags, int mode, struct thread *td) * * Currently B_ASYNC is only partially handled - for OBJT_SWAP I/O only. * - * NOTE: bp->b_blkno is DEV_BSIZE'd. We must generate bp->b_pblkno for - * our uio or vn_pager_strategy() call that is vn->sc_secsize'd + * NOTE: bio->bio_blkno is DEV_BSIZE'd. We must generate a new bio + * with a secsize'd blkno. */ static void -vnstrategy(struct buf *bp) +vnstrategy(dev_t dev, struct bio *bio) { + struct buf *bp; + struct bio *nbio; int unit; struct vn_softc *vn; int error; - unit = dkunit(bp->b_dev); - if ((vn = bp->b_dev->si_drv1) == NULL) - vn = vnfindvn(bp->b_dev); + unit = dkunit(dev); + if ((vn = dev->si_drv1) == NULL) + vn = vnfindvn(dev); + + bp = bio->bio_buf; IFOPT(vn, VN_DEBUG) printf("vnstrategy(%p): unit %d\n", bp, unit); @@ -306,7 +304,7 @@ vnstrategy(struct buf *bp) if ((vn->sc_flags & VNF_INITED) == 0) { bp->b_error = ENXIO; bp->b_flags |= B_ERROR; - biodone(bp); + biodone(bio); return; } @@ -320,9 +318,11 @@ vnstrategy(struct buf *bp) * slices that exist ON the vnode device itself, and * translate the "slice-relative" block number, again. */ - if (vn->sc_slices != NULL && dscheck(bp, vn->sc_slices) <= 0) { + if (vn->sc_slices == NULL) { + nbio = bio; + } else if ((nbio = dscheck(dev, bio, vn->sc_slices)) == NULL) { bp->b_flags |= B_INVAL; - biodone(bp); + biodone(bio); return; } } else { @@ -334,14 +334,14 @@ vnstrategy(struct buf *bp) * multiple of the sector size. */ if (bp->b_bcount % vn->sc_secsize != 0 || - bp->b_blkno % (vn->sc_secsize / DEV_BSIZE) != 0) { + bio->bio_blkno % (vn->sc_secsize / DEV_BSIZE) != 0) { bp->b_error = EINVAL; bp->b_flags |= B_ERROR | B_INVAL; - biodone(bp); + biodone(bio); return; } - pbn = bp->b_blkno / (vn->sc_secsize / DEV_BSIZE); + pbn = bio->bio_blkno / (vn->sc_secsize / DEV_BSIZE); sz = howmany(bp->b_bcount, vn->sc_secsize); /* @@ -353,7 +353,7 @@ vnstrategy(struct buf *bp) bp->b_error = EINVAL; bp->b_flags |= B_ERROR | B_INVAL; } - biodone(bp); + biodone(bio); return; } @@ -364,14 +364,18 @@ vnstrategy(struct buf *bp) bp->b_bcount = (vn->sc_size - pbn) * vn->sc_secsize; bp->b_resid = bp->b_bcount; } - bp->b_pblkno = pbn; + nbio = push_bio(bio); + nbio->bio_blkno = pbn; } + /* + * Use the translated nbio from this point on + */ if (vn->sc_vp && (bp->b_flags & B_FREEBUF)) { /* * Not handled for vnode-backed element yet. */ - biodone(bp); + biodone(nbio); } else if (vn->sc_vp) { /* * VNODE I/O @@ -389,9 +393,9 @@ vnstrategy(struct buf *bp) aiov.iov_len = bp->b_bcount; auio.uio_iov = &aiov; auio.uio_iovcnt = 1; - auio.uio_offset = (vm_ooffset_t)bp->b_pblkno * vn->sc_secsize; + auio.uio_offset = (vm_ooffset_t)nbio->bio_blkno * vn->sc_secsize; auio.uio_segflg = UIO_SYSSPACE; - if( bp->b_flags & B_READ) + if (bp->b_flags & B_READ) auio.uio_rw = UIO_READ; else auio.uio_rw = UIO_WRITE; @@ -409,7 +413,7 @@ vnstrategy(struct buf *bp) bp->b_error = error; bp->b_flags |= B_ERROR; } - biodone(bp); + biodone(nbio); } else if (vn->sc_object) { /* * OBJT_SWAP I/O @@ -422,14 +426,14 @@ vnstrategy(struct buf *bp) ("vnstrategy: buffer %p too small for physio", bp)); if ((bp->b_flags & B_FREEBUF) && TESTOPT(vn, VN_RESERVE)) { - biodone(bp); + biodone(nbio); } else { - vm_pager_strategy(vn->sc_object, bp); + vm_pager_strategy(vn->sc_object, nbio); } } else { bp->b_flags |= B_ERROR; bp->b_error = EINVAL; - biodone(bp); + biodone(nbio); } } diff --git a/sys/dev/disk/wt/wt.c b/sys/dev/disk/wt/wt.c index a9f6f9d34c..ed433a4fbd 100644 --- a/sys/dev/disk/wt/wt.c +++ b/sys/dev/disk/wt/wt.c @@ -21,7 +21,7 @@ * * Version 1.3, Thu Nov 11 12:09:13 MSK 1993 * $FreeBSD: src/sys/i386/isa/wt.c,v 1.57.2.1 2000/08/08 19:49:53 peter Exp $ - * $DragonFly: src/sys/dev/disk/wt/wt.c,v 1.12 2005/10/13 08:50:33 sephe Exp $ + * $DragonFly: src/sys/dev/disk/wt/wt.c,v 1.13 2006/02/17 19:18:05 dillon Exp $ * */ @@ -507,9 +507,10 @@ wtioctl (dev_t dev, u_long cmd, caddr_t arg, int flags, struct thread *td) * Strategy routine. */ static void -wtstrategy (struct buf *bp) +wtstrategy (dev_t dev, struct bio *bio) { - int u = minor (bp->b_dev) & T_UNIT; + struct buf *bp = bio->bio_buf; + int u = minor(dev) & T_UNIT; wtinfo_t *t = wttab + u; bp->b_resid = bp->b_bcount; @@ -576,7 +577,7 @@ wtstrategy (struct buf *bp) errxit: bp->b_error = EIO; err2xit: bp->b_flags |= B_ERROR; } -xit: biodone (bp); +xit: biodone (bio); return; } diff --git a/sys/dev/misc/labpc/labpc.c b/sys/dev/misc/labpc/labpc.c index 61492bddd2..1e93d69ddd 100644 --- a/sys/dev/misc/labpc/labpc.c +++ b/sys/dev/misc/labpc/labpc.c @@ -39,7 +39,7 @@ * dufault@hda.com * * $FreeBSD: src/sys/i386/isa/labpc.c,v 1.35 1999/09/25 18:24:08 phk Exp $ - * $DragonFly: src/sys/dev/misc/labpc/labpc.c,v 1.14 2005/10/13 08:50:33 sephe Exp $ + * $DragonFly: src/sys/dev/misc/labpc/labpc.c,v 1.15 2006/02/17 19:18:05 dillon Exp $ * */ @@ -52,7 +52,7 @@ #include #include #include -#define b_actf b_act.tqe_next +#define bio_actf bio_act.tqe_next #include #include #include @@ -124,8 +124,9 @@ struct ctlr u_short sample_us; - struct buf start_queue; /* Start queue */ - struct buf *last; /* End of start queue */ + struct bio start_queue; /* Start queue */ + struct bio *last; /* End of start queue */ + int count; u_char *data; u_char *data_end; long tmo; /* Timeout in Hertz */ @@ -312,29 +313,28 @@ static void labpcintr(void *); static void start(struct ctlr *ctlr); static void -bp_done(struct buf *bp, int err) +bp_done(struct bio *bio, int err) { - bp->b_error = err; + struct buf *bp = bio->bio_buf; if (err || bp->b_resid) - { bp->b_flags |= B_ERROR; - } - - biodone(bp); + biodone(bio); } static void tmo_stop(void *p); static void -done_and_start_next(struct ctlr *ctlr, struct buf *bp, int err) +done_and_start_next(struct ctlr *ctlr, struct bio *bio, int err) { + struct buf *bp = bio->bio_buf; + bp->b_resid = ctlr->data_end - ctlr->data; ctlr->data = 0; - ctlr->start_queue.b_actf = bp->b_actf; - bp_done(bp, err); + ctlr->start_queue.bio_actf = bio->bio_actf; + bp_done(bio, err); callout_stop(&ctlr->ch); @@ -592,7 +592,7 @@ static void tmo_stop(void *p) { struct ctlr *ctlr = (struct ctlr *)p; - struct buf *bp; + struct bio *bio; crit_enter(); @@ -607,9 +607,9 @@ tmo_stop(void *p) (*ctlr->stop)(ctlr); - bp = ctlr->start_queue.b_actf; + bio = ctlr->start_queue.bio_actf; - if (bp == 0) { + if (bio == NULL) { printf(", Null bp.\n"); crit_exit(); return; @@ -617,7 +617,7 @@ tmo_stop(void *p) printf("\n"); - done_and_start_next(ctlr, bp, ETIMEDOUT); + done_and_start_next(ctlr, bio, ETIMEDOUT); crit_exit(); } @@ -643,10 +643,10 @@ static void ad_intr(struct ctlr *ctlr) { if ((status & (OVERRUN|OVERFLOW))) { - struct buf *bp = ctlr->start_queue.b_actf; + struct bio *bio = ctlr->start_queue.bio_actf; printf("ad_intr: error: bp %p, data %p, status %x", - (void *)bp, (void *)ctlr->data, status); + bio->bio_buf, ctlr->data, status); if (status & OVERRUN) printf(" Conversion overrun (multiple A-D trigger)"); @@ -656,13 +656,10 @@ static void ad_intr(struct ctlr *ctlr) printf("\n"); - if (bp) - { - done_and_start_next(ctlr, bp, EIO); + if (bio) { + done_and_start_next(ctlr, bio, EIO); return; - } - else - { + } else { printf("ad_intr: (should not happen) error between records\n"); ctlr->err = status; /* Set overrun condition */ return; @@ -670,25 +667,22 @@ static void ad_intr(struct ctlr *ctlr) } else /* FIFO interrupt */ { - struct buf *bp = ctlr->start_queue.b_actf; + struct bio *bio = ctlr->start_queue.bio_actf; - if (ctlr->data) - { + if (ctlr->data) { *ctlr->data++ = inb(ADFIFO(ctlr)); - if (ctlr->data == ctlr->data_end) /* Normal completion */ - { - done_and_start_next(ctlr, bp, 0); + if (ctlr->data == ctlr->data_end) { + /* Normal completion */ + done_and_start_next(ctlr, bio, 0); return; } - } - else /* Interrupt with no where to put the data. */ - { + } else { + /* Interrupt with no where to put the data. */ printf("ad_intr: (should not happen) dropped input.\n"); (void)inb(ADFIFO(ctlr)); printf("bp %p, status %x, cr3 %x\n", - (void *)bp, status, ctlr->cr_image[2]); - + bio->bio_buf, status, ctlr->cr_image[2]); ctlr->err = DROPPED_INPUT; return; } @@ -770,19 +764,20 @@ labpcclose(dev_t dev, int flags, int fmt, struct thread *td) static void start(struct ctlr *ctlr) { + struct bio *bio; struct buf *bp; - if ((bp = ctlr->start_queue.b_actf) == 0) - { + if ((bio = ctlr->start_queue.bio_actf) == NULL) { /* We must turn off FIFO interrupts when there is no * place to put the data. We have to get back to * reading before the FIFO overflows. */ CR_EXPR(ctlr, 3, &= ~(FIFOINTEN|ERRINTEN)); ctlr->cleared_intr = 1; - ctlr->start_queue.b_bcount = 0; + ctlr->count = 0; return; } + bp = bio->bio_buf; ctlr->data = (u_char *)bp->b_data; ctlr->data_end = ctlr->data + bp->b_bcount; @@ -790,18 +785,17 @@ start(struct ctlr *ctlr) if (ctlr->err) { printf("labpc start: (should not happen) error between records.\n"); - done_and_start_next(ctlr, bp, EIO); + done_and_start_next(ctlr, bio, EIO); return; } if (ctlr->data == 0) { printf("labpc start: (should not happen) NULL data pointer.\n"); - done_and_start_next(ctlr, bp, EIO); + done_and_start_next(ctlr, bio, EIO); return; } - (*ctlr->starter)(ctlr, bp->b_bcount); if (!FIFOINTENABLED(ctlr)) /* We can store the data again */ @@ -817,21 +811,18 @@ start(struct ctlr *ctlr) } static void -ad_strategy(struct buf *bp, struct ctlr *ctlr) +ad_strategy(struct bio *bio, struct ctlr *ctlr) { crit_enter(); - bp->b_actf = NULL; - - if (ctlr->start_queue.b_bcount) - { - ctlr->last->b_actf = bp; - ctlr->last = bp; - } - else - { - ctlr->start_queue.b_bcount = 1; - ctlr->start_queue.b_actf = bp; - ctlr->last = bp; + bio->bio_actf = NULL; + + if (ctlr->count) { + ctlr->last->bio_actf = bio; + ctlr->last = bio; + } else { + ctlr->count = 1; + ctlr->start_queue.bio_actf = bio; + ctlr->last = bio; start(ctlr); } crit_exit(); @@ -850,14 +841,16 @@ ad_strategy(struct buf *bp, struct ctlr *ctlr) * 2. No interrupt support yet. */ static void -da_strategy(struct buf *bp, struct ctlr *ctlr) +da_strategy(struct bio *bio, struct ctlr *ctlr) { + struct buf *bp = bio->bio_buf; + dev_t dev = bio->bio_driver_info; int len; u_char *data; int port; int i; - switch(CHAN(bp->b_dev)) + switch(CHAN(dev)) { case 0: port = DAC0L(ctlr); @@ -886,18 +879,18 @@ da_strategy(struct buf *bp, struct ctlr *ctlr) } bp->b_resid = bp->b_bcount & 3; - bp_done(bp, 0); + bp_done(bio, 0); return; default: - bp_done(bp, ENXIO); + bp_done(bio, ENXIO); return; } /* Port 0 or 1 falls through to here. */ if (bp->b_bcount & 1) /* Odd transfers are illegal */ - bp_done(bp, EIO); + bp_done(bio, EIO); len = bp->b_bcount; data = (u_char *)bp->b_data; @@ -910,7 +903,7 @@ da_strategy(struct buf *bp, struct ctlr *ctlr) bp->b_resid = 0; - bp_done(bp, 0); + bp_done(bio, 0); } /* Input masks for MODE 0 of the ports treating PC as a single @@ -931,13 +924,15 @@ static void flush_dcr(struct ctlr *ctlr) /* do: Digital output */ static void -digital_out_strategy(struct buf *bp, struct ctlr *ctlr) +digital_out_strategy(struct bio *bio, struct ctlr *ctlr) { + struct buf *bp = bio->bio_buf; + dev_t dev = bio->bio_driver_info; int len; u_char *data; int port; int i; - int chan = CHAN(bp->b_dev); + int chan = CHAN(dev); ctlr->dcr_val &= ~set_input[chan]; /* Digital out: Clear bit */ flush_dcr(ctlr); @@ -954,19 +949,21 @@ digital_out_strategy(struct buf *bp, struct ctlr *ctlr) bp->b_resid = 0; - bp_done(bp, 0); + bp_done(bio, 0); } /* digital_in_strategy: Digital input */ static void -digital_in_strategy(struct buf *bp, struct ctlr *ctlr) +digital_in_strategy(struct bio *bio, struct ctlr *ctlr) { + struct buf *bp = bio->bio_buf; + dev_t dev = bio->bio_driver_info; int len; u_char *data; int port; int i; - int chan = CHAN(bp->b_dev); + int chan = CHAN(dev); ctlr->dcr_val |= set_input[chan]; /* Digital in: Set bit */ flush_dcr(ctlr); @@ -982,28 +979,31 @@ digital_in_strategy(struct buf *bp, struct ctlr *ctlr) bp->b_resid = 0; - bp_done(bp, 0); + bp_done(bio, 0); } static void -labpcstrategy(struct buf *bp) +labpcstrategy(dev_t dev, struct bio *bio) { - struct ctlr *ctlr = labpcs[UNIT(bp->b_dev)]; + struct buf *bp = bio->bio_buf; + struct ctlr *ctlr = labpcs[UNIT(dev)]; + + bio->bio_driver_info = dev; - if (DIGITAL(bp->b_dev)) { + if (DIGITAL(dev)) { if (bp->b_flags & B_READ) { ctlr->starter = null_start; ctlr->stop = all_stop; ctlr->intr = null_intr; - digital_in_strategy(bp, ctlr); + digital_in_strategy(bio, ctlr); } else { ctlr->starter = null_start; ctlr->stop = all_stop; ctlr->intr = null_intr; - digital_out_strategy(bp, ctlr); + digital_out_strategy(bio, ctlr); } } else { @@ -1012,14 +1012,14 @@ labpcstrategy(struct buf *bp) ctlr->starter = INTERVAL(ctlr->dev) ? ad_interval_start : ad_start; ctlr->stop = all_stop; ctlr->intr = ad_intr; - ad_strategy(bp, ctlr); + ad_strategy(bio, ctlr); } else { ctlr->starter = null_start; ctlr->stop = all_stop; ctlr->intr = null_intr; - da_strategy(bp, ctlr); + da_strategy(bio, ctlr); } } } diff --git a/sys/dev/netif/de/if_de.c b/sys/dev/netif/de/if_de.c index 938225d718..9b23c01adb 100644 --- a/sys/dev/netif/de/if_de.c +++ b/sys/dev/netif/de/if_de.c @@ -1,7 +1,7 @@ /* $NetBSD: if_de.c,v 1.86 1999/06/01 19:17:59 thorpej Exp $ */ /* $FreeBSD: src/sys/pci/if_de.c,v 1.123.2.4 2000/08/04 23:25:09 peter Exp $ */ -/* $DragonFly: src/sys/dev/netif/de/if_de.c,v 1.41 2005/11/28 17:13:42 dillon Exp $ */ +/* $DragonFly: src/sys/dev/netif/de/if_de.c,v 1.42 2006/02/17 19:18:05 dillon Exp $ */ /*- * Copyright (c) 1994-1997 Matt Thomas (matt@3am-software.com) @@ -129,11 +129,11 @@ tulip_timeout_callback(void *arg) { tulip_softc_t *sc = arg; - lwkt_serialize_enter(&sc->tulip_serializer); + lwkt_serialize_enter(sc->tulip_if.if_serializer); sc->tulip_flags &= ~TULIP_TIMEOUTPENDING; sc->tulip_probe_timeout -= 1000 / TULIP_HZ; (sc->tulip_boardsw->bd_media_poll)(sc, TULIP_MEDIAPOLL_TIMER); - lwkt_serialize_exit(&sc->tulip_serializer); + lwkt_serialize_exit(sc->tulip_if.if_serializer); } static void @@ -3944,6 +3944,13 @@ tulip_attach(tulip_softc_t *sc) ifp->if_snd.ifq_maxlen = ifqmaxlen; } +static void +tulip_detach(tulip_softc_t *sc) +{ + ifmedia_removeall(&sc->tulip_ifmedia); + ether_ifdetach(&sc->tulip_if); +} + static void tulip_initcsrs(tulip_softc_t *sc, tulip_csrptr_t csr_base, size_t csr_size) { @@ -4031,12 +4038,12 @@ tulip_shutdown(device_t dev) { tulip_softc_t *sc = device_get_softc(dev); - lwkt_serialize_enter(&sc->tulip_serializer); + lwkt_serialize_enter(sc->tulip_if.if_serializer); TULIP_CSR_WRITE(sc, csr_busmode, TULIP_BUSMODE_SWRESET); DELAY(10); /* Wait 10 microseconds (actually 50 PCI cycles but at 33MHz that comes to two microseconds but wait a bit longer anyways) */ - lwkt_serialize_exit(&sc->tulip_serializer); + lwkt_serialize_exit(sc->tulip_if.if_serializer); return 0; } @@ -4090,7 +4097,6 @@ tulip_pci_attach(device_t dev) } sc = device_get_softc(dev); - lwkt_serialize_init(&sc->tulip_serializer); sc->tulip_dev = dev; sc->tulip_pci_busno = pci_get_bus(dev); sc->tulip_pci_devno = pci_get_slot(dev); @@ -4156,7 +4162,6 @@ tulip_pci_attach(device_t dev) 33MHz that comes to two microseconds but wait a bit longer anyways) */ - lwkt_serialize_enter(&sc->tulip_serializer); if ((retval = tulip_read_macaddr(sc)) < 0) { device_printf(dev, "can't read ENET ROM (why=%d) (", retval); for (idx = 0; idx < 32; idx++) @@ -4172,6 +4177,7 @@ tulip_pci_attach(device_t dev) if (sc->tulip_features & TULIP_HAVE_SHAREDINTR) intr_rtn = tulip_intr_shared; + tulip_attach(sc); if ((sc->tulip_features & TULIP_HAVE_SLAVEDINTR) == 0) { void *ih; @@ -4180,16 +4186,14 @@ tulip_pci_attach(device_t dev) RF_SHAREABLE | RF_ACTIVE); if (res == 0 || bus_setup_intr(dev, res, INTR_NETSAFE, intr_rtn, sc, &ih, - &sc->tulip_serializer)) { - lwkt_serialize_exit(&sc->tulip_serializer); + sc->tulip_if.if_serializer)) { device_printf(dev, "couldn't map interrupt\n"); + tulip_detach(sc); free((caddr_t) sc->tulip_rxdescs, M_DEVBUF); free((caddr_t) sc->tulip_txdescs, M_DEVBUF); return ENXIO; } } - tulip_attach(sc); - lwkt_serialize_exit(&sc->tulip_serializer); } return 0; } diff --git a/sys/dev/netif/de/if_devar.h b/sys/dev/netif/de/if_devar.h index b4b4dbc4a8..d7af83d067 100644 --- a/sys/dev/netif/de/if_devar.h +++ b/sys/dev/netif/de/if_devar.h @@ -1,7 +1,7 @@ /* $NetBSD: if_devar.h,v 1.32 1999/04/01 14:55:25 tsubai Exp $ */ /* $FreeBSD: src/sys/pci/if_devar.h,v 1.23.2.1 2000/08/04 23:25:10 peter Exp $ */ -/* $DragonFly: src/sys/dev/netif/de/if_devar.h,v 1.14 2005/11/28 17:13:42 dillon Exp $ */ +/* $DragonFly: src/sys/dev/netif/de/if_devar.h,v 1.15 2006/02/17 19:18:05 dillon Exp $ */ /*- * Copyright (c) 1994-1997 Matt Thomas (matt@3am-software.com) @@ -432,7 +432,6 @@ struct _tulip_softc_t { struct ifmedia tulip_ifmedia; struct callout tulip_timer; struct callout tulip_fast_timer; - struct lwkt_serialize tulip_serializer; bus_space_tag_t tulip_csrs_bst; bus_space_handle_t tulip_csrs_bsh; tulip_regfile_t tulip_csrs; diff --git a/sys/dev/raid/aac/aac.c b/sys/dev/raid/aac/aac.c index 08af2151cd..f1eb7d702f 100644 --- a/sys/dev/raid/aac/aac.c +++ b/sys/dev/raid/aac/aac.c @@ -27,7 +27,7 @@ * SUCH DAMAGE. * * $FreeBSD: src/sys/dev/aac/aac.c,v 1.9.2.14 2003/04/08 13:22:08 scottl Exp $ - * $DragonFly: src/sys/dev/raid/aac/aac.c,v 1.19 2005/08/08 01:25:31 hmp Exp $ + * $DragonFly: src/sys/dev/raid/aac/aac.c,v 1.20 2006/02/17 19:18:05 dillon Exp $ */ /* @@ -877,18 +877,17 @@ aac_complete(void *context, int pending) * Handle a bio submitted from a disk device. */ void -aac_submit_bio(struct buf *bp) +aac_submit_bio(struct aac_disk *ad, struct bio *bio) { - struct aac_disk *ad; struct aac_softc *sc; debug_called(2); - ad = (struct aac_disk *)bp->b_dev->si_drv1; + bio->bio_driver_info = ad; sc = ad->ad_controller; /* queue the BIO and try to get some work done */ - aac_enqueue_bio(sc, bp); + aac_enqueue_bio(sc, bio); aac_startio(sc); } @@ -903,22 +902,24 @@ aac_bio_command(struct aac_softc *sc, struct aac_command **cmp) struct aac_blockread *br; struct aac_blockwrite *bw; struct aac_disk *ad; + struct bio *bio; struct buf *bp; debug_called(2); /* get the resources we will need */ cm = NULL; - if ((bp = aac_dequeue_bio(sc)) == NULL) + if ((bio = aac_dequeue_bio(sc)) == NULL) goto fail; if (aac_alloc_command(sc, &cm)) /* get a command */ goto fail; /* fill out the command */ + bp = bio->bio_buf; cm->cm_data = (void *)bp->b_data; cm->cm_datalen = bp->b_bcount; cm->cm_complete = aac_bio_complete; - cm->cm_private = bp; + cm->cm_private = bio; cm->cm_timestamp = time_second; cm->cm_queue = AAC_ADAP_NORM_CMD_QUEUE; @@ -937,12 +938,12 @@ aac_bio_command(struct aac_softc *sc, struct aac_command **cmp) fib->Header.Size = sizeof(struct aac_fib_header); /* build the read/write request */ - ad = (struct aac_disk *)bp->b_dev->si_drv1; - if (BIO_IS_READ(bp)) { + ad = (struct aac_disk *)bio->bio_driver_info; + if (bp->b_flags & B_READ) { br = (struct aac_blockread *)&fib->data[0]; br->Command = VM_CtBlockRead; br->ContainerId = ad->ad_container->co_mntobj.ObjectId; - br->BlockNumber = bp->b_pblkno; + br->BlockNumber = bio->bio_blkno; br->ByteCount = bp->b_bcount; fib->Header.Size += sizeof(struct aac_blockread); cm->cm_sgtable = &br->SgMap; @@ -951,7 +952,7 @@ aac_bio_command(struct aac_softc *sc, struct aac_command **cmp) bw = (struct aac_blockwrite *)&fib->data[0]; bw->Command = VM_CtBlockWrite; bw->ContainerId = ad->ad_container->co_mntobj.ObjectId; - bw->BlockNumber = bp->b_pblkno; + bw->BlockNumber = bio->bio_blkno; bw->ByteCount = bp->b_bcount; bw->Stable = CUNSTABLE; /* XXX what's appropriate here? */ fib->Header.Size += sizeof(struct aac_blockwrite); @@ -963,8 +964,8 @@ aac_bio_command(struct aac_softc *sc, struct aac_command **cmp) return(0); fail: - if (bp != NULL) - aac_enqueue_bio(sc, bp); + if (bio != NULL) + aac_enqueue_bio(sc, bio); if (cm != NULL) aac_release_command(cm); return(ENOMEM); @@ -978,12 +979,15 @@ aac_bio_complete(struct aac_command *cm) { struct aac_blockread_response *brr; struct aac_blockwrite_response *bwr; + struct bio *bio; struct buf *bp; + const char *code; AAC_FSAStatus status; /* fetch relevant status and then release the command */ - bp = (struct buf *)cm->cm_private; - if (BIO_IS_READ(bp)) { + bio = (struct bio *)cm->cm_private; + bp = bio->bio_buf; + if (bp->b_flags & B_READ) { brr = (struct aac_blockread_response *)&cm->cm_fib->data[0]; status = brr->Status; } else { @@ -995,14 +999,14 @@ aac_bio_complete(struct aac_command *cm) /* fix up the bio based on status */ if (status == ST_OK) { bp->b_resid = 0; + code = 0; } else { bp->b_error = EIO; bp->b_flags |= B_ERROR; /* pass an error string out to the disk layer */ - bp->b_driver1 = aac_describe_code(aac_command_status_table, - status); + code = aac_describe_code(aac_command_status_table, status); } - aac_biodone(bp); + aac_biodone(bio, code); } /* diff --git a/sys/dev/raid/aac/aac_compat.h b/sys/dev/raid/aac/aac_compat.h index 948d8e5b67..41601b11b2 100644 --- a/sys/dev/raid/aac/aac_compat.h +++ b/sys/dev/raid/aac/aac_compat.h @@ -25,7 +25,7 @@ * SUCH DAMAGE. * * $FreeBSD: src/sys/dev/aac/aac_compat.h,v 1.2.2.2 2001/09/19 19:09:11 scottl Exp $ - * $DragonFly: src/sys/dev/raid/aac/Attic/aac_compat.h,v 1.6 2005/08/08 01:25:31 hmp Exp $ + * $DragonFly: src/sys/dev/raid/aac/Attic/aac_compat.h,v 1.7 2006/02/17 19:18:05 dillon Exp $ */ /* * Backwards compatibility support. @@ -39,13 +39,11 @@ #include #include #include -#define bioq_init(x) bufq_init(x) -#define bioq_insert_tail(x, y) bufq_insert_tail(x, y) -#define bioq_remove(x, y) bufq_remove(x, y) -#define bioq_first(x) bufq_first(x) -#define bio_queue_head buf_queue_head + +#if 0 #define FREEBSD_4 #define BIO_ERROR B_ERROR #define devstat_end_transaction_bio(x, y) devstat_end_transaction_buf(x, y) #define BIO_IS_READ(x) ((x)->b_flags & B_READ) #endif +#endif diff --git a/sys/dev/raid/aac/aac_disk.c b/sys/dev/raid/aac/aac_disk.c index 93897bef45..b9548b7ede 100644 --- a/sys/dev/raid/aac/aac_disk.c +++ b/sys/dev/raid/aac/aac_disk.c @@ -27,7 +27,7 @@ * SUCH DAMAGE. * * $FreeBSD: src/sys/dev/aac/aac_disk.c,v 1.3.2.8 2003/01/11 18:39:39 scottl Exp $ - * $DragonFly: src/sys/dev/raid/aac/aac_disk.c,v 1.10 2005/08/08 01:25:31 hmp Exp $ + * $DragonFly: src/sys/dev/raid/aac/aac_disk.c,v 1.11 2006/02/17 19:18:05 dillon Exp $ */ #include "opt_aac.h" @@ -183,26 +183,27 @@ aac_disk_close(dev_t dev, int flags, int fmt, d_thread_t *td) * Handle an I/O request. */ static void -aac_disk_strategy(struct buf *bp) +aac_disk_strategy(dev_t dev, struct bio *bio) { + struct buf *bp = bio->bio_buf; struct aac_disk *sc; debug_called(4); - sc = (struct aac_disk *)bp->b_dev->si_drv1; + sc = (struct aac_disk *)dev->si_drv1; /* bogus disk? */ if (sc == NULL) { bp->b_flags |= B_ERROR; bp->b_error = EINVAL; - biodone(bp); + biodone(bio); return; } /* do-nothing operation? */ if (bp->b_bcount == 0) { bp->b_resid = bp->b_bcount; - biodone(bp); + biodone(bio); return; } @@ -210,8 +211,7 @@ aac_disk_strategy(struct buf *bp) devstat_start_transaction(&sc->ad_stats); /* pass the bio to the controller - it can work out who we are */ - aac_submit_bio(bp); - return; + aac_submit_bio(sc, bio); } /* @@ -294,27 +294,28 @@ retry: * Handle completion of an I/O request. */ void -aac_biodone(struct buf *bp) +aac_biodone(struct bio *bio, const char *code) { + struct buf *bp = bio->bio_buf; struct aac_disk *sc; int blkno; debug_called(4); - sc = (struct aac_disk *)bp->b_dev->si_drv1; + sc = (struct aac_disk *)bio->bio_driver_info; - devstat_end_transaction_bio(&sc->ad_stats, bp); - if (bp->b_flags & BIO_ERROR) { + devstat_end_transaction_buf(&sc->ad_stats, bp); + if (bp->b_flags & B_ERROR) { blkno = (sc->ad_label.d_nsectors) ? 0 : -1; #if defined(__FreeBSD__) && __FreeBSD_version > 500005 - diskerr(bp, bp->b_dev, - (char *)bp->bio_driver1, blkno, &sc->ad_label); + diskerr(bio, sc->ad_dev_t, + code, blkno, &sc->ad_label); #else - diskerr(bp, bp->b_dev, - (char *)bp->b_driver1, 0, blkno, &sc->ad_label); + diskerr(bio, sc->ad_dev_t, + code, 0, blkno, &sc->ad_label); #endif } - biodone(bp); + biodone(bio); } /* diff --git a/sys/dev/raid/aac/aacvar.h b/sys/dev/raid/aac/aacvar.h index e873ab7dc7..c98fdb0003 100644 --- a/sys/dev/raid/aac/aacvar.h +++ b/sys/dev/raid/aac/aacvar.h @@ -27,7 +27,7 @@ * SUCH DAMAGE. * * $FreeBSD: src/sys/dev/aac/aacvar.h,v 1.4.2.7 2003/04/08 13:22:08 scottl Exp $ - * $DragonFly: src/sys/dev/raid/aac/aacvar.h,v 1.10 2005/08/08 01:25:31 hmp Exp $ + * $DragonFly: src/sys/dev/raid/aac/aacvar.h,v 1.11 2006/02/17 19:18:05 dillon Exp $ */ #include @@ -330,7 +330,7 @@ struct aac_softc TAILQ_HEAD(,aac_command) aac_busy; TAILQ_HEAD(,aac_command) aac_complete; /* commands which have been * returned by the controller */ - struct buf_queue_head aac_bioq; + struct bio_queue_head aac_bioq; struct aac_queue_table *aac_queues; struct aac_queue_entry *aac_qentries[AAC_QUEUE_COUNT]; @@ -390,8 +390,8 @@ extern int aac_suspend(device_t dev); extern int aac_resume(device_t dev); extern void aac_intr(void *arg); extern devclass_t aac_devclass; -extern void aac_submit_bio(struct buf *bp); -extern void aac_biodone(struct buf *bp); +extern void aac_submit_bio(struct aac_disk *ad, struct bio *bio); +extern void aac_biodone(struct bio *bio, const char *code); extern int aac_dump_enqueue(struct aac_disk *ad, u_int32_t lba, void *data, int nblks); extern void aac_dump_complete(struct aac_softc *sc); @@ -557,26 +557,26 @@ aac_initq_bio(struct aac_softc *sc) } static __inline void -aac_enqueue_bio(struct aac_softc *sc, struct buf *bp) +aac_enqueue_bio(struct aac_softc *sc, struct bio *bio) { crit_enter(); - bioq_insert_tail(&sc->aac_bioq, bp); + bioq_insert_tail(&sc->aac_bioq, bio); AACQ_ADD(sc, AACQ_BIO); crit_exit(); } -static __inline struct buf * +static __inline struct bio * aac_dequeue_bio(struct aac_softc *sc) { - struct buf *bp; + struct bio *bio; crit_enter(); - if ((bp = bioq_first(&sc->aac_bioq)) != NULL) { - bioq_remove(&sc->aac_bioq, bp); + if ((bio = bioq_first(&sc->aac_bioq)) != NULL) { + bioq_remove(&sc->aac_bioq, bio); AACQ_REMOVE(sc, AACQ_BIO); } crit_exit(); - return(bp); + return(bio); } static __inline void diff --git a/sys/dev/raid/amr/amr.c b/sys/dev/raid/amr/amr.c index 1f2bf17565..236918b5dc 100644 --- a/sys/dev/raid/amr/amr.c +++ b/sys/dev/raid/amr/amr.c @@ -53,7 +53,7 @@ * SUCH DAMAGE. * * $FreeBSD: src/sys/dev/amr/amr.c,v 1.7.2.13 2003/01/15 13:41:18 emoore Exp $ - * $DragonFly: src/sys/dev/raid/amr/amr.c,v 1.15 2005/06/09 20:55:05 swildner Exp $ + * $DragonFly: src/sys/dev/raid/amr/amr.c,v 1.16 2006/02/17 19:18:05 dillon Exp $ */ /* @@ -838,8 +838,8 @@ amr_completeio(struct amr_command *ac) struct amr_softc *sc = ac->ac_sc; if (ac->ac_status != AMR_STATUS_SUCCESS) { /* could be more verbose here? */ - ac->ac_bio->bio_error = EIO; - ac->ac_bio->bio_flags |= BIO_ERROR; + ac->ac_bio->bio_buf->b_error = EIO; + ac->ac_bio->bio_buf->b_flags |= B_ERROR; device_printf(sc->amr_dev, "I/O error - 0x%x\n", ac->ac_status); /* amr_printcommand(ac);*/ @@ -884,28 +884,28 @@ amr_bio_command(struct amr_softc *sc, struct amr_command **acp) /* connect the bio to the command */ ac->ac_complete = amr_completeio; ac->ac_bio = bio; - ac->ac_data = bio->bio_data; - ac->ac_length = bio->bio_bcount; - if (BIO_IS_READ(bio)) { + ac->ac_data = bio->bio_buf->b_data; + ac->ac_length = bio->bio_buf->b_bcount; + if (bio->bio_buf->b_flags & B_READ) { ac->ac_flags |= AMR_CMD_DATAIN; cmd = AMR_CMD_LREAD; } else { ac->ac_flags |= AMR_CMD_DATAOUT; cmd = AMR_CMD_LWRITE; } - amrd = (struct amrd_softc *)bio->bio_dev->si_drv1; + amrd = (struct amrd_softc *)bio->bio_driver_info; driveno = amrd->amrd_drive - sc->amr_drive; - blkcount = (bio->bio_bcount + AMR_BLKSIZE - 1) / AMR_BLKSIZE; + blkcount = (bio->bio_buf->b_bcount + AMR_BLKSIZE - 1) / AMR_BLKSIZE; ac->ac_mailbox.mb_command = cmd; ac->ac_mailbox.mb_blkcount = blkcount; - ac->ac_mailbox.mb_lba = bio->bio_pblkno; + ac->ac_mailbox.mb_lba = bio->bio_blkno; ac->ac_mailbox.mb_drive = driveno; /* we fill in the s/g related data when the command is mapped */ - if ((bio->bio_pblkno + blkcount) > sc->amr_drive[driveno].al_size) + if ((bio->bio_blkno + blkcount) > sc->amr_drive[driveno].al_size) device_printf(sc->amr_dev, "I/O beyond end of unit (%lld,%d > %lu)\n", - (long long)bio->bio_pblkno, blkcount, + (long long)bio->bio_blkno, blkcount, (u_long)sc->amr_drive[driveno].al_size); out: diff --git a/sys/dev/raid/amr/amr_compat.h b/sys/dev/raid/amr/amr_compat.h index b04807495a..88e3f861a0 100644 --- a/sys/dev/raid/amr/amr_compat.h +++ b/sys/dev/raid/amr/amr_compat.h @@ -53,55 +53,13 @@ * SUCH DAMAGE. * * $FreeBSD: src/sys/dev/amr/amr_compat.h,v 1.2.2.4 2002/11/11 13:19:10 emoore Exp $ - * $DragonFly: src/sys/dev/raid/amr/amr_compat.h,v 1.6 2004/07/17 01:45:37 hmp Exp $ + * $DragonFly: src/sys/dev/raid/amr/amr_compat.h,v 1.7 2006/02/17 19:18:05 dillon Exp $ */ -/* - * Backwards compatibility support. - */ - -#if defined(__DragonFly__) || __FreeBSD_version < 500003 /* old buf style */ -# include -# include -# include -# include - -# define FREEBSD_4 -# define bio buf -# define bioq_init(x) bufq_init(x) -# define bioq_insert_tail(x, y) bufq_insert_tail(x, y) -# define bioq_remove(x, y) bufq_remove(x, y) -# define bioq_first(x) bufq_first(x) -# define bio_queue_head buf_queue_head -# define bio_bcount b_bcount -# define bio_blkno b_blkno -# define bio_caller1 b_caller1 -# define bio_data b_data -# define bio_dev b_dev -# define bio_driver1 b_driver1 -# define bio_error b_error -# define bio_flags b_flags -# define bio_pblkno b_pblkno -# define bio_resid b_resid -# define BIO_ERROR B_ERROR -# define devstat_end_transaction_bio(x, y) devstat_end_transaction_buf(x, y) -# define BIO_IS_READ(x) ((x)->b_flags & B_READ) -# define AMR_BIO_FINISH(x) devstat_end_transaction_bio(&sc->amrd_stats, x);\ - biodone(x) - -#else -# include -# define BIO_IS_READ(x) ((x)->bio_cmd == BIO_READ) -# define AMR_BIO_FINISH(x) biofinish(x, &sc->amrd_stats, 0) -#endif - -/************************************************************************ - * Compatibility with older versions of FreeBSD - */ -#if defined(__FreeBSD__) && __FreeBSD_version < 440001 -typedef struct proc d_thread_t; -#define M_ZERO 0x0008 /* bzero the allocation */ -#endif +#include +#include +#include +#include #ifndef __packed #define __packed __attribute__ ((packed)) diff --git a/sys/dev/raid/amr/amr_disk.c b/sys/dev/raid/amr/amr_disk.c index d494656ab3..1e99d7ef9a 100644 --- a/sys/dev/raid/amr/amr_disk.c +++ b/sys/dev/raid/amr/amr_disk.c @@ -54,7 +54,7 @@ * SUCH DAMAGE. * * $FreeBSD: src/sys/dev/amr/amr_disk.c,v 1.5.2.5 2002/12/20 15:12:04 emoore Exp $ - * $DragonFly: src/sys/dev/raid/amr/amr_disk.c,v 1.9 2004/05/19 22:52:46 dillon Exp $ + * $DragonFly: src/sys/dev/raid/amr/amr_disk.c,v 1.10 2006/02/17 19:18:05 dillon Exp $ */ /* @@ -252,47 +252,46 @@ amrd_dump(dev_t dev, u_int count, u_int blkno, u_int secsize) * be a multiple of a sector in length. */ static void -amrd_strategy(struct bio *bio) +amrd_strategy(dev_t dev, struct bio *bio) { - struct amrd_softc *sc = (struct amrd_softc *)bio->bio_dev->si_drv1; + struct buf *bp = bio->bio_buf; + struct amrd_softc *sc = (struct amrd_softc *)dev->si_drv1; /* bogus disk? */ if (sc == NULL) { - bio->bio_error = EINVAL; + bp->b_error = EINVAL; goto bad; } + bio->bio_driver_info = sc; devstat_start_transaction(&sc->amrd_stats); amr_submit_bio(sc->amrd_controller, bio); return; bad: - bio->bio_flags |= BIO_ERROR; + bp->b_flags |= B_ERROR; /* * Correctly set the buf to indicate a completed transfer */ - bio->bio_resid = bio->bio_bcount; + bp->b_resid = bp->b_bcount; biodone(bio); - return; } void -amrd_intr(void *data) +amrd_intr(struct bio *bio) { - struct bio *bio = (struct bio *)data; - struct amrd_softc *sc = (struct amrd_softc *)bio->bio_dev->si_drv1; + struct buf *bp = bio->bio_buf; debug_called(2); - if (bio->bio_flags & BIO_ERROR) { - bio->bio_error = EIO; + if (bp->b_flags & B_ERROR) { + bp->b_error = EIO; debug(1, "i/o error\n"); } else { - bio->bio_resid = 0; + bp->b_resid = 0; } - - AMR_BIO_FINISH(bio); + biodone(bio); } static int diff --git a/sys/dev/raid/amr/amrvar.h b/sys/dev/raid/amr/amrvar.h index c49e116fec..f4db4465ef 100644 --- a/sys/dev/raid/amr/amrvar.h +++ b/sys/dev/raid/amr/amrvar.h @@ -53,7 +53,7 @@ * SUCH DAMAGE. * * $FreeBSD: src/sys/dev/amr/amrvar.h,v 1.2.2.5 2002/12/20 15:12:04 emoore Exp $ - * $DragonFly: src/sys/dev/raid/amr/amrvar.h,v 1.6 2005/06/09 20:55:05 swildner Exp $ + * $DragonFly: src/sys/dev/raid/amr/amrvar.h,v 1.7 2006/02/17 19:18:05 dillon Exp $ */ #include @@ -266,7 +266,7 @@ struct amrd_softc * Interface between driver core and disk driver (should be using a bus?) */ extern int amr_submit_bio(struct amr_softc *sc, struct bio *bio); -extern void amrd_intr(void *data); +extern void amrd_intr(struct bio *bio); extern int amr_dump_blocks(struct amr_softc *sc, int unit, u_int32_t lba, void *data, int blks); /******************************************************************************** diff --git a/sys/dev/raid/ida/ida.c b/sys/dev/raid/ida/ida.c index 17695b8392..ef7e646225 100644 --- a/sys/dev/raid/ida/ida.c +++ b/sys/dev/raid/ida/ida.c @@ -28,7 +28,7 @@ * SUCH DAMAGE. * * $FreeBSD: src/sys/dev/ida/ida.c,v 1.7.2.3 2001/03/01 01:57:32 ps Exp $ - * $DragonFly: src/sys/dev/raid/ida/ida.c,v 1.8 2005/06/10 15:46:31 swildner Exp $ + * $DragonFly: src/sys/dev/raid/ida/ida.c,v 1.9 2006/02/17 19:18:05 dillon Exp $ */ /* @@ -196,7 +196,7 @@ ida_init(struct ida_softc *ida) SLIST_INIT(&ida->free_qcbs); STAILQ_INIT(&ida->qcb_queue); - bufq_init(&ida->buf_queue); + bioq_init(&ida->bio_queue); ida->qcbs = malloc(IDA_QCB_MAX * sizeof(struct ida_qcb), M_DEVBUF, M_INTWAIT|M_ZERO); @@ -372,9 +372,9 @@ ida_command(struct ida_softc *ida, int command, void *data, int datasize, } void -ida_submit_buf(struct ida_softc *ida, struct buf *bp) +ida_submit_buf(struct ida_softc *ida, struct bio *bio) { - bufq_insert_tail(&ida->buf_queue, bp); + bioq_insert_tail(&ida->bio_queue, bio); ida_construct_qcb(ida); ida_start(ida); } @@ -386,22 +386,24 @@ ida_construct_qcb(struct ida_softc *ida) struct ida_qcb *qcb; bus_dmasync_op_t op; struct buf *bp; + struct bio *bio; - bp = bufq_first(&ida->buf_queue); - if (bp == NULL) + bio = bioq_first(&ida->bio_queue); + if (bio == NULL) return; /* no more buffers */ qcb = ida_get_qcb(ida); if (qcb == NULL) return; /* out of resources */ - bufq_remove(&ida->buf_queue, bp); - qcb->buf = bp; + bioq_remove(&ida->bio_queue, bio); + qcb->bio = bio; qcb->flags = 0; hwqcb = qcb->hwqcb; bzero(hwqcb, sizeof(struct ida_hdr) + sizeof(struct ida_req)); + bp = bio->bio_buf; bus_dmamap_load(ida->buffer_dmat, qcb->dmamap, (void *)bp->b_data, bp->b_bcount, ida_setup_dmamap, hwqcb, 0); op = qcb->flags & DMA_DATA_IN ? @@ -409,11 +411,13 @@ ida_construct_qcb(struct ida_softc *ida) bus_dmamap_sync(ida->buffer_dmat, qcb->dmamap, op); { - struct idad_softc *drv = (struct idad_softc *)bp->b_driver1; + struct idad_softc *drv; + + drv = (struct idad_softc *)bio->bio_driver_info; hwqcb->hdr.drive = drv->drive; } - hwqcb->req.blkno = bp->b_pblkno; + hwqcb->req.blkno = bio->bio_blkno; hwqcb->req.bcount = howmany(bp->b_bcount, DEV_BSIZE); hwqcb->req.command = bp->b_flags & B_READ ? CMD_READ : CMD_WRITE; @@ -532,8 +536,8 @@ ida_done(struct ida_softc *ida, struct ida_qcb *qcb) wakeup(qcb); } else { if (error) - qcb->buf->b_flags |= B_ERROR; - idad_intr(qcb->buf); + qcb->bio->bio_buf->b_flags |= B_ERROR; + idad_intr(qcb->bio); } qcb->state = QCB_FREE; diff --git a/sys/dev/raid/ida/ida_disk.c b/sys/dev/raid/ida/ida_disk.c index 17fa04043f..9224a8f8c0 100644 --- a/sys/dev/raid/ida/ida_disk.c +++ b/sys/dev/raid/ida/ida_disk.c @@ -24,7 +24,7 @@ * SUCH DAMAGE. * * $FreeBSD: src/sys/dev/ida/ida_disk.c,v 1.12.2.6 2001/11/27 20:21:02 ps Exp $ - * $DragonFly: src/sys/dev/raid/ida/ida_disk.c,v 1.9 2005/06/10 15:46:31 swildner Exp $ + * $DragonFly: src/sys/dev/raid/ida/ida_disk.c,v 1.10 2006/02/17 19:18:05 dillon Exp $ */ /* @@ -156,11 +156,12 @@ idad_close(dev_t dev, int flags, int fmt, d_thread_t *td) * be a multiple of a sector in length. */ static void -idad_strategy(struct buf *bp) +idad_strategy(dev_t dev, struct bio *bio) { + struct buf *bp = bio->bio_buf; struct idad_softc *drv; - drv = idad_getsoftc(bp->b_dev); + drv = idad_getsoftc(dev); if (drv == NULL) { bp->b_error = EINVAL; goto bad; @@ -180,10 +181,10 @@ idad_strategy(struct buf *bp) if (bp->b_bcount == 0) goto done; - bp->b_driver1 = drv; + bio->bio_driver_info = drv; crit_enter(); devstat_start_transaction(&drv->stats); - ida_submit_buf(drv->controller, bp); + ida_submit_buf(drv->controller, bio); crit_exit(); return; @@ -195,8 +196,7 @@ done: * Correctly set the buf to indicate a completed transfer */ bp->b_resid = bp->b_bcount; - biodone(bp); - return; + biodone(bio); } static int @@ -244,9 +244,10 @@ idad_dump(dev_t dev, u_int count, u_int blkno, u_int secsize) } void -idad_intr(struct buf *bp) +idad_intr(struct bio *bio) { - struct idad_softc *drv = (struct idad_softc *)bp->b_driver1; + struct idad_softc *drv = (struct idad_softc *)bio->bio_driver_info; + struct buf *bp = bio->bio_buf; if (bp->b_flags & B_ERROR) bp->b_error = EIO; @@ -254,7 +255,7 @@ idad_intr(struct buf *bp) bp->b_resid = 0; devstat_end_transaction_buf(&drv->stats, bp); - biodone(bp); + biodone(bio); } static int diff --git a/sys/dev/raid/ida/idavar.h b/sys/dev/raid/ida/idavar.h index 339ee5332c..86bca59f42 100644 --- a/sys/dev/raid/ida/idavar.h +++ b/sys/dev/raid/ida/idavar.h @@ -24,7 +24,7 @@ * SUCH DAMAGE. * * $FreeBSD: src/sys/dev/ida/idavar.h,v 1.3.2.4 2001/07/30 20:29:58 jlemon Exp $ - * $DragonFly: src/sys/dev/raid/ida/idavar.h,v 1.2 2003/06/17 04:28:27 dillon Exp $ + * $DragonFly: src/sys/dev/raid/ida/idavar.h,v 1.3 2006/02/17 19:18:05 dillon Exp $ */ /* @@ -104,7 +104,7 @@ struct ida_qcb { } link; bus_dmamap_t dmamap; bus_addr_t hwqcb_busaddr; - struct buf *buf; /* buf associated with qcb */ + struct bio *bio; /* bio associated with qcb */ }; struct ida_softc; @@ -157,7 +157,7 @@ struct ida_softc { struct ida_qcb *qcbs; /* kernel QCB array */ SLIST_HEAD(, ida_qcb) free_qcbs; STAILQ_HEAD(, ida_qcb) qcb_queue; - struct buf_queue_head buf_queue; + struct bio_queue_head bio_queue; struct ida_access cmd; }; @@ -197,9 +197,9 @@ extern int ida_init(struct ida_softc *ida); extern void ida_attach(struct ida_softc *ida); extern int ida_command(struct ida_softc *ida, int command, void *data, int datasize, int drive, u_int32_t pblkno, int flags); -extern void ida_submit_buf(struct ida_softc *ida, struct buf *bp); +extern void ida_submit_buf(struct ida_softc *ida, struct bio *bio); extern void ida_intr(void *data); -extern void idad_intr(struct buf *bp); +extern void idad_intr(struct bio *bio); #endif /* _IDAVAR_H */ diff --git a/sys/dev/raid/ips/ips.h b/sys/dev/raid/ips/ips.h index 81e9740915..9f96b221ab 100644 --- a/sys/dev/raid/ips/ips.h +++ b/sys/dev/raid/ips/ips.h @@ -26,7 +26,7 @@ * SUCH DAMAGE. * * $FreeBSD: src/sys/dev/ips/ips.h,v 1.10 2004/05/30 20:08:34 phk Exp $ - * $DragonFly: src/sys/dev/raid/ips/ips.h,v 1.7 2005/08/09 16:23:13 dillon Exp $ + * $DragonFly: src/sys/dev/raid/ips/ips.h,v 1.8 2006/02/17 19:18:05 dillon Exp $ */ @@ -198,6 +198,7 @@ MALLOC_DECLARE(M_IPSBUF); * for compatibility */ /* struct buf to struct bio changes */ +#if 0 #define BIO_ERROR B_ERROR #define BIO_READ B_READ #define bio buf @@ -211,8 +212,9 @@ MALLOC_DECLARE(M_IPSBUF); #define bio_resid b_resid /* geom */ -#define bio_disk bio_dev #define d_drv1 si_drv1 +#endif + #define d_maxsize si_iosize_max #define disk_open_t d_open_t @@ -237,7 +239,7 @@ MALLOC_DECLARE(M_IPSBUF); #define ips_write_2(sc,offset,value) bus_space_write_2(sc->bustag, sc->bushandle, offset, value) #define ips_write_4(sc,offset,value) bus_space_write_4(sc->bustag, sc->bushandle, offset, value) -#define ips_read_request(iobuf) ((iobuf)->b_flags & B_READ) +#define ips_read_request(iobuf) ((bio)->bio_buf->b_flags & B_READ) #define COMMAND_ERROR(status) (((status)->fields.basic_status & 0x0f) >= IPS_MIN_ERROR) @@ -469,7 +471,7 @@ typedef struct ips_softc { ips_copper_queue_t *copper_queue; struct lwkt_rwlock queue_lock; - struct buf_queue_head queue; + struct bio_queue_head bio_queue; } ips_softc_t; /* function defines from ips_ioctl.c */ diff --git a/sys/dev/raid/ips/ips_commands.c b/sys/dev/raid/ips/ips_commands.c index e0d6aef64d..7e392b550a 100644 --- a/sys/dev/raid/ips/ips_commands.c +++ b/sys/dev/raid/ips/ips_commands.c @@ -25,10 +25,12 @@ * SUCH DAMAGE. * * $FreeBSD: src/sys/dev/ips/ips_commands.c,v 1.10 2004/05/30 04:01:29 scottl Exp $ - * $DragonFly: src/sys/dev/raid/ips/ips_commands.c,v 1.10 2006/01/01 16:53:15 y0netan1 Exp $ + * $DragonFly: src/sys/dev/raid/ips/ips_commands.c,v 1.11 2006/02/17 19:18:05 dillon Exp $ */ +#include #include +#include int ips_timed_wait(ips_command_t *command, const char *id, int timo) @@ -71,9 +73,9 @@ ips_wakeup_callback(ips_command_t *command) static void ips_io_request_finish(ips_command_t *command) { - struct bio *iobuf = command->arg; + struct bio *bio = command->arg; - if (ips_read_request(iobuf)) { + if (ips_read_request(bio)) { bus_dmamap_sync(command->data_dmatag, command->data_dmamap, BUS_DMASYNC_POSTREAD); } else { @@ -82,11 +84,11 @@ ips_io_request_finish(ips_command_t *command) } bus_dmamap_unload(command->data_dmatag, command->data_dmamap); if (COMMAND_ERROR(&command->status)) { - iobuf->bio_flags |=BIO_ERROR; - iobuf->bio_error = EIO; + bio->bio_buf->b_flags |=B_ERROR; + bio->bio_buf->b_error = EIO; } ips_insert_free_cmd(command->sc, command); - ipsd_finish(iobuf); + ipsd_finish(bio); } static void @@ -97,7 +99,9 @@ ips_io_request_callback(void *cmdptr, bus_dma_segment_t *segments, int segnum, ips_command_t *command = cmdptr; ips_sg_element_t *sg_list; ips_io_cmd *command_struct; - struct bio *iobuf = command->arg; + struct bio *bio = command->arg; + struct buf *bp = bio->bio_buf; + ipsdisk_softc_t *dsc; int i, length = 0; u_int8_t cmdtype; @@ -105,17 +109,19 @@ ips_io_request_callback(void *cmdptr, bus_dma_segment_t *segments, int segnum, if (error) { printf("ips: error = %d in ips_sg_request_callback\n", error); bus_dmamap_unload(command->data_dmatag, command->data_dmamap); - iobuf->bio_flags |= BIO_ERROR; - iobuf->bio_error = ENOMEM; + bp->b_flags |= B_ERROR; + bp->b_error = ENOMEM; ips_insert_free_cmd(sc, command); - ipsd_finish(iobuf); + ipsd_finish(bio); return; } + dsc = bio->bio_driver_info; command_struct = (ips_io_cmd *)command->command_buffer; command_struct->id = command->id; - command_struct->drivenum = (uintptr_t)iobuf->bio_driver1; + command_struct->drivenum = dsc->sc->drives[dsc->disk_number].drivenum; + if (segnum != 1) { - if (ips_read_request(iobuf)) + if (ips_read_request(bio)) cmdtype = IPS_SG_READ_CMD; else cmdtype = IPS_SG_WRITE_CMD; @@ -130,7 +136,7 @@ ips_io_request_callback(void *cmdptr, bus_dma_segment_t *segments, int segnum, command_struct->buffaddr = (u_int32_t)command->command_phys_addr + IPS_COMMAND_LEN; } else { - if (ips_read_request(iobuf)) + if (ips_read_request(bio)) cmdtype = IPS_READ_CMD; else cmdtype = IPS_WRITE_CMD; @@ -138,12 +144,12 @@ ips_io_request_callback(void *cmdptr, bus_dma_segment_t *segments, int segnum, length = segments[0].ds_len; } command_struct->command = cmdtype; - command_struct->lba = iobuf->bio_pblkno; + command_struct->lba = bio->bio_blkno; length = (length + IPS_BLKSIZE - 1)/IPS_BLKSIZE; command_struct->length = length; bus_dmamap_sync(sc->command_dmatag, command->command_dmamap, BUS_DMASYNC_PREWRITE); - if (ips_read_request(iobuf)) { + if (ips_read_request(bio)) { bus_dmamap_sync(command->data_dmatag, command->data_dmamap, BUS_DMASYNC_PREREAD); } else { @@ -156,7 +162,7 @@ ips_io_request_callback(void *cmdptr, bus_dma_segment_t *segments, int segnum, */ PRINTF(10, "ips test: command id: %d segments: %d " "pblkno: %lld length: %d, ds_len: %d\n", command->id, segnum, - (long long)iobuf->bio_pblkno, + (long long)bio->bio_blkno, length, segments[0].ds_len); sc->ips_issue_cmd(command); @@ -164,13 +170,15 @@ ips_io_request_callback(void *cmdptr, bus_dma_segment_t *segments, int segnum, } static int -ips_send_io_request(ips_command_t *command, struct buf *iobuf) +ips_send_io_request(ips_command_t *command, struct bio *bio) { + struct buf *bp = bio->bio_buf; + command->callback = ips_io_request_finish; - command->arg = iobuf; - PRINTF(10, "ips test: : bcount %ld\n", iobuf->bio_bcount); + command->arg = bio; + PRINTF(10, "ips test: : bcount %ld\n", bp->b_bcount); bus_dmamap_load(command->data_dmatag, command->data_dmamap, - iobuf->bio_data, iobuf->bio_bcount, + bp->b_data, bp->b_bcount, ips_io_request_callback, command, 0); return 0; } @@ -179,15 +187,15 @@ void ips_start_io_request(ips_softc_t *sc) { ips_command_t *command; - struct bio *iobuf; + struct bio *bio; - iobuf = bufq_first(&sc->queue); - if (iobuf == NULL) + bio = bioq_first(&sc->bio_queue); + if (bio == NULL) return; if (ips_get_free_cmd(sc, &command, 0) != 0) return; - bufq_remove(&sc->queue, iobuf); - ips_send_io_request(command, iobuf); + bioq_remove(&sc->bio_queue, bio); + ips_send_io_request(command, bio); } /* diff --git a/sys/dev/raid/ips/ips_disk.c b/sys/dev/raid/ips/ips_disk.c index bff05affb2..cc4572b0d8 100644 --- a/sys/dev/raid/ips/ips_disk.c +++ b/sys/dev/raid/ips/ips_disk.c @@ -25,7 +25,7 @@ * SUCH DAMAGE. * * $FreeBSD: src/sys/dev/ips/ips_disk.c,v 1.4 2003/09/22 04:59:07 njl Exp $ - * $DragonFly: src/sys/dev/raid/ips/ips_disk.c,v 1.6 2005/08/09 16:23:13 dillon Exp $ + * $DragonFly: src/sys/dev/raid/ips/ips_disk.c,v 1.7 2006/02/17 19:18:05 dillon Exp $ */ #include @@ -112,32 +112,34 @@ ipsd_close(dev_t dev, int oflags, int devtype, d_thread_t *td) /* ipsd_finish is called to clean up and return a completed IO request */ void -ipsd_finish(struct bio *iobuf) +ipsd_finish(struct bio *bio) { + struct buf *bp = bio->bio_buf; ipsdisk_softc_t *dsc; - dsc = iobuf->bio_disk->d_drv1; - if (iobuf->bio_flags & BIO_ERROR) { - device_printf(dsc->dev, "iobuf error %d\n", iobuf->bio_error); - } else - iobuf->bio_resid = 0; - devstat_end_transaction_buf(&dsc->stats, iobuf); - biodone(iobuf); + dsc = bio->bio_driver_info; + if (bp->b_flags & B_ERROR) { + device_printf(dsc->dev, "iobuf error %d\n", bp->b_error); + } else { + bp->b_resid = 0; + } + devstat_end_transaction_buf(&dsc->stats, bp); + biodone(bio); ips_start_io_request(dsc->sc); } static void -ipsd_strategy(struct bio *iobuf) +ipsd_strategy(dev_t dev, struct bio *bio) { ipsdisk_softc_t *dsc; - dsc = iobuf->bio_disk->d_drv1; + dsc = dev->si_drv1; DEVICE_PRINTF(8, dsc->dev, "in strategy\n"); - iobuf->bio_driver1 = (void *)(uintptr_t)dsc->sc->drives[dsc->disk_number].drivenum; + bio->bio_driver_info = dsc; devstat_start_transaction(&dsc->stats); lwkt_exlock(&dsc->sc->queue_lock, __func__); - bufq_insert_tail(&dsc->sc->queue, iobuf); + bioq_insert_tail(&dsc->sc->bio_queue, bio); ips_start_io_request(dsc->sc); lwkt_exunlock(&dsc->sc->queue_lock); } diff --git a/sys/dev/raid/ips/ips_pci.c b/sys/dev/raid/ips/ips_pci.c index 7308bf2f69..7ed2e84a1a 100644 --- a/sys/dev/raid/ips/ips_pci.c +++ b/sys/dev/raid/ips/ips_pci.c @@ -26,7 +26,7 @@ * SUCH DAMAGE. * * $FreeBSD: src/sys/dev/ips/ips_pci.c,v 1.10 2004/03/19 17:36:47 scottl Exp $ - * $DragonFly: src/sys/dev/raid/ips/ips_pci.c,v 1.14 2005/10/12 17:35:54 dillon Exp $ + * $DragonFly: src/sys/dev/raid/ips/ips_pci.c,v 1.15 2006/02/17 19:18:05 dillon Exp $ */ #include @@ -155,7 +155,7 @@ ips_pci_attach(device_t dev) sc->ips_ich.ich_arg = sc; sc->ips_ich.ich_desc = "ips"; lwkt_rwlock_init(&sc->queue_lock); - bufq_init(&sc->queue); + bioq_init(&sc->bio_queue); if (config_intrhook_establish(&sc->ips_ich) != 0) { printf("IPS can't establish configuration hook\n"); goto error; diff --git a/sys/dev/raid/mlx/mlx.c b/sys/dev/raid/mlx/mlx.c index 6ac48f47c2..9f9506e9e1 100644 --- a/sys/dev/raid/mlx/mlx.c +++ b/sys/dev/raid/mlx/mlx.c @@ -24,7 +24,7 @@ * SUCH DAMAGE. * * $FreeBSD: src/sys/dev/mlx/mlx.c,v 1.14.2.5 2001/09/11 09:49:53 kris Exp $ - * $DragonFly: src/sys/dev/raid/mlx/mlx.c,v 1.15 2006/01/25 19:56:29 dillon Exp $ + * $DragonFly: src/sys/dev/raid/mlx/mlx.c,v 1.16 2006/02/17 19:18:05 dillon Exp $ */ /* @@ -300,7 +300,7 @@ mlx_attach(struct mlx_softc *sc) */ TAILQ_INIT(&sc->mlx_work); TAILQ_INIT(&sc->mlx_freecmds); - MLX_BIO_QINIT(sc->mlx_bioq); + bioq_init(&sc->mlx_bioq); /* * Select accessor methods based on controller interface type. @@ -703,12 +703,12 @@ mlx_intr(void *arg) * disk resource, then poke the disk resource to start as much work as it can. */ int -mlx_submit_buf(struct mlx_softc *sc, mlx_bio *bp) +mlx_submit_bio(struct mlx_softc *sc, struct bio *bio) { debug_called(1); crit_enter(); - MLX_BIO_QINSERT(sc->mlx_bioq, bp); + bioq_insert_tail(&sc->mlx_bioq, bio); sc->mlx_waitbufs++; crit_exit(); mlx_startio(sc); @@ -1732,7 +1732,8 @@ mlx_startio(struct mlx_softc *sc) { struct mlx_command *mc; struct mlxd_softc *mlxd; - mlx_bio *bp; + struct bio *bio; + struct buf *bp; int blkcount; int driveno; int cmd; @@ -1746,7 +1747,7 @@ mlx_startio(struct mlx_softc *sc) for (;;) { /* see if there's work to be done */ - if ((bp = MLX_BIO_QFIRST(sc->mlx_bioq)) == NULL) + if ((bio = bioq_first(&sc->mlx_bioq)) == NULL) break; /* get a command */ if ((mc = mlx_alloccmd(sc)) == NULL) @@ -1757,16 +1758,17 @@ mlx_startio(struct mlx_softc *sc) break; } /* get the buf containing our work */ - MLX_BIO_QREMOVE(sc->mlx_bioq, bp); + bioq_remove(&sc->mlx_bioq, bio); + bp = bio->bio_buf; sc->mlx_waitbufs--; crit_exit(); /* connect the buf to the command */ mc->mc_complete = mlx_completeio; mc->mc_private = bp; - mc->mc_data = MLX_BIO_DATA(bp); - mc->mc_length = MLX_BIO_LENGTH(bp); - if (MLX_BIO_IS_READ(bp)) { + mc->mc_data = bp->b_data; + mc->mc_length = bp->b_bcount; + if (bp->b_flags & B_READ) { mc->mc_flags |= MLX_CMD_DATAIN; cmd = MLX_CMD_READSG; } else { @@ -1778,13 +1780,13 @@ mlx_startio(struct mlx_softc *sc) mlx_mapcmd(mc); /* build a suitable I/O command (assumes 512-byte rounded transfers) */ - mlxd = (struct mlxd_softc *)MLX_BIO_SOFTC(bp); + mlxd = (struct mlxd_softc *)bio->bio_driver_info; driveno = mlxd->mlxd_drive - sc->mlx_sysdrive; - blkcount = (MLX_BIO_LENGTH(bp) + MLX_BLKSIZE - 1) / MLX_BLKSIZE; + blkcount = (bp->b_bcount + MLX_BLKSIZE - 1) / MLX_BLKSIZE; - if ((MLX_BIO_LBA(bp) + blkcount) > sc->mlx_sysdrive[driveno].ms_size) + if ((bio->bio_blkno + blkcount) > sc->mlx_sysdrive[driveno].ms_size) device_printf(sc->mlx_dev, "I/O beyond end of unit (%u,%d > %u)\n", - MLX_BIO_LBA(bp), blkcount, sc->mlx_sysdrive[driveno].ms_size); + bio->bio_blkno, blkcount, sc->mlx_sysdrive[driveno].ms_size); /* * Build the I/O command. Note that the SG list type bits are set to zero, @@ -1793,7 +1795,7 @@ mlx_startio(struct mlx_softc *sc) if (sc->mlx_iftype == MLX_IFTYPE_2) { mlx_make_type1(mc, (cmd == MLX_CMD_WRITESG) ? MLX_CMD_WRITESG_OLD : MLX_CMD_READSG_OLD, blkcount & 0xff, /* xfer length low byte */ - MLX_BIO_LBA(bp), /* physical block number */ + bio->bio_blkno, /* physical block number */ driveno, /* target drive number */ mc->mc_sgphys, /* location of SG list */ mc->mc_nsgent & 0x3f); /* size of SG list (top 3 bits clear) */ @@ -1801,7 +1803,7 @@ mlx_startio(struct mlx_softc *sc) mlx_make_type5(mc, cmd, blkcount & 0xff, /* xfer length low byte */ (driveno << 3) | ((blkcount >> 8) & 0x07), /* target and length high 3 bits */ - MLX_BIO_LBA(bp), /* physical block number */ + bio->bio_blkno, /* physical block number */ mc->mc_sgphys, /* location of SG list */ mc->mc_nsgent & 0x3f); /* size of SG list (top 3 bits clear) */ } @@ -1825,11 +1827,13 @@ static void mlx_completeio(struct mlx_command *mc) { struct mlx_softc *sc = mc->mc_sc; - mlx_bio *bp = (mlx_bio *)mc->mc_private; - struct mlxd_softc *mlxd = (struct mlxd_softc *)MLX_BIO_SOFTC(bp); + struct bio *bio = (mlx_bio *)mc->mc_private; + struct mlxd_softc *mlxd = (struct mlxd_softc *)bio->bio_driver_info; + struct buf *bp = bio->bio_buf; if (mc->mc_status != MLX_STATUS_OK) { /* could be more verbose here? */ - MLX_BIO_SET_ERROR(bp, EIO); + bp->b_error = EIO; + bp->b_flags |= B_ERROR; switch(mc->mc_status) { case MLX_STATUS_RDWROFFLINE: /* system drive has gone offline */ @@ -1842,14 +1846,14 @@ mlx_completeio(struct mlx_command *mc) device_printf(sc->mlx_dev, "I/O error - %s\n", mlx_diagnose_command(mc)); #if 0 device_printf(sc->mlx_dev, " b_bcount %ld blkcount %ld b_pblkno %d\n", - MLX_BIO_LENGTH(bp), MLX_BIO_LENGTH(bp) / MLX_BLKSIZE, MLX_BIO_LBA(bp)); + bp->b_bcount, bp->b_bcount / MLX_BLKSIZE, bio->bio_blkno); device_printf(sc->mlx_dev, " %13D\n", mc->mc_mailbox, " "); #endif break; } } mlx_releasecmd(mc); - mlxd_intr(bp); + mlxd_intr(bio); } /******************************************************************************** diff --git a/sys/dev/raid/mlx/mlx_compat.h b/sys/dev/raid/mlx/mlx_compat.h index cbd54308cd..91d71b098e 100644 --- a/sys/dev/raid/mlx/mlx_compat.h +++ b/sys/dev/raid/mlx/mlx_compat.h @@ -25,7 +25,7 @@ * SUCH DAMAGE. * * $FreeBSD: src/sys/dev/mlx/mlx_compat.h,v 1.1.2.1 2001/06/25 04:37:51 msmith Exp $ - * $DragonFly: src/sys/dev/raid/mlx/mlx_compat.h,v 1.5 2004/02/21 06:37:06 dillon Exp $ + * $DragonFly: src/sys/dev/raid/mlx/mlx_compat.h,v 1.6 2006/02/17 19:18:05 dillon Exp $ */ /* * Portability and compatibility interfaces. @@ -37,12 +37,13 @@ # include /* old buf style */ # include /* old buf style */ # include -typedef struct buf mlx_bio; -typedef struct buf_queue_head mlx_bioq; -# define MLX_BIO_QINIT(bq) bufq_init(&bq); -# define MLX_BIO_QINSERT(bq, bp) bufq_insert_tail(&bq, bp) -# define MLX_BIO_QFIRST(bq) bufq_first(&bq) -# define MLX_BIO_QREMOVE(bq, bp) bufq_remove(&bq, bp) +typedef struct bio mlx_bio; +typedef struct bio_queue_head mlx_bioq; +#if 0 +# define MLX_BIO_QINIT(bq) bioq_init(&bq); +# define MLX_BIO_QINSERT(bq, bp) bioq_insert_tail(&bq, bp) +# define MLX_BIO_QFIRST(bq) bioq_first(&bq) +# define MLX_BIO_QREMOVE(bq, bp) bioq_remove(&bq, bp) # define MLX_BIO_IS_READ(bp) ((bp)->b_flags & B_READ) # define MLX_BIO_DATA(bp) (bp)->b_data # define MLX_BIO_LENGTH(bp) (bp)->b_bcount @@ -55,6 +56,7 @@ typedef struct buf_queue_head mlx_bioq; # define MLX_BIO_DONE(bp) biodone(bp) # define MLX_BIO_STATS_START(bp) devstat_start_transaction(&((struct mlxd_softc *)MLX_BIO_SOFTC(bp))->mlxd_stats) # define MLX_BIO_STATS_END(bp) devstat_end_transaction_buf(&((struct mlxd_softc *)MLX_BIO_SOFTC(bp))->mlxd_stats, bp) +#endif #else # include typedef struct bio mlx_bio; diff --git a/sys/dev/raid/mlx/mlx_disk.c b/sys/dev/raid/mlx/mlx_disk.c index 1e41975206..d18acc79b8 100644 --- a/sys/dev/raid/mlx/mlx_disk.c +++ b/sys/dev/raid/mlx/mlx_disk.c @@ -25,7 +25,7 @@ * SUCH DAMAGE. * * $FreeBSD: src/sys/dev/mlx/mlx_disk.c,v 1.8.2.4 2001/06/25 04:37:51 msmith Exp $ - * $DragonFly: src/sys/dev/raid/mlx/mlx_disk.c,v 1.7 2004/05/13 23:49:19 dillon Exp $ + * $DragonFly: src/sys/dev/raid/mlx/mlx_disk.c,v 1.8 2006/02/17 19:18:05 dillon Exp $ */ /* @@ -164,51 +164,54 @@ mlxd_ioctl(dev_t dev, u_long cmd, caddr_t addr, int32_t flag, d_thread_t *td) * be a multiple of a sector in length. */ static void -mlxd_strategy(mlx_bio *bp) +mlxd_strategy(dev_t dev, mlx_bio *bio) { - struct mlxd_softc *sc = (struct mlxd_softc *)MLX_BIO_SOFTC(bp); + struct buf *bp = bio->bio_buf; + struct mlxd_softc *sc = (struct mlxd_softc *)bio->bio_driver_info; debug_called(1); /* bogus disk? */ if (sc == NULL) { - MLX_BIO_SET_ERROR(bp, EINVAL); + bp->b_error = EINVAL; + bp->b_flags |= B_ERROR; goto bad; } /* XXX may only be temporarily offline - sleep? */ if (sc->mlxd_drive->ms_state == MLX_SYSD_OFFLINE) { - MLX_BIO_SET_ERROR(bp, ENXIO); + bp->b_error = ENXIO; + bp->b_flags |= B_ERROR; goto bad; } - MLX_BIO_STATS_START(bp); - mlx_submit_buf(sc->mlxd_controller, bp); + devstat_start_transaction(&sc->mlxd_stats); + mlx_submit_bio(sc->mlxd_controller, bio); return; bad: /* * Correctly set the bio to indicate a failed tranfer. */ - MLX_BIO_RESID(bp) = MLX_BIO_LENGTH(bp); - MLX_BIO_DONE(bp); + bp->b_resid = bp->b_bcount; + biodone(bio); return; } void -mlxd_intr(void *data) +mlxd_intr(struct bio *bio) { - mlx_bio *bp = (mlx_bio *)data; + struct buf *bp = bio->bio_buf; + struct mlxd_softc *sc = (struct mlxd_softc *)bio->bio_driver_info; debug_called(1); - - if (MLX_BIO_HAS_ERROR(bp)) - MLX_BIO_SET_ERROR(bp, EIO); - else - MLX_BIO_RESID(bp) = 0; - MLX_BIO_STATS_END(bp); - MLX_BIO_DONE(bp); + if (bp->b_flags & B_ERROR) + bp->b_error = EIO; + else + bp->b_resid = 0; + devstat_end_transaction_buf(&sc->mlxd_stats, bp); + biodone(bio); } static int diff --git a/sys/dev/raid/mlx/mlxvar.h b/sys/dev/raid/mlx/mlxvar.h index b443f39062..2f2d7f05c7 100644 --- a/sys/dev/raid/mlx/mlxvar.h +++ b/sys/dev/raid/mlx/mlxvar.h @@ -24,7 +24,7 @@ * SUCH DAMAGE. * * $FreeBSD: src/sys/dev/mlx/mlxvar.h,v 1.5.2.3 2001/06/25 04:37:51 msmith Exp $ - * $DragonFly: src/sys/dev/raid/mlx/mlxvar.h,v 1.6 2005/02/17 13:59:36 joerg Exp $ + * $DragonFly: src/sys/dev/raid/mlx/mlxvar.h,v 1.7 2006/02/17 19:18:05 dillon Exp $ */ /* @@ -239,9 +239,9 @@ struct mlxd_softc /* * Interface between driver core and disk driver (should be using a bus?) */ -extern int mlx_submit_buf(struct mlx_softc *sc, mlx_bio *bp); +extern int mlx_submit_bio(struct mlx_softc *sc, struct bio *bio); extern int mlx_submit_ioctl(struct mlx_softc *sc, struct mlx_sysdrive *drive, u_long cmd, caddr_t addr, int32_t flag, d_thread_t *td); -extern void mlxd_intr(void *data); +extern void mlxd_intr(struct bio *bio); diff --git a/sys/dev/raid/pst/pst-raid.c b/sys/dev/raid/pst/pst-raid.c index 8f2e75873f..2037054f10 100644 --- a/sys/dev/raid/pst/pst-raid.c +++ b/sys/dev/raid/pst/pst-raid.c @@ -26,7 +26,7 @@ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * $FreeBSD: src/sys/dev/pst/pst-raid.c,v 1.2.2.1 2002/08/18 12:32:36 sos Exp $ - * $DragonFly: src/sys/dev/raid/pst/pst-raid.c,v 1.12 2005/06/10 17:10:26 swildner Exp $ + * $DragonFly: src/sys/dev/raid/pst/pst-raid.c,v 1.13 2006/02/17 19:18:06 dillon Exp $ */ #include @@ -82,7 +82,7 @@ struct pst_softc { dev_t device; struct devstat stats; struct disk disk; - struct buf_queue_head queue; + struct bio_queue_head bio_queue; int outstanding; }; @@ -90,7 +90,7 @@ struct pst_request { struct pst_softc *psc; /* pointer to softc */ u_int32_t mfa; /* frame addreess */ struct callout timeout; /* handle for untimeout */ - struct buf *bp; /* associated bio ptr */ + struct bio *bio; /* associated bio ptr */ }; /* prototypes */ @@ -166,7 +166,7 @@ pst_attach(device_t dev) sprintf(name, "%s %s", ident->vendor, ident->product); contigfree(reply, PAGE_SIZE, M_PSTRAID); - bufq_init(&psc->queue); + bioq_init(&psc->bio_queue); psc->device = disk_create(lun, &psc->disk, 0, &pst_cdevsw); psc->device->si_drv1 = psc; @@ -223,12 +223,12 @@ pst_shutdown(device_t dev) #endif static void -pststrategy(struct buf *bp) +pststrategy(dev_t dev, struct bio *bio) { - struct pst_softc *psc = bp->b_dev->si_drv1; + struct pst_softc *psc = dev->si_drv1; crit_enter(); - bufqdisksort(&psc->queue, bp); + bioqdisksort(&psc->bio_queue, bio); pst_start(psc); crit_exit(); } @@ -238,27 +238,29 @@ pst_start(struct pst_softc *psc) { struct pst_request *request; struct buf *bp; + struct bio *bio; u_int32_t mfa; if (psc->outstanding < (I2O_IOP_OUTBOUND_FRAME_COUNT - 1) && - (bp = bufq_first(&psc->queue))) { + (bio = bioq_first(&psc->bio_queue))) { if ((mfa = iop_get_mfa(psc->iop)) != 0xffffffff) { request = malloc(sizeof(struct pst_request), M_PSTRAID, M_INTWAIT | M_ZERO); psc->outstanding++; request->psc = psc; request->mfa = mfa; - request->bp = bp; + request->bio = bio; callout_init(&request->timeout); if (!dumping) callout_reset(&request->timeout, 10 * hz, pst_timeout, request); - bufq_remove(&psc->queue, bp); + bioq_remove(&psc->bio_queue, bio); + bp = bio->bio_buf; devstat_start_transaction(&psc->stats); if (pst_rw(request)) { - devstat_end_transaction_buf(&psc->stats, request->bp); - request->bp->b_error = EIO; - request->bp->b_flags |= B_ERROR; - biodone(request->bp); + devstat_end_transaction_buf(&psc->stats, bp); + bp->b_error = EIO; + bp->b_flags |= B_ERROR; + biodone(bio); iop_free_mfa(request->psc->iop, request->mfa); psc->outstanding--; callout_stop(&request->timeout); @@ -274,15 +276,16 @@ pst_done(struct iop_softc *sc, u_int32_t mfa, struct i2o_single_reply *reply) struct pst_request *request = (struct pst_request *)reply->transaction_context; struct pst_softc *psc = request->psc; + struct buf *bp = request->bio->bio_buf; callout_stop(&request->timeout); - request->bp->b_resid = request->bp->b_bcount - reply->donecount; - devstat_end_transaction_buf(&psc->stats, request->bp); + bp->b_resid = bp->b_bcount - reply->donecount; + devstat_end_transaction_buf(&psc->stats, bp); if (reply->status) { - request->bp->b_error = EIO; - request->bp->b_flags |= B_ERROR; + bp->b_error = EIO; + bp->b_flags |= B_ERROR; } - biodone(request->bp); + biodone(request->bio); free(request, M_PSTRAID); crit_enter(); psc->iop->reg->oqueue = mfa; @@ -295,17 +298,18 @@ static void pst_timeout(void *xrequest) { struct pst_request *request = xrequest; + struct buf *bp = request->bio->bio_buf; crit_enter(); printf("pst: timeout mfa=0x%08x cmd=%s\n", - request->mfa, request->bp->b_flags & B_READ ? "READ" : "WRITE"); + request->mfa, bp->b_flags & B_READ ? "READ" : "WRITE"); iop_free_mfa(request->psc->iop, request->mfa); if ((request->mfa = iop_get_mfa(request->psc->iop)) == 0xffffffff) { printf("pst: timeout no mfa possible\n"); - devstat_end_transaction_buf(&request->psc->stats, request->bp); - request->bp->b_error = EIO; - request->bp->b_flags |= B_ERROR; - biodone(request->bp); + devstat_end_transaction_buf(&request->psc->stats, bp); + bp->b_error = EIO; + bp->b_flags |= B_ERROR; + biodone(request->bio); request->psc->outstanding--; crit_exit(); return; @@ -314,10 +318,10 @@ pst_timeout(void *xrequest) callout_reset(&request->timeout, 10 * hz, pst_timeout, request); if (pst_rw(request)) { iop_free_mfa(request->psc->iop, request->mfa); - devstat_end_transaction_buf(&request->psc->stats, request->bp); - request->bp->b_error = EIO; - request->bp->b_flags |= B_ERROR; - biodone(request->bp); + devstat_end_transaction_buf(&request->psc->stats, bp); + bp->b_error = EIO; + bp->b_flags |= B_ERROR; + biodone(request->bio); request->psc->outstanding--; } crit_exit(); @@ -328,6 +332,7 @@ pst_rw(struct pst_request *request) { struct i2o_bsa_rw_block_message *msg; int sgl_flag; + struct buf *bp = request->bio->bio_buf; msg = (struct i2o_bsa_rw_block_message *) (request->psc->iop->ibase + request->mfa); @@ -337,7 +342,7 @@ pst_rw(struct pst_request *request) msg->message_size = sizeof(struct i2o_bsa_rw_block_message) >> 2; msg->target_address = request->psc->lct->local_tid; msg->initiator_address = I2O_TID_HOST; - if (request->bp->b_flags & B_READ) { + if (bp->b_flags & B_READ) { msg->function = I2O_BSA_BLOCK_READ; msg->control_flags = 0x0; /* 0x0c = read cache + readahead */ msg->fetch_ahead = 0x0; /* 8 Kb */ @@ -352,10 +357,10 @@ pst_rw(struct pst_request *request) msg->initiator_context = (u_int32_t)pst_done; msg->transaction_context = (u_int32_t)request; msg->time_multiplier = 1; - msg->bytecount = request->bp->b_bcount; - msg->lba = ((u_int64_t)request->bp->b_pblkno) * (DEV_BSIZE * 1LL); - if (!iop_create_sgl((struct i2o_basic_message *)msg, request->bp->b_data, - request->bp->b_bcount, sgl_flag)) + msg->bytecount = bp->b_bcount; + msg->lba = ((u_int64_t)request->bio->bio_blkno) * (DEV_BSIZE * 1LL); + if (!iop_create_sgl((struct i2o_basic_message *)msg, bp->b_data, + bp->b_bcount, sgl_flag)) return -1; request->psc->iop->reg->iqueue = request->mfa; return 0; diff --git a/sys/dev/raid/twe/twe.c b/sys/dev/raid/twe/twe.c index fd01ede28c..68498512cd 100644 --- a/sys/dev/raid/twe/twe.c +++ b/sys/dev/raid/twe/twe.c @@ -27,7 +27,7 @@ * SUCH DAMAGE. * * $FreeBSD: src/sys/dev/twe/twe.c,v 1.1.2.10 2004/06/11 18:57:31 vkashyap Exp $ - * $DragonFly: src/sys/dev/raid/twe/twe.c,v 1.12 2005/08/22 21:16:20 hmp Exp $ + * $DragonFly: src/sys/dev/raid/twe/twe.c,v 1.13 2006/02/17 19:18:06 dillon Exp $ */ /* @@ -378,7 +378,7 @@ twe_startio(struct twe_softc *sc) { struct twe_request *tr; TWE_Command *cmd; - twe_bio *bp; + struct bio *bio; int error; debug_called(4); @@ -400,18 +400,18 @@ twe_startio(struct twe_softc *sc) break; /* see if there's work to be done */ - if ((bp = twe_dequeue_bio(sc)) == NULL) { + if ((bio = twe_dequeue_bio(sc)) == NULL) { twe_release_request(tr); break; } /* connect the bio to the command */ tr->tr_complete = twe_completeio; - tr->tr_private = bp; - tr->tr_data = TWE_BIO_DATA(bp); - tr->tr_length = TWE_BIO_LENGTH(bp); + tr->tr_private = bio; + tr->tr_data = bio->bio_buf->b_data; + tr->tr_length = bio->bio_buf->b_bcount; cmd = &tr->tr_command; - if (TWE_BIO_IS_READ(bp)) { + if (bio->bio_buf->b_flags & B_READ) { tr->tr_flags |= TWE_CMD_DATAIN; cmd->io.opcode = TWE_OP_READ; } else { @@ -421,9 +421,9 @@ twe_startio(struct twe_softc *sc) /* build a suitable I/O command (assumes 512-byte rounded transfers) */ cmd->io.size = 3; - cmd->io.unit = TWE_BIO_UNIT(bp); + cmd->io.unit = ((struct twed_softc *)bio->bio_driver_info)->twed_drive->td_twe_unit; cmd->io.block_count = (tr->tr_length + TWE_BLOCK_SIZE - 1) / TWE_BLOCK_SIZE; - cmd->io.lba = TWE_BIO_LBA(bp); + cmd->io.lba = bio->bio_blkno; } /* did we find something to do? */ @@ -438,10 +438,11 @@ twe_startio(struct twe_softc *sc) break; tr->tr_status = TWE_CMD_ERROR; if (tr->tr_private != NULL) { - bp = (twe_bio *)(tr->tr_private); - TWE_BIO_SET_ERROR(bp, error); + bio = (twe_bio *)tr->tr_private; + bio->bio_buf->b_error = error; + bio->bio_buf->b_flags |= B_ERROR; tr->tr_private = NULL; - twed_intr(bp); + twed_intr(bio); twe_release_request(tr); } else if (tr->tr_flags & TWE_CMD_SLEEPER) wakeup_one(tr); /* wakeup the sleeping owner */ @@ -940,19 +941,22 @@ static void twe_completeio(struct twe_request *tr) { struct twe_softc *sc = tr->tr_sc; - twe_bio *bp = (twe_bio *)tr->tr_private; + struct bio *bio = (twe_bio *)tr->tr_private; + struct buf *bp = bio->bio_buf; debug_called(4); if (tr->tr_status == TWE_CMD_COMPLETE) { if (tr->tr_command.generic.status) - if (twe_report_request(tr)) - TWE_BIO_SET_ERROR(bp, EIO); + if (twe_report_request(tr)) { + bp->b_error = EIO; + bp->b_flags |= B_ERROR; + } } else { twe_panic(sc, "twe_completeio on incomplete command"); } tr->tr_private = NULL; - twed_intr(bp); + twed_intr(bio); twe_release_request(tr); } diff --git a/sys/dev/raid/twe/twe_compat.h b/sys/dev/raid/twe/twe_compat.h index af3bd88544..c8d266eb56 100644 --- a/sys/dev/raid/twe/twe_compat.h +++ b/sys/dev/raid/twe/twe_compat.h @@ -27,7 +27,7 @@ * SUCH DAMAGE. * * $FreeBSD: src/sys/dev/twe/twe_compat.h,v 1.1.2.5 2004/04/07 22:18:00 vkashyap Exp $ - * $DragonFly: src/sys/dev/raid/twe/twe_compat.h,v 1.12 2005/10/26 14:19:08 sephe Exp $ + * $DragonFly: src/sys/dev/raid/twe/twe_compat.h,v 1.13 2006/02/17 19:18:06 dillon Exp $ */ /* * Portability and compatibility interfaces. @@ -162,12 +162,13 @@ # include /* old buf style */ # include /* bufq stuff */ #define FREEBSD_4 -typedef struct buf twe_bio; -typedef struct buf_queue_head twe_bioq; -# define TWE_BIO_QINIT(bq) bufq_init(&bq); -# define TWE_BIO_QINSERT(bq, bp) bufq_insert_tail(&bq, bp) -# define TWE_BIO_QFIRST(bq) bufq_first(&bq) -# define TWE_BIO_QREMOVE(bq, bp) bufq_remove(&bq, bp) +typedef struct bio twe_bio; +typedef struct bio_queue_head twe_bioq; +#if 0 +# define TWE_BIO_QINIT(bq) bioq_init(&bq); +# define TWE_BIO_QINSERT(bq, bp) bioq_insert_tail(&bq, bp) +# define TWE_BIO_QFIRST(bq) bioq_first(&bq) +# define TWE_BIO_QREMOVE(bq, bp) bioq_remove(&bq, bp) # define TWE_BIO_IS_READ(bp) ((bp)->b_flags & B_READ) # define TWE_BIO_DATA(bp) (bp)->b_data # define TWE_BIO_LENGTH(bp) (bp)->b_bcount @@ -180,6 +181,7 @@ typedef struct buf_queue_head twe_bioq; # define TWE_BIO_DONE(bp) biodone(bp) # define TWE_BIO_STATS_START(bp) devstat_start_transaction(&((struct twed_softc *)TWE_BIO_SOFTC(bp))->twed_stats) # define TWE_BIO_STATS_END(bp) devstat_end_transaction_buf(&((struct twed_softc *)TWE_BIO_SOFTC(bp))->twed_stats, bp) +#endif #else # include typedef struct bio twe_bio; diff --git a/sys/dev/raid/twe/twe_freebsd.c b/sys/dev/raid/twe/twe_freebsd.c index a3ccc43010..045bfeef9c 100644 --- a/sys/dev/raid/twe/twe_freebsd.c +++ b/sys/dev/raid/twe/twe_freebsd.c @@ -27,7 +27,7 @@ * SUCH DAMAGE. * * $FreeBSD: src/sys/dev/twe/twe_freebsd.c,v 1.2.2.9 2004/06/11 18:57:31 vkashyap Exp $ - * $DragonFly: src/sys/dev/raid/twe/twe_freebsd.c,v 1.18 2006/01/25 19:56:31 dillon Exp $ + * $DragonFly: src/sys/dev/raid/twe/twe_freebsd.c,v 1.19 2006/02/17 19:18:06 dillon Exp $ */ /* @@ -693,9 +693,12 @@ twed_close(dev_t dev, int flags, int fmt, d_thread_t *td) * Handle an I/O request. */ static void -twed_strategy(twe_bio *bp) +twed_strategy(dev_t dev, struct bio *bio) { - struct twed_softc *sc = (struct twed_softc *)TWE_BIO_SOFTC(bp); + struct twed_softc *sc = dev->si_drv1; + struct buf *bp = bio->bio_buf; + + bio->bio_driver_info = sc; debug_called(4); @@ -703,18 +706,19 @@ twed_strategy(twe_bio *bp) /* bogus disk? */ if ((sc == NULL) || (!sc->twed_drive->td_disk)) { - TWE_BIO_SET_ERROR(bp, EINVAL); + bp->b_error = EINVAL; + bp->b_flags |= B_ERROR; printf("twe: bio for invalid disk!\n"); - TWE_BIO_DONE(bp); + biodone(bio); TWED_BIO_OUT; return; } /* perform accounting */ - TWE_BIO_STATS_START(bp); + devstat_start_transaction(&sc->twed_stats); /* queue the bio on the controller */ - twe_enqueue_bio(sc->twed_controller, bp); + twe_enqueue_bio(sc->twed_controller, bio); /* poke the controller to start I/O */ twe_startio(sc->twed_controller); @@ -781,16 +785,17 @@ twed_dump(dev_t dev, u_int count, u_int blkno, u_int secsize) * Handle completion of an I/O request. */ void -twed_intr(twe_bio *bp) +twed_intr(struct bio *bio) { + struct buf *bp = bio->bio_buf; + struct twed_softc *sc = bio->bio_driver_info; debug_called(4); /* if no error, transfer completed */ - if (!TWE_BIO_HAS_ERROR(bp)) - TWE_BIO_RESID(bp) = 0; - - TWE_BIO_STATS_END(bp); - TWE_BIO_DONE(bp); + if (bp->b_flags & B_ERROR) + bp->b_resid = 0; + devstat_end_transaction_buf(&sc->twed_stats, bp); + biodone(bio); TWED_BIO_OUT; } diff --git a/sys/dev/raid/twe/twevar.h b/sys/dev/raid/twe/twevar.h index d45465b5c9..409e96a27c 100644 --- a/sys/dev/raid/twe/twevar.h +++ b/sys/dev/raid/twe/twevar.h @@ -27,7 +27,7 @@ * SUCH DAMAGE. * * $FreeBSD: src/sys/dev/twe/twevar.h,v 1.1.2.8 2004/06/11 18:57:32 vkashyap Exp $ - * $DragonFly: src/sys/dev/raid/twe/twevar.h,v 1.5 2005/08/22 21:16:20 hmp Exp $ + * $DragonFly: src/sys/dev/raid/twe/twevar.h,v 1.6 2006/02/17 19:18:06 dillon Exp $ */ #define TWE_DRIVER_VERSION_STRING "1.40.01.002" @@ -274,29 +274,30 @@ TWEQ_REQUEST_QUEUE(complete, TWEQ_COMPLETE) static __inline void twe_initq_bio(struct twe_softc *sc) { - TWE_BIO_QINIT(sc->twe_bioq); + bioq_init(&sc->twe_bioq); TWEQ_INIT(sc, TWEQ_BIO); } static __inline void -twe_enqueue_bio(struct twe_softc *sc, twe_bio *bp) +twe_enqueue_bio(struct twe_softc *sc, struct bio *bio) { crit_enter(); - TWE_BIO_QINSERT(sc->twe_bioq, bp); + bioq_insert_tail(&sc->twe_bioq, bio); TWEQ_ADD(sc, TWEQ_BIO); crit_exit(); } -static __inline twe_bio * +static __inline +struct bio * twe_dequeue_bio(struct twe_softc *sc) { - twe_bio *bp; + struct bio *bio; crit_enter(); - if ((bp = TWE_BIO_QFIRST(sc->twe_bioq)) != NULL) { - TWE_BIO_QREMOVE(sc->twe_bioq, bp); + if ((bio = bioq_first(&sc->twe_bioq)) != NULL) { + bioq_remove(&sc->twe_bioq, bio); TWEQ_REMOVE(sc, TWEQ_BIO); } crit_exit(); - return(bp); + return(bio); } diff --git a/sys/dev/raid/vinum/.gdbinit.crash b/sys/dev/raid/vinum/.gdbinit.crash index f3e643671c..7f0f92c1ce 100644 --- a/sys/dev/raid/vinum/.gdbinit.crash +++ b/sys/dev/raid/vinum/.gdbinit.crash @@ -1,3 +1,4 @@ +# $DragonFly: src/sys/dev/raid/vinum/.gdbinit.crash,v 1.2 2006/02/17 19:18:06 dillon Exp $ source .gdbinit.kernel source .gdbinit.vinum.paths source .gdbinit.vinum diff --git a/sys/dev/raid/vinum/.gdbinit.kernel b/sys/dev/raid/vinum/.gdbinit.kernel index 557ab98868..82980c9a1b 100644 --- a/sys/dev/raid/vinum/.gdbinit.kernel +++ b/sys/dev/raid/vinum/.gdbinit.kernel @@ -1,3 +1,4 @@ +# $DragonFly: src/sys/dev/raid/vinum/.gdbinit.kernel,v 1.3 2006/02/17 19:18:06 dillon Exp $ set remotebaud 38400 set remotetimeout 1 set complaints 1 @@ -233,14 +234,14 @@ set $bp = (struct buf *) $arg0 $bp->b_dev->si_udev, \ $bp->b_data, \ $bp->b_bcount, \ - $bp->b_blkno, \ + $bp->b_bio->bio_blkno, \ $bp->b_resid else printf " Buffer at 0x%x: dev (none) data 0x%x bcount 0x%x blkno 0x%x resid 0x%x\n", \ $bp, \ $bp->b_data, \ $bp->b_bcount, \ - $bp->b_blkno, \ + $bp->b_bio->bio_blkno, \ $bp->b_resid end printf " flags 0x%x: ", $bp->b_flags @@ -291,9 +292,9 @@ output $bp->b_kvasize printf "\nb_lblkno: " output $bp->b_lblkno printf "\nb_blkno: " -output $bp->b_blkno +output $bp->b_bio->bio_blkno printf "\nb_iodone: " -output $bp->b_iodone +output $bp->b_bio->bio_done printf "\nb_vp: " output $bp->b_vp printf "\nb_dirtyoff: " @@ -375,9 +376,7 @@ output/x bp->b_data printf "\n b_kvasize " output/x bp->b_kvasize printf "\n b_blkno " -output/x bp->b_blkno -printf "\n b_iodone_chain " -output/x bp->b_iodone_chain +output/x bp->b_bio->bio_blkno printf "\n b_vp " output/x bp->b_vp printf "\n b_dirtyoff " diff --git a/sys/dev/raid/vinum/.gdbinit.vinum b/sys/dev/raid/vinum/.gdbinit.vinum index d494be39af..f1e71af9de 100644 --- a/sys/dev/raid/vinum/.gdbinit.vinum +++ b/sys/dev/raid/vinum/.gdbinit.vinum @@ -1,3 +1,4 @@ +# $DragonFly: src/sys/dev/raid/vinum/.gdbinit.vinum,v 1.2 2006/02/17 19:18:06 dillon Exp $ define rq rqq rq end @@ -62,7 +63,7 @@ output/x rq->prq[0].rqe[0].b.b_data printf " length: " output/x rq->prq[0].rqe[0].b.b_bcount printf " drive offset: " -output/x rq->prq[0].rqe[0].b.b_blkno +output/x rq->prq[0].rqe[0].b.b_bio1.bio_blkno printf " subdisk offset: " output/x rq->prq[0].rqe[0].sdoffset printf "\nFlags: " @@ -88,7 +89,7 @@ output/x rq->prq[0].rqe[1].b.b_data printf " length: " output/x rq->prq[0].rqe[1].b.b_bcount printf " drive offset: " -output/x rq->prq[0].rqe[1].b.b_blkno +output/x rq->prq[0].rqe[1].b.b_bio1.bio_blkno printf " subdisk offset: " output/x rq->prq[0].rqe[1].sdoffset printf "\nFlags: " @@ -105,7 +106,7 @@ output/x rq->prq[1].rqe[0].b.b_data printf " length: " output/x rq->prq[1].rqe[0].b.b_bcount printf " drive offset: " -output/x rq->prq[1].rqe[0].b.b_blkno +output/x rq->prq[1].rqe[0].b.b_bio1.bio_blkno printf " subdisk offset: " output/x rq->prq[1].rqe[0].sdoffset printf "\nFlags: " @@ -116,7 +117,7 @@ printf "\nBuffer: device: " output/x rq->prq[1].rqe[1].b.b_dev printf " data: 0x%x length 0x%x drive offset 0x%x sd offset 0x%x\n" rq->prq[1].rqe[1].b.b_data, rq->prq[1].rqe[1].b.b_bcount, - rq->prq[1].rqe[1].b.b_blkno, + rq->prq[1].rqe[1].b.b_bio1.bio_blkno, rq->prq[1].rqe[1].sdoffset printf "\nFlags: " output/x rq->prq[1].rqe[1].b.b_flags @@ -186,7 +187,7 @@ define rqinfo else printf "1VS Write" end - printf "\t%p\t%d.%d\t0x%-9x\t%ld\n", $rqip->bp, $rqip->devmajor, $rqip->devminor & 0xff, $rqip->info.b.b_blkno, $rqip->info.b.b_bcount + printf "\t%p\t%d.%d\t0x%-9x\t%ld\n", $rqip->bp, $rqip->devmajor, $rqip->devminor & 0xff, $rqip->info.b.b_bio1.bio_blkno, $rqip->info.b.b_bcount end if ($rqip->type == loginfo_user_bpl) @@ -195,7 +196,7 @@ define rqinfo else printf "2LR Write" end - printf "\t%p\t%d.%d\t0x%-9x\t%ld\n", $rqip->bp, $rqip->devmajor, $rqip->devminor & 0xff, $rqip->info.b.b_blkno, $rqip->info.b.b_bcount + printf "\t%p\t%d.%d\t0x%-9x\t%ld\n", $rqip->bp, $rqip->devmajor, $rqip->devminor & 0xff, $rqip->info.b.b_bio1.bio_blkno, $rqip->info.b.b_bcount end if ($rqip->type == loginfo_rqe) @@ -204,7 +205,7 @@ define rqinfo else printf "3RQ Write" end - printf "\t%p\t%d.%d\t0x%-9x\t%ld\t%d\t%x\t%x\t%x\n", $rqip->bp, $rqip->devmajor, $rqip->devminor & 0xff, $rqip->info.rqe.b.b_blkno, $rqip->info.rqe.b.b_bcount, $rqip->info.rqe.sdno, $rqip->info.rqe.sdoffset, $rqip->info.rqe.dataoffset, $rqip->info.rqe.groupoffset + printf "\t%p\t%d.%d\t0x%-9x\t%ld\t%d\t%x\t%x\t%x\n", $rqip->bp, $rqip->devmajor, $rqip->devminor & 0xff, $rqip->info.rqe.b.b_bio1.bio_blkno, $rqip->info.rqe.b.b_bcount, $rqip->info.rqe.sdno, $rqip->info.rqe.sdoffset, $rqip->info.rqe.dataoffset, $rqip->info.rqe.groupoffset end if ($rqip->type == loginfo_iodone) @@ -213,7 +214,7 @@ define rqinfo else printf "4DN Write" end - printf "\t%p\t%d.%d\t0x%-9x\t%ld\t%d\t%x\t%x\t%x\n", $rqip->bp, $rqip->devmajor, $rqip->devminor & 0xff, $rqip->info.rqe.b.b_blkno, $rqip->info.rqe.b.b_bcount, $rqip->info.rqe.sdno, $rqip->info.rqe.sdoffset, $rqip->info.rqe.dataoffset, $rqip->info.rqe.groupoffset + printf "\t%p\t%d.%d\t0x%-9x\t%ld\t%d\t%x\t%x\t%x\n", $rqip->bp, $rqip->devmajor, $rqip->devminor & 0xff, $rqip->info.rqe.b.b_bio1.bio_blkno, $rqip->info.rqe.b.b_bcount, $rqip->info.rqe.sdno, $rqip->info.rqe.sdoffset, $rqip->info.rqe.dataoffset, $rqip->info.rqe.groupoffset end if ($rqip->type == loginfo_raid5_data) @@ -222,7 +223,7 @@ define rqinfo else printf "5RD Write" end - printf "\t%p\t%d.%d\t0x%-9x\t%ld\t%d\t%x\t%x\t%x\n", $rqip->bp, $rqip->devmajor, $rqip->devminor & 0xff, $rqip->info.rqe.b.b_blkno, $rqip->info.rqe.b.b_bcount, $rqip->info.rqe.sdno, $rqip->info.rqe.sdoffset, $rqip->info.rqe.dataoffset, $rqip->info.rqe.groupoffset + printf "\t%p\t%d.%d\t0x%-9x\t%ld\t%d\t%x\t%x\t%x\n", $rqip->bp, $rqip->devmajor, $rqip->devminor & 0xff, $rqip->info.rqe.b.b_bio1.bio_blkno, $rqip->info.rqe.b.b_bcount, $rqip->info.rqe.sdno, $rqip->info.rqe.sdoffset, $rqip->info.rqe.dataoffset, $rqip->info.rqe.groupoffset end if ($rqip->type == loginfo_raid5_parity) @@ -231,7 +232,7 @@ define rqinfo else printf "6RP Write" end - printf "\t%p\t%d.%d\t0x%-9x\t%ld\t%d\t%x\t%x\t%x\n", $rqip->bp, $rqip->devmajor, $rqip->devminor & 0xff, $rqip->info.rqe.b.b_blkno, $rqip->info.rqe.b.b_bcount, $rqip->info.rqe.sdno, $rqip->info.rqe.sdoffset, $rqip->info.rqe.dataoffset, $rqip->info.rqe.groupoffset + printf "\t%p\t%d.%d\t0x%-9x\t%ld\t%d\t%x\t%x\t%x\n", $rqip->bp, $rqip->devmajor, $rqip->devminor & 0xff, $rqip->info.rqe.b.b_bio1.bio_blkno, $rqip->info.rqe.b.b_bcount, $rqip->info.rqe.sdno, $rqip->info.rqe.sdoffset, $rqip->info.rqe.dataoffset, $rqip->info.rqe.groupoffset end if ($rqip->type == loginfo_sdio) @@ -240,7 +241,7 @@ define rqinfo else printf "7VS Write" end - printf "\t%p\t\t 0x%-9x\t%ld\t%d\n", $rqip->bp, $rqip->info.b.b_blkno, $rqip->info.b.b_bcount, $rqip->devminor & 0xff + printf "\t%p\t\t 0x%-9x\t%ld\t%d\n", $rqip->bp, $rqip->info.b.b_bio1.bio_blkno, $rqip->info.b.b_bcount, $rqip->devminor & 0xff end if ($rqip->type == loginfo_sdiol) @@ -249,7 +250,7 @@ define rqinfo else printf "8LR Write" end - printf "\t%p\t%d.%d\t0x%-9x\t%ld\n", $rqip->bp, $rqip->devmajor, $rqip->devminor & 0xff, $rqip->info.b.b_blkno, $rqip->info.b.b_bcount + printf "\t%p\t%d.%d\t0x%-9x\t%ld\n", $rqip->bp, $rqip->devmajor, $rqip->devminor & 0xff, $rqip->info.b.b_bio1.bio_blkno, $rqip->info.b.b_bcount end if ($rqip->type == loginfo_lockwait) @@ -270,7 +271,7 @@ define rqinfo else printf "9DN Write" end - printf "\t%p\t\t 0x%-9x\t%ld\t%d\n", $rqip->bp, $rqip->info.b.b_blkno, $rqip->info.b.b_bcount, $rqip->devminor + printf "\t%p\t\t 0x%-9x\t%ld\t%d\n", $rqip->bp, $rqip->info.b.b_bio1.bio_blkno, $rqip->info.b.b_bcount, $rqip->devminor end end diff --git a/sys/dev/raid/vinum/request.h b/sys/dev/raid/vinum/request.h index 2cb313b218..d7650c022c 100644 --- a/sys/dev/raid/vinum/request.h +++ b/sys/dev/raid/vinum/request.h @@ -35,7 +35,7 @@ * * $Id: request.h,v 1.19 2000/11/24 03:41:51 grog Exp grog $ * $FreeBSD: src/sys/dev/vinum/request.h,v 1.17.2.1 2001/03/13 02:59:42 grog Exp $ - * $DragonFly: src/sys/dev/raid/vinum/request.h,v 1.2 2003/06/17 04:28:33 dillon Exp $ + * $DragonFly: src/sys/dev/raid/vinum/request.h,v 1.3 2006/02/17 19:18:06 dillon Exp $ */ /* Information needed to set up a transfer */ @@ -129,7 +129,7 @@ struct rqgroup { * work we have to do to satisfy it. */ struct request { - struct buf *bp; /* pointer to the high-level request */ + struct bio *bio; /* pointer to the high-level request */ enum xferinfo flags; union { int volno; /* volume index */ @@ -150,7 +150,7 @@ struct request { */ struct sdbuf { struct buf b; /* our buffer */ - struct buf *bp; /* and pointer to parent */ + struct bio *bio; /* and pointer to parent */ short driveno; /* drive index */ short sdno; /* and subdisk index */ }; @@ -189,7 +189,7 @@ enum rqinfo_type { }; union rqinfou { /* info to pass to logrq */ - struct buf *bp; + struct bio *bio; struct rqelement *rqe; /* address of request, for correlation */ struct rangelock *lockinfo; }; @@ -197,11 +197,12 @@ union rqinfou { /* info to pass to logrq */ struct rqinfo { enum rqinfo_type type; /* kind of event */ struct timeval timestamp; /* time it happened */ - struct buf *bp; /* point to user buffer */ + struct bio *bio; /* point to user buffer */ int devmajor; /* major and minor device info */ int devminor; union { struct buf b; /* yup, the *whole* buffer header */ + struct bio bio; struct rqelement rqe; /* and the whole rqe */ struct rangelock lockinfo; } info; @@ -209,7 +210,7 @@ struct rqinfo { #define RQINFO_SIZE 128 /* number of info slots in buffer */ -void logrq(enum rqinfo_type type, union rqinfou info, struct buf *ubp); +void logrq(enum rqinfo_type type, union rqinfou info, struct bio *ubio); #endif /* Structures for the daemon */ diff --git a/sys/dev/raid/vinum/vinumdaemon.c b/sys/dev/raid/vinum/vinumdaemon.c index ab17339948..e25debcdc9 100644 --- a/sys/dev/raid/vinum/vinumdaemon.c +++ b/sys/dev/raid/vinum/vinumdaemon.c @@ -36,7 +36,7 @@ * * $Id: vinumdaemon.c,v 1.8 2000/01/03 05:22:03 grog Exp grog $ * $FreeBSD: src/sys/dev/vinum/vinumdaemon.c,v 1.16 2000/01/05 06:03:56 grog Exp $ - * $DragonFly: src/sys/dev/raid/vinum/vinumdaemon.c,v 1.7 2005/12/11 01:54:09 swildner Exp $ + * $DragonFly: src/sys/dev/raid/vinum/vinumdaemon.c,v 1.8 2006/02/17 19:18:06 dillon Exp $ */ #include "vinumhdr.h" @@ -106,11 +106,11 @@ vinum_daemon(void) log(LOG_WARNING, "vinum: recovering I/O request: %p\n%s dev %d.%d, offset 0x%x, length %ld\n", rq, - rq->bp->b_flags & B_READ ? "Read" : "Write", - major(rq->bp->b_dev), - minor(rq->bp->b_dev), - rq->bp->b_blkno, - rq->bp->b_bcount); + rq->bio->bio_buf->b_flags & B_READ ? "Read" : "Write", + major((dev_t)rq->bio->bio_driver_info), + minor((dev_t)rq->bio->bio_driver_info), + rq->bio->bio_blkno, + rq->bio->bio_buf->b_bcount); } recover_io(request->info.rq); /* the failed request */ break; @@ -201,11 +201,12 @@ recover_io(struct request *rq) /* * This should read: * - * vinumstrategy(rq->bp); + * vinumstrategy(rq->bio); * * Negotiate with phk to get it fixed. + * Reissue the command. */ - BUF_STRATEGY(rq->bp, 0); /* reissue the command */ + dev_dstrategy((dev_t)rq->bio->bio_driver_info, rq->bio); } /* Functions called to interface with the daemon */ diff --git a/sys/dev/raid/vinum/vinumext.h b/sys/dev/raid/vinum/vinumext.h index f9d953fd1d..bc9c883620 100644 --- a/sys/dev/raid/vinum/vinumext.h +++ b/sys/dev/raid/vinum/vinumext.h @@ -35,7 +35,7 @@ * * $Id: vinumext.h,v 1.26 2000/05/16 07:38:08 grog Exp grog $ * $FreeBSD: src/sys/dev/vinum/vinumext.h,v 1.25.2.3 2001/05/11 02:11:06 grog Exp $ - * $DragonFly: src/sys/dev/raid/vinum/vinumext.h,v 1.5 2005/01/27 02:43:12 joerg Exp $ + * $DragonFly: src/sys/dev/raid/vinum/vinumext.h,v 1.6 2006/02/17 19:18:06 dillon Exp $ */ /* vinumext.h: external definitions */ @@ -139,9 +139,9 @@ d_ioctl_t vinumioctl; d_dump_t vinumdump; d_psize_t vinumsize; -int vinumstart(struct buf *bp, int reviveok); +int vinumstart(dev_t dev, struct bio *bio, int reviveok); int launch_requests(struct request *rq, int reviveok); -void sdio(struct buf *bp); +void sdio(struct bio *bio); /* XXX Do we need this? */ int vinumpart(dev_t); diff --git a/sys/dev/raid/vinum/vinuminterrupt.c b/sys/dev/raid/vinum/vinuminterrupt.c index 9d3ac0f97f..ee07ab13d2 100644 --- a/sys/dev/raid/vinum/vinuminterrupt.c +++ b/sys/dev/raid/vinum/vinuminterrupt.c @@ -41,7 +41,7 @@ * * $Id: vinuminterrupt.c,v 1.12 2000/11/24 03:41:42 grog Exp grog $ * $FreeBSD: src/sys/dev/vinum/vinuminterrupt.c,v 1.25.2.3 2001/05/28 05:56:27 grog Exp $ - * $DragonFly: src/sys/dev/raid/vinum/vinuminterrupt.c,v 1.5 2005/09/16 04:33:14 dillon Exp $ + * $DragonFly: src/sys/dev/raid/vinum/vinuminterrupt.c,v 1.6 2006/02/17 19:18:06 dillon Exp $ */ #include "vinumhdr.h" @@ -49,8 +49,8 @@ #include void complete_raid5_write(struct rqelement *); -void complete_rqe(struct buf *bp); -void sdio_done(struct buf *bp); +void complete_rqe(struct bio *bio); +void sdio_done(struct bio *bio); /* * Take a completed buffer, transfer the data back if @@ -61,12 +61,13 @@ void sdio_done(struct buf *bp); * includes a couple of extras at the end. */ void -complete_rqe(struct buf *bp) +complete_rqe(struct bio *bio) { + struct buf *bp = bio->bio_buf; struct rqelement *rqe; struct request *rq; struct rqgroup *rqg; - struct buf *ubp; /* user buffer */ + struct bio *ubio; /* user buffer */ struct drive *drive; struct sd *sd; char *gravity; /* for error messages */ @@ -74,11 +75,11 @@ complete_rqe(struct buf *bp) rqe = (struct rqelement *) bp; /* point to the element that completed */ rqg = rqe->rqg; /* and the request group */ rq = rqg->rq; /* and the complete request */ - ubp = rq->bp; /* user buffer */ + ubio = rq->bio; /* user buffer */ #ifdef VINUMDEBUG if (debug & DEBUG_LASTREQS) - logrq(loginfo_iodone, (union rqinfou) rqe, ubp); + logrq(loginfo_iodone, (union rqinfou) rqe, ubio); #endif drive = &DRIVE[rqe->driveno]; drive->active--; /* one less outstanding I/O on this drive */ @@ -104,7 +105,7 @@ complete_rqe(struct buf *bp) "%s:%s read error, block %d for %ld bytes\n", gravity, sd->name, - bp->b_blkno, + bio->bio_blkno, bp->b_bcount); } else { /* write operation */ if ((rq->error == ENXIO) || (sd->flags & VF_RETRYERRORS) == 0) { @@ -115,19 +116,19 @@ complete_rqe(struct buf *bp) "%s:%s write error, block %d for %ld bytes\n", gravity, sd->name, - bp->b_blkno, + bio->bio_blkno, bp->b_bcount); } log(LOG_ERR, "%s: user buffer block %d for %ld bytes\n", sd->name, - ubp->b_blkno, - ubp->b_bcount); + ubio->bio_blkno, + ubio->bio_buf->b_bcount); if (rq->error == ENXIO) { /* the drive's down too */ log(LOG_ERR, "%s: fatal drive I/O error, block %d for %ld bytes\n", DRIVE[rqe->driveno].label.name, - bp->b_blkno, + bio->bio_blkno, bp->b_bcount); DRIVE[rqe->driveno].lasterror = rq->error; set_drive_state(rqe->driveno, /* take the drive down */ @@ -184,7 +185,7 @@ complete_rqe(struct buf *bp) char *src = &rqe->b.b_data[rqe->dataoffset << DEV_BSHIFT]; /* read data is here */ char *dst; - dst = (char *) ubp->b_data + (rqe->useroffset << DEV_BSHIFT); /* where to put it in user buffer */ + dst = (char *) ubio->bio_buf->b_data + (rqe->useroffset << DEV_BSHIFT); /* where to put it in user buffer */ length = rqe->datalen << DEV_BSHIFT; /* and count involved */ bcopy(src, dst, length); /* move it */ } @@ -208,22 +209,22 @@ complete_rqe(struct buf *bp) if (rq->active == 0) { /* request finished, */ #ifdef VINUMDEBUG if (debug & DEBUG_RESID) { - if (ubp->b_resid != 0) /* still something to transfer? */ + if (ubio->bio_buf->b_resid != 0) /* still something to transfer? */ Debugger("resid"); } #endif if (rq->error) { /* did we have an error? */ if (rq->isplex) { /* plex operation, */ - ubp->b_flags |= B_ERROR; /* yes, propagate to user */ - ubp->b_error = rq->error; + ubio->bio_buf->b_flags |= B_ERROR; /* yes, propagate to user */ + ubio->bio_buf->b_error = rq->error; } else /* try to recover */ queue_daemon_request(daemonrq_ioerror, (union daemoninfo) rq); /* let the daemon complete */ } else { - ubp->b_resid = 0; /* completed our transfer */ + ubio->bio_buf->b_resid = 0; /* completed our transfer */ if (rq->isplex == 0) /* volume request, */ VOL[rq->volplex.volno].active--; /* another request finished */ - biodone(ubp); /* top level buffer completed */ + biodone(ubio); /* top level buffer completed */ freerq(rq); /* return the request storage */ } } @@ -257,22 +258,22 @@ freerq(struct request *rq) /* I/O on subdisk completed */ void -sdio_done(struct buf *bp) +sdio_done(struct bio *bio) { struct sdbuf *sbp; - sbp = (struct sdbuf *) bp; + sbp = (struct sdbuf *) bio->bio_buf; if (sbp->b.b_flags & B_ERROR) { /* had an error */ - sbp->bp->b_flags |= B_ERROR; /* propagate upwards */ - sbp->bp->b_error = sbp->b.b_error; + sbp->bio->bio_buf->b_flags |= B_ERROR; /* propagate upwards */ + sbp->bio->bio_buf->b_error = sbp->b.b_error; } #ifdef VINUMDEBUG if (debug & DEBUG_LASTREQS) - logrq(loginfo_sdiodone, (union rqinfou) bp, bp); + logrq(loginfo_sdiodone, (union rqinfou)bio, bio); #endif - sbp->bp->b_resid = sbp->b.b_resid; /* copy the resid field */ + sbp->bio->bio_buf->b_resid = sbp->b.b_resid; /* copy the resid field */ /* Now update the statistics */ - if (bp->b_flags & B_READ) { /* read operation */ + if (sbp->b.b_flags & B_READ) { /* read operation */ DRIVE[sbp->driveno].reads++; DRIVE[sbp->driveno].bytes_read += sbp->b.b_bcount; SD[sbp->sdno].reads++; @@ -283,7 +284,7 @@ sdio_done(struct buf *bp) SD[sbp->sdno].writes++; SD[sbp->sdno].bytes_written += sbp->b.b_bcount; } - biodone(sbp->bp); /* complete the caller's I/O */ + biodone(sbp->bio); /* complete the caller's I/O */ BUF_UNLOCK(&sbp->b); BUF_LOCKFREE(&sbp->b); Free(sbp); @@ -299,15 +300,16 @@ complete_raid5_write(struct rqelement *rqe) int count; /* loop counter */ int rqno; /* request index */ int rqoffset; /* offset of request data from parity data */ - struct buf *ubp; /* user buffer header */ + struct bio *ubio; /* user buffer header */ struct request *rq; /* pointer to our request */ struct rqgroup *rqg; /* and to the request group */ struct rqelement *prqe; /* point to the parity block */ struct drive *drive; /* drive to access */ + dev_t dev; rqg = rqe->rqg; /* and to our request group */ rq = rqg->rq; /* point to our request */ - ubp = rq->bp; /* user's buffer header */ + ubio = rq->bio; /* user's buffer header */ prqe = &rqg->rqe[0]; /* point to the parity block */ /* @@ -368,9 +370,9 @@ complete_raid5_write(struct rqelement *rqe) pdata[count] ^= sdata[count]; /* "add" the new data block */ - sdata = (int *) (&ubp->b_data[rqe->useroffset << DEV_BSHIFT]); /* new data */ - if ((sdata < ((int *) ubp->b_data)) - || (&sdata[length] > ((int *) (ubp->b_data + ubp->b_bcount)))) + sdata = (int *) (&ubio->bio_buf->b_data[rqe->useroffset << DEV_BSHIFT]); /* new data */ + if ((sdata < ((int *) ubio->bio_buf->b_data)) + || (&sdata[length] > ((int *) (ubio->bio_buf->b_data + ubio->bio_buf->b_bcount)))) panic("complete_raid5_write: bounds overflow"); for (count = 0; count < length; count++) pdata[count] ^= sdata[count]; @@ -385,14 +387,15 @@ complete_raid5_write(struct rqelement *rqe) if ((rqe->b.b_flags & B_READ) /* this was a read */ &&((rqe->flags & XFR_BAD_SUBDISK) == 0)) { /* and we can write this block */ rqe->b.b_flags &= ~(B_READ | B_DONE); /* we're writing now */ - rqe->b.b_iodone = complete_rqe; /* by calling us here */ + rqe->b.b_bio1.bio_done = complete_rqe; /* by calling us here */ rqe->flags &= ~XFR_PARITYOP; /* reset flags that brought us here */ - rqe->b.b_data = &ubp->b_data[rqe->useroffset << DEV_BSHIFT]; /* point to the user data */ + rqe->b.b_data = &ubio->bio_buf->b_data[rqe->useroffset << DEV_BSHIFT]; /* point to the user data */ rqe->b.b_bcount = rqe->datalen << DEV_BSHIFT; /* length to write */ rqe->b.b_bufsize = rqe->b.b_bcount; /* don't claim more */ rqe->b.b_resid = rqe->b.b_bcount; /* nothing transferred */ - rqe->b.b_blkno += rqe->dataoffset; /* point to the correct block */ - rqe->b.b_dev = DRIVE[rqe->driveno].dev; + rqe->b.b_bio1.bio_blkno += rqe->dataoffset; /* point to the correct block */ + dev = DRIVE[rqe->driveno].dev; + rqe->b.b_bio1.bio_driver_info = dev; rqg->active++; /* another active request */ drive = &DRIVE[rqe->driveno]; /* drive to access */ @@ -408,16 +411,16 @@ complete_raid5_write(struct rqelement *rqe) log(LOG_DEBUG, " %s dev %d.%d, sd %d, offset 0x%x, devoffset 0x%x, length %ld\n", rqe->b.b_flags & B_READ ? "Read" : "Write", - major(rqe->b.b_dev), - minor(rqe->b.b_dev), + major(dev), + minor(dev), rqe->sdno, - (u_int) (rqe->b.b_blkno - SD[rqe->sdno].driveoffset), - rqe->b.b_blkno, + (u_int) (rqe->b.b_bio1.bio_blkno - SD[rqe->sdno].driveoffset), + rqe->b.b_bio1.bio_blkno, rqe->b.b_bcount); if (debug & DEBUG_LASTREQS) - logrq(loginfo_raid5_data, (union rqinfou) rqe, ubp); + logrq(loginfo_raid5_data, (union rqinfou) rqe, ubio); #endif - BUF_STRATEGY(&rqe->b, 0); + dev_dstrategy(dev, &rqe->b.b_bio1); } } } @@ -425,12 +428,13 @@ complete_raid5_write(struct rqelement *rqe) /* Finally, write the parity block */ rqe = &rqg->rqe[0]; rqe->b.b_flags &= ~(B_READ | B_DONE); /* we're writing now */ - rqe->b.b_iodone = complete_rqe; /* by calling us here */ + rqe->b.b_bio1.bio_done = complete_rqe; /* by calling us here */ rqg->flags &= ~XFR_PARITYOP; /* reset flags that brought us here */ rqe->b.b_bcount = rqe->buflen << DEV_BSHIFT; /* length to write */ rqe->b.b_bufsize = rqe->b.b_bcount; /* don't claim we have more */ rqe->b.b_resid = rqe->b.b_bcount; /* nothing transferred */ - rqe->b.b_dev = DRIVE[rqe->driveno].dev; + dev = DRIVE[rqe->driveno].dev; + rqe->b.b_bio1.bio_driver_info = dev; rqg->active++; /* another active request */ drive = &DRIVE[rqe->driveno]; /* drive to access */ @@ -447,16 +451,16 @@ complete_raid5_write(struct rqelement *rqe) log(LOG_DEBUG, " %s dev %d.%d, sd %d, offset 0x%x, devoffset 0x%x, length %ld\n", rqe->b.b_flags & B_READ ? "Read" : "Write", - major(rqe->b.b_dev), - minor(rqe->b.b_dev), + major(dev), + minor(dev), rqe->sdno, - (u_int) (rqe->b.b_blkno - SD[rqe->sdno].driveoffset), - rqe->b.b_blkno, + (u_int) (rqe->b.b_bio1.bio_blkno - SD[rqe->sdno].driveoffset), + rqe->b.b_bio1.bio_blkno, rqe->b.b_bcount); if (debug & DEBUG_LASTREQS) - logrq(loginfo_raid5_parity, (union rqinfou) rqe, ubp); + logrq(loginfo_raid5_parity, (union rqinfou) rqe, ubio); #endif - BUF_STRATEGY(&rqe->b, 0); + dev_dstrategy(dev, &rqe->b.b_bio1); } /* Local Variables: */ diff --git a/sys/dev/raid/vinum/vinumio.c b/sys/dev/raid/vinum/vinumio.c index b4ed4f1714..e8ab7fa593 100644 --- a/sys/dev/raid/vinum/vinumio.c +++ b/sys/dev/raid/vinum/vinumio.c @@ -35,7 +35,7 @@ * * $Id: vinumio.c,v 1.30 2000/05/10 23:23:30 grog Exp grog $ * $FreeBSD: src/sys/dev/vinum/vinumio.c,v 1.52.2.6 2002/05/02 08:43:44 grog Exp $ - * $DragonFly: src/sys/dev/raid/vinum/vinumio.c,v 1.9 2005/09/16 04:33:14 dillon Exp $ + * $DragonFly: src/sys/dev/raid/vinum/vinumio.c,v 1.10 2006/02/17 19:18:06 dillon Exp $ */ #include "vinumhdr.h" @@ -324,12 +324,11 @@ driveio(struct drive *drive, char *buf, size_t length, off_t offset, int flag) bp = geteblk(len); /* get a buffer header */ bp->b_flags = flag; - bp->b_dev = drive->dev; /* device */ - bp->b_blkno = offset / drive->partinfo.disklab->d_secsize; /* block number */ + bp->b_bio1.bio_blkno = offset / drive->partinfo.disklab->d_secsize; /* block number */ bp->b_saveaddr = bp->b_data; bp->b_data = buf; bp->b_bcount = len; - BUF_STRATEGY(bp, 0); /* initiate the transfer */ + dev_dstrategy(drive->dev, &bp->b_bio1); error = biowait(bp); bp->b_data = bp->b_saveaddr; bp->b_flags |= B_INVAL | B_AGE; @@ -794,8 +793,7 @@ write_volume_label(int volno) */ bp = geteblk((int) lp->d_secsize); /* get a buffer */ dev = make_adhoc_dev(&vinum_cdevsw, vol->volno); - bp->b_dev = dev; - bp->b_blkno = LABELSECTOR * ((int) lp->d_secsize / DEV_BSIZE); + bp->b_bio1.bio_blkno = LABELSECTOR * ((int) lp->d_secsize / DEV_BSIZE); bp->b_bcount = lp->d_secsize; bzero(bp->b_data, lp->d_secsize); dlp = (struct disklabel *) bp->b_data; @@ -810,7 +808,7 @@ write_volume_label(int volno) * * Negotiate with phk to get it fixed. */ - BUF_STRATEGY(bp, 0); + dev_dstrategy(dev, &bp->b_bio1); error = biowait(bp); bp->b_flags |= B_INVAL | B_AGE; bp->b_flags &= ~B_ERROR; diff --git a/sys/dev/raid/vinum/vinumlock.c b/sys/dev/raid/vinum/vinumlock.c index 9fa752bbee..489afe2ccf 100644 --- a/sys/dev/raid/vinum/vinumlock.c +++ b/sys/dev/raid/vinum/vinumlock.c @@ -39,7 +39,7 @@ * * $Id: vinumlock.c,v 1.13 2000/05/02 23:25:02 grog Exp grog $ * $FreeBSD: src/sys/dev/vinum/vinumlock.c,v 1.18.2.3 2001/04/04 06:27:11 grog Exp $ - * $DragonFly: src/sys/dev/raid/vinum/vinumlock.c,v 1.5 2005/06/11 00:05:46 dillon Exp $ + * $DragonFly: src/sys/dev/raid/vinum/vinumlock.c,v 1.6 2006/02/17 19:18:06 dillon Exp $ */ #include "vinumhdr.h" @@ -161,7 +161,7 @@ lockrange(daddr_t stripe, struct buf *bp, struct plex *plex) info.stripe = stripe; info.bp = bp; - logrq(loginfo_lockwait, (union rqinfou) &info, bp); + logrq(loginfo_lockwait, (union rqinfou) &info, &bp->b_bio1); } #endif plex->lockwaits++; /* waited one more time */ @@ -192,7 +192,7 @@ lockrange(daddr_t stripe, struct buf *bp, struct plex *plex) crit_exit(); #ifdef VINUMDEBUG if (debug & DEBUG_LASTREQS) - logrq(loginfo_lock, (union rqinfou) pos, bp); + logrq(loginfo_lock, (union rqinfou) pos, &bp->b_bio1); #endif return pos; } @@ -214,7 +214,7 @@ unlockrange(int plexno, struct rangelock *lock) #endif #ifdef VINUMDEBUG if (debug & DEBUG_LASTREQS) - logrq(loginfo_unlock, (union rqinfou) lock, lock->bp); + logrq(loginfo_unlock, (union rqinfou) lock, &lock->bp->b_bio1); #endif lock->stripe = 0; /* no longer used */ plex->usedlocks--; /* one less lock */ diff --git a/sys/dev/raid/vinum/vinumraid5.c b/sys/dev/raid/vinum/vinumraid5.c index e21a9d4e6b..02e3ab5bda 100644 --- a/sys/dev/raid/vinum/vinumraid5.c +++ b/sys/dev/raid/vinum/vinumraid5.c @@ -40,7 +40,7 @@ * * $Id: vinumraid5.c,v 1.21 2001/01/09 04:21:27 grog Exp grog $ * $FreeBSD: src/sys/dev/vinum/vinumraid5.c,v 1.6.2.2 2001/03/13 02:59:43 grog Exp $ - * $DragonFly: src/sys/dev/raid/vinum/vinumraid5.c,v 1.3 2003/08/07 21:17:09 dillon Exp $ + * $DragonFly: src/sys/dev/raid/vinum/vinumraid5.c,v 1.4 2006/02/17 19:18:06 dillon Exp $ */ #include "vinumhdr.h" #include "request.h" @@ -124,7 +124,8 @@ bre5(struct request *rq, struct metrics m; /* most of the information */ struct sd *sd; struct plex *plex; - struct buf *bp; /* user's bp */ + struct bio *bio; /* user's bp */ + struct buf *bp; struct rqgroup *rqg; /* the request group that we will create */ struct rqelement *rqe; /* point to this request information */ int rsectors; /* sectors remaining in this stripe */ @@ -133,7 +134,8 @@ bre5(struct request *rq, rqg = NULL; /* shut up, damn compiler */ m.diskstart = *diskaddr; /* start of transfer */ - bp = rq->bp; /* buffer pointer */ + bio = rq->bio; /* buffer pointer */ + bp = bio->bio_buf; plex = &PLEX[plexno]; /* point to the plex */ diff --git a/sys/dev/raid/vinum/vinumrequest.c b/sys/dev/raid/vinum/vinumrequest.c index 041718b9bd..a5194c07ca 100644 --- a/sys/dev/raid/vinum/vinumrequest.c +++ b/sys/dev/raid/vinum/vinumrequest.c @@ -39,7 +39,7 @@ * * $Id: vinumrequest.c,v 1.30 2001/01/09 04:20:55 grog Exp grog $ * $FreeBSD: src/sys/dev/vinum/vinumrequest.c,v 1.44.2.5 2002/08/28 04:30:56 grog Exp $ - * $DragonFly: src/sys/dev/raid/vinum/vinumrequest.c,v 1.6 2005/08/03 16:36:33 hmp Exp $ + * $DragonFly: src/sys/dev/raid/vinum/vinumrequest.c,v 1.7 2006/02/17 19:18:06 dillon Exp $ */ #include "vinumhdr.h" @@ -59,11 +59,11 @@ enum requeststatus build_write_request(struct request *rq); enum requeststatus build_rq_buffer(struct rqelement *rqe, struct plex *plex); int find_alternate_sd(struct request *rq); int check_range_covered(struct request *); -void complete_rqe(struct buf *bp); +void complete_rqe(struct bio *bio); void complete_raid5_write(struct rqelement *); int abortrequest(struct request *rq, int error); -void sdio_done(struct buf *bp); -int vinum_bounds_check(struct buf *bp, struct volume *vol); +void sdio_done(struct bio *bio); +struct bio *vinum_bounds_check(struct bio *bio, struct volume *vol); caddr_t allocdatabuf(struct rqelement *rqe); void freedatabuf(struct rqelement *rqe); @@ -72,22 +72,26 @@ struct rqinfo rqinfo[RQINFO_SIZE]; struct rqinfo *rqip = rqinfo; void -logrq(enum rqinfo_type type, union rqinfou info, struct buf *ubp) +logrq(enum rqinfo_type type, union rqinfou info, struct bio *ubio) { + dev_t dev; + crit_enter(); microtime(&rqip->timestamp); /* when did this happen? */ rqip->type = type; - rqip->bp = ubp; /* user buffer */ + rqip->bio = ubio; /* user buffer */ + switch (type) { case loginfo_user_bp: case loginfo_user_bpl: case loginfo_sdio: /* subdisk I/O */ case loginfo_sdiol: /* subdisk I/O launch */ case loginfo_sdiodone: /* subdisk I/O complete */ - bcopy(info.bp, &rqip->info.b, sizeof(struct buf)); - rqip->devmajor = major(info.bp->b_dev); - rqip->devminor = minor(info.bp->b_dev); + bcopy(info.bio, &rqip->info.bio, sizeof(struct bio)); + dev = info.bio->bio_driver_info; + rqip->devmajor = major(dev); + rqip->devminor = minor(dev); break; case loginfo_iodone: @@ -95,8 +99,9 @@ logrq(enum rqinfo_type type, union rqinfou info, struct buf *ubp) case loginfo_raid5_data: case loginfo_raid5_parity: bcopy(info.rqe, &rqip->info.rqe, sizeof(struct rqelement)); - rqip->devmajor = major(info.rqe->b.b_dev); - rqip->devminor = minor(info.rqe->b.b_dev); + dev = info.rqe->b.b_bio1.bio_driver_info; + rqip->devmajor = major(dev); + rqip->devminor = minor(dev); break; case loginfo_lockwait: @@ -118,15 +123,18 @@ logrq(enum rqinfo_type type, union rqinfou info, struct buf *ubp) #endif void -vinumstrategy(struct buf *bp) +vinumstrategy(dev_t dev, struct bio *bio) { - int volno; + struct buf *bp = bio->bio_buf; + struct bio *nbio = bio; struct volume *vol = NULL; + int volno; - switch (DEVTYPE(bp->b_dev)) { + switch (DEVTYPE(dev)) { case VINUM_SD_TYPE: case VINUM_RAWSD_TYPE: - sdio(bp); + bio->bio_driver_info = dev; + sdio(bio); return; /* @@ -137,20 +145,21 @@ vinumstrategy(struct buf *bp) default: bp->b_error = EIO; /* I/O error */ bp->b_flags |= B_ERROR; - biodone(bp); + biodone(bio); return; case VINUM_VOLUME_TYPE: /* volume I/O */ - volno = Volno(bp->b_dev); + volno = Volno(dev); vol = &VOL[volno]; if (vol->state != volume_up) { /* can't access this volume */ bp->b_error = EIO; /* I/O error */ bp->b_flags |= B_ERROR; - biodone(bp); + biodone(bio); return; } - if (vinum_bounds_check(bp, vol) <= 0) { /* don't like them bounds */ - biodone(bp); + nbio = vinum_bounds_check(bio, vol); + if (nbio == NULL) { + biodone(bio); return; } /* FALLTHROUGH */ @@ -162,7 +171,7 @@ vinumstrategy(struct buf *bp) case VINUM_PLEX_TYPE: case VINUM_RAWPLEX_TYPE: bp->b_resid = bp->b_bcount; /* transfer everything */ - vinumstart(bp, 0); + vinumstart(dev, nbio, 0); return; } } @@ -178,30 +187,33 @@ vinumstrategy(struct buf *bp) * a currently active revive operation. */ int -vinumstart(struct buf *bp, int reviveok) +vinumstart(dev_t dev, struct bio *bio, int reviveok) { + struct buf *bp = bio->bio_buf; int plexno; int maxplex; /* maximum number of plexes to handle */ struct volume *vol; struct request *rq; /* build up our request here */ enum requeststatus status; + bio->bio_driver_info = dev; + #if VINUMDEBUG if (debug & DEBUG_LASTREQS) - logrq(loginfo_user_bp, (union rqinfou) bp, bp); + logrq(loginfo_user_bp, (union rqinfou) bio, bio); #endif if ((bp->b_bcount % DEV_BSIZE) != 0) { /* bad length */ bp->b_error = EINVAL; /* invalid size */ bp->b_flags |= B_ERROR; - biodone(bp); + biodone(bio); return -1; } rq = (struct request *) Malloc(sizeof(struct request)); /* allocate a request struct */ if (rq == NULL) { /* can't do it */ bp->b_error = ENOMEM; /* can't get memory */ bp->b_flags |= B_ERROR; - biodone(bp); + biodone(bio); return -1; } bzero(rq, sizeof(struct request)); @@ -211,16 +223,16 @@ vinumstart(struct buf *bp, int reviveok) * the request building functions use as an * indication for single plex I/O */ - rq->bp = bp; /* and the user buffer struct */ + rq->bio = bio; /* and the user buffer struct */ - if (DEVTYPE(bp->b_dev) == VINUM_VOLUME_TYPE) { /* it's a volume, */ - rq->volplex.volno = Volno(bp->b_dev); /* get the volume number */ + if (DEVTYPE(dev) == VINUM_VOLUME_TYPE) { /* it's a volume, */ + rq->volplex.volno = Volno(dev); /* get the volume number */ vol = &VOL[rq->volplex.volno]; /* and point to it */ vol->active++; /* one more active request */ maxplex = vol->plexes; /* consider all its plexes */ } else { vol = NULL; /* no volume */ - rq->volplex.plexno = Plexno(bp->b_dev); /* point to the plex */ + rq->volplex.plexno = Plexno(dev); /* point to the plex */ rq->isplex = 1; /* note that it's a plex */ maxplex = 1; /* just the one plex */ } @@ -246,7 +258,7 @@ vinumstart(struct buf *bp, int reviveok) } status = build_read_request(rq, plexno); /* build a request */ } else { - daddr_t diskaddr = bp->b_blkno; /* start offset of transfer */ + daddr_t diskaddr = bio->bio_blkno; /* start offset of transfer */ status = bre(rq, /* build a request list */ rq->volplex.plexno, &diskaddr, @@ -258,7 +270,7 @@ vinumstart(struct buf *bp, int reviveok) bp->b_error = EIO; /* I/O error */ bp->b_flags |= B_ERROR; } - biodone(bp); + biodone(bio); freerq(rq); return -1; } @@ -274,18 +286,18 @@ vinumstart(struct buf *bp, int reviveok) else { /* plex I/O */ daddr_t diskstart; - diskstart = bp->b_blkno; /* start offset of transfer */ + diskstart = bio->bio_blkno; /* start offset of transfer */ status = bre(rq, - Plexno(bp->b_dev), + Plexno(dev), &diskstart, - bp->b_blkno + (bp->b_bcount / DEV_BSIZE)); /* build requests for the plex */ + bio->bio_blkno + (bp->b_bcount / DEV_BSIZE)); /* build requests for the plex */ } if (status > REQUEST_RECOVERED) { /* can't satisfy it */ if (status == REQUEST_DOWN) { /* not enough subdisks */ bp->b_error = EIO; /* I/O error */ bp->b_flags |= B_ERROR; } - biodone(bp); + biodone(bio); freerq(rq); return -1; } @@ -328,16 +340,17 @@ launch_requests(struct request *rq, int reviveok) sd->waitlist = rq; /* hook our request at the front */ #if VINUMDEBUG - if (debug & DEBUG_REVIVECONFLICT) + if (debug & DEBUG_REVIVECONFLICT) { log(LOG_DEBUG, "Revive conflict sd %d: %p\n%s dev %d.%d, offset 0x%x, length %ld\n", rq->sdno, rq, - rq->bp->b_flags & B_READ ? "Read" : "Write", - major(rq->bp->b_dev), - minor(rq->bp->b_dev), - rq->bp->b_blkno, - rq->bp->b_bcount); + rq->bio->bio_buf->b_flags & B_READ ? "Read" : "Write", + major(((dev_t)rq->bio->bio_driver_info)), + minor(((dev_t)rq->bio->bio_driver_info)), + rq->bio->bio_blkno, + rq->bio->bio_buf->b_bcount); + } #endif return 0; /* and get out of here */ } @@ -347,15 +360,15 @@ launch_requests(struct request *rq, int reviveok) log(LOG_DEBUG, "Request: %p\n%s dev %d.%d, offset 0x%x, length %ld\n", rq, - rq->bp->b_flags & B_READ ? "Read" : "Write", - major(rq->bp->b_dev), - minor(rq->bp->b_dev), - rq->bp->b_blkno, - rq->bp->b_bcount); + rq->bio->bio_buf->b_flags & B_READ ? "Read" : "Write", + major(((dev_t)rq->bio->bio_driver_info)), + minor(((dev_t)rq->bio->bio_driver_info)), + rq->bio->bio_blkno, + rq->bio->bio_buf->b_bcount); vinum_conf.lastrq = rq; - vinum_conf.lastbuf = rq->bp; + vinum_conf.lastbio = rq->bio; if (debug & DEBUG_LASTREQS) - logrq(loginfo_user_bpl, (union rqinfou) rq->bp, rq->bp); + logrq(loginfo_user_bpl, (union rqinfou) rq->bio, rq->bio); #endif /* @@ -382,9 +395,11 @@ launch_requests(struct request *rq, int reviveok) crit_enter(); for (rqg = rq->rqg; rqg != NULL;) { /* through the whole request chain */ if (rqg->lockbase >= 0) /* this rqg needs a lock first */ - rqg->lock = lockrange(rqg->lockbase, rqg->rq->bp, &PLEX[rqg->plexno]); + rqg->lock = lockrange(rqg->lockbase, rqg->rq->bio->bio_buf, &PLEX[rqg->plexno]); rcount = rqg->count; for (rqno = 0; rqno < rcount;) { + dev_t dev; + rqe = &rqg->rqe[rqno]; /* @@ -402,22 +417,23 @@ launch_requests(struct request *rq, int reviveok) if (vinum_conf.active >= vinum_conf.maxactive) vinum_conf.maxactive = vinum_conf.active; + dev = rqe->b.b_bio1.bio_driver_info; #ifdef VINUMDEBUG if (debug & DEBUG_ADDRESSES) log(LOG_DEBUG, " %s dev %d.%d, sd %d, offset 0x%x, devoffset 0x%x, length %ld\n", rqe->b.b_flags & B_READ ? "Read" : "Write", - major(rqe->b.b_dev), - minor(rqe->b.b_dev), + major(dev), + minor(dev), rqe->sdno, - (u_int) (rqe->b.b_blkno - SD[rqe->sdno].driveoffset), - rqe->b.b_blkno, + (u_int) (rqe->b.b_bio1.bio_blkno - SD[rqe->sdno].driveoffset), + rqe->b.b_bio1.bio_blkno, rqe->b.b_bcount); if (debug & DEBUG_LASTREQS) - logrq(loginfo_rqe, (union rqinfou) rqe, rq->bp); + logrq(loginfo_rqe, (union rqinfou) rqe, rq->bio); #endif /* fire off the request */ - BUF_STRATEGY(&rqe->b, 0); + dev_dstrategy(dev, &rqe->b.b_bio1); } } } @@ -453,6 +469,7 @@ bre(struct request *rq, int sdno; struct sd *sd; struct rqgroup *rqg; + struct bio *bio; struct buf *bp; /* user's bp */ struct plex *plex; enum requeststatus status; /* return value */ @@ -464,7 +481,8 @@ bre(struct request *rq, daddr_t diskstart = *diskaddr; /* remember where this transfer starts */ enum requeststatus s; /* temp return value */ - bp = rq->bp; /* buffer pointer */ + bio = rq->bio; /* buffer pointer */ + bp = bio->bio_buf; status = REQUEST_OK; /* return value: OK until proven otherwise */ plex = &PLEX[plexno]; /* point to the plex */ @@ -502,7 +520,7 @@ bre(struct request *rq, s = checksdstate(sd, rq, *diskaddr, diskend); /* do we need to change state? */ if (s == REQUEST_DOWN) { /* down? */ rqe->flags = XFR_BAD_SUBDISK; /* yup */ - if (rq->bp->b_flags & B_READ) /* read request, */ + if (rq->bio->bio_buf->b_flags & B_READ) /* read request, */ return REQUEST_DEGRADED; /* give up here */ /* * If we're writing, don't give up @@ -584,7 +602,7 @@ bre(struct request *rq, s = checksdstate(sd, rq, *diskaddr, diskend); /* do we need to change state? */ if (s == REQUEST_DOWN) { /* down? */ rqe->flags = XFR_BAD_SUBDISK; /* yup */ - if (rq->bp->b_flags & B_READ) /* read request, */ + if (rq->bio->bio_buf->b_flags & B_READ) /* read request, */ return REQUEST_DEGRADED; /* give up here */ /* * If we're writing, don't give up @@ -613,7 +631,7 @@ bre(struct request *rq, plex->name, sd->name, (u_int) sd->sectors, - bp->b_blkno); + bp->b_bio1.bio_blkno); log(LOG_DEBUG, "vinum: stripebase %x, stripeoffset %x, blockoffset %x\n", stripebase, @@ -665,6 +683,7 @@ enum requeststatus build_read_request(struct request *rq, /* request */ int plexindex) { /* index in the volume's plex table */ + struct bio *bio; struct buf *bp; daddr_t startaddr; /* offset of previous part of transfer */ daddr_t diskaddr; /* offset of current part of transfer */ @@ -676,8 +695,9 @@ build_read_request(struct request *rq, /* request */ enum requeststatus status = REQUEST_OK; int plexmask; /* bit mask of plexes, for recovery */ - bp = rq->bp; /* buffer pointer */ - diskaddr = bp->b_blkno; /* start offset of transfer */ + bio = rq->bio; /* buffer pointer */ + bp = bio->bio_buf; + diskaddr = bio->bio_blkno; /* start offset of transfer */ diskend = diskaddr + (bp->b_bcount / DEV_BSIZE); /* and end offset of transfer */ rqg = &rq->rqg[plexindex]; /* plex request */ vol = &VOL[rq->volplex.volno]; /* point to volume */ @@ -743,6 +763,7 @@ build_read_request(struct request *rq, /* request */ enum requeststatus build_write_request(struct request *rq) { /* request */ + struct bio *bio; struct buf *bp; daddr_t diskstart; /* offset of current part of transfer */ daddr_t diskend; /* and end offset of transfer */ @@ -750,12 +771,13 @@ build_write_request(struct request *rq) struct volume *vol; /* volume in question */ enum requeststatus status; - bp = rq->bp; /* buffer pointer */ + bio = rq->bio; /* buffer pointer */ + bp = bio->bio_buf; vol = &VOL[rq->volplex.volno]; /* point to volume */ - diskend = bp->b_blkno + (bp->b_bcount / DEV_BSIZE); /* end offset of transfer */ + diskend = bio->bio_blkno + (bp->b_bcount / DEV_BSIZE); /* end offset of transfer */ status = REQUEST_DOWN; /* assume the worst */ for (plexno = 0; plexno < vol->plexes; plexno++) { - diskstart = bp->b_blkno; /* start offset of transfer */ + diskstart = bio->bio_blkno; /* start offset of transfer */ /* * Build requests for the plex. * We take the best possible result here (min, @@ -777,11 +799,13 @@ build_rq_buffer(struct rqelement *rqe, struct plex *plex) struct volume *vol; struct buf *bp; struct buf *ubp; /* user (high level) buffer header */ + struct bio *ubio; vol = &VOL[rqe->rqg->rq->volplex.volno]; sd = &SD[rqe->sdno]; /* point to subdisk */ bp = &rqe->b; - ubp = rqe->rqg->rq->bp; /* pointer to user buffer header */ + ubio = rqe->rqg->rq->bio; /* pointer to user buffer header */ + ubp = ubio->bio_buf; /* Initialize the buf struct */ /* copy these flags from user bp */ @@ -794,7 +818,7 @@ build_rq_buffer(struct rqelement *rqe, struct plex *plex) BUF_LOCK(bp, LK_EXCLUSIVE); /* and lock it */ BUF_KERNPROC(bp); rqe->flags |= XFR_BUFLOCKED; - bp->b_iodone = complete_rqe; + bp->b_bio1.bio_done = complete_rqe; /* * You'd think that we wouldn't need to even * build the request buffer for a dead subdisk, @@ -805,8 +829,8 @@ build_rq_buffer(struct rqelement *rqe, struct plex *plex) * when the drive is dead. */ if ((rqe->flags & XFR_BAD_SUBDISK) == 0) /* subdisk is accessible, */ - bp->b_dev = DRIVE[rqe->driveno].dev; /* drive device */ - bp->b_blkno = rqe->sdoffset + sd->driveoffset; /* start address */ + bp->b_bio1.bio_driver_info = DRIVE[rqe->driveno].dev; /* drive device */ + bp->b_bio1.bio_blkno = rqe->sdoffset + sd->driveoffset; /* start address */ bp->b_bcount = rqe->buflen << DEV_BSHIFT; /* number of bytes to transfer */ bp->b_resid = bp->b_bcount; /* and it's still all waiting */ bp->b_bufsize = bp->b_bcount; /* and buffer size */ @@ -846,7 +870,7 @@ build_rq_buffer(struct rqelement *rqe, struct plex *plex) int abortrequest(struct request *rq, int error) { - struct buf *bp = rq->bp; /* user buffer */ + struct buf *bp = rq->bio->bio_buf; /* user buffer */ bp->b_error = error; freerq(rq); /* free everything we're doing */ @@ -868,18 +892,23 @@ check_range_covered(struct request *rq) /* Perform I/O on a subdisk */ void -sdio(struct buf *bp) +sdio(struct bio *bio) { + dev_t dev; + dev_t sddev; struct sd *sd; struct sdbuf *sbp; daddr_t endoffset; struct drive *drive; + struct buf *bp = bio->bio_buf; + + dev = bio->bio_driver_info; #if VINUMDEBUG if (debug & DEBUG_LASTREQS) - logrq(loginfo_sdio, (union rqinfou) bp, bp); + logrq(loginfo_sdio, (union rqinfou) bio, bio); #endif - sd = &SD[Sdno(bp->b_dev)]; /* point to the subdisk */ + sd = &SD[Sdno(dev)]; /* point to the subdisk */ drive = &DRIVE[sd->driveno]; if (drive->state != drive_up) { @@ -891,7 +920,7 @@ sdio(struct buf *bp) } bp->b_error = EIO; bp->b_flags |= B_ERROR; - biodone(bp); + biodone(bio); return; } /* @@ -901,7 +930,7 @@ sdio(struct buf *bp) if (sd->state < sd_empty) { /* nothing to talk to, */ bp->b_error = EIO; bp->b_flags |= B_ERROR; - biodone(bp); + biodone(bio); return; } /* Get a buffer */ @@ -909,30 +938,31 @@ sdio(struct buf *bp) if (sbp == NULL) { bp->b_error = ENOMEM; bp->b_flags |= B_ERROR; - biodone(bp); + biodone(bio); return; } + sddev = DRIVE[sd->driveno].dev; /* device */ bzero(sbp, sizeof(struct sdbuf)); /* start with nothing */ sbp->b.b_flags = bp->b_flags; sbp->b.b_bufsize = bp->b_bufsize; /* buffer size */ sbp->b.b_bcount = bp->b_bcount; /* number of bytes to transfer */ sbp->b.b_resid = bp->b_resid; /* and amount waiting */ - sbp->b.b_dev = DRIVE[sd->driveno].dev; /* device */ sbp->b.b_data = bp->b_data; /* data buffer */ - sbp->b.b_blkno = bp->b_blkno + sd->driveoffset; - sbp->b.b_iodone = sdio_done; /* come here on completion */ BUF_LOCKINIT(&sbp->b); /* get a lock for the buffer */ BUF_LOCK(&sbp->b, LK_EXCLUSIVE); /* and lock it */ BUF_KERNPROC(&sbp->b); - sbp->bp = bp; /* note the address of the original header */ + initbufbio(&sbp->b); + sbp->b.b_bio1.bio_blkno = bio->bio_blkno + sd->driveoffset; + sbp->b.b_bio1.bio_done = sdio_done; /* come here on completion */ + sbp->bio = bio; /* note the address of the original header */ sbp->sdno = sd->sdno; /* note for statistics */ sbp->driveno = sd->driveno; - endoffset = bp->b_blkno + sbp->b.b_bcount / DEV_BSIZE; /* final sector offset */ + endoffset = bio->bio_blkno + sbp->b.b_bcount / DEV_BSIZE; /* final sector offset */ if (endoffset > sd->sectors) { /* beyond the end */ sbp->b.b_bcount -= (endoffset - sd->sectors) * DEV_BSIZE; /* trim */ if (sbp->b.b_bcount <= 0) { /* nothing to transfer */ bp->b_resid = bp->b_bcount; /* nothing transferred */ - biodone(bp); + biodone(bio); BUF_UNLOCK(&sbp->b); BUF_LOCKFREE(&sbp->b); Free(sbp); @@ -944,19 +974,19 @@ sdio(struct buf *bp) log(LOG_DEBUG, " %s dev %d.%d, sd %d, offset 0x%x, devoffset 0x%x, length %ld\n", sbp->b.b_flags & B_READ ? "Read" : "Write", - major(sbp->b.b_dev), - minor(sbp->b.b_dev), + major(sddev), + minor(sddev), sbp->sdno, - (u_int) (sbp->b.b_blkno - SD[sbp->sdno].driveoffset), - (int) sbp->b.b_blkno, + (u_int) (sbp->b.b_bio1.bio_blkno - SD[sbp->sdno].driveoffset), + (int) sbp->b.b_bio1.bio_blkno, sbp->b.b_bcount); #endif crit_enter(); #if VINUMDEBUG if (debug & DEBUG_LASTREQS) - logrq(loginfo_sdiol, (union rqinfou) &sbp->b, &sbp->b); + logrq(loginfo_sdiol, (union rqinfou) &sbp->b.b_bio1, &sbp->b.b_bio1); #endif - BUF_STRATEGY(&sbp->b, 0); + dev_dstrategy(sddev, &sbp->b.b_bio1); crit_exit(); } @@ -976,45 +1006,48 @@ sdio(struct buf *bp) * one in the first pleace (because it's protected), it wouldn't * be a problem. */ -int -vinum_bounds_check(struct buf *bp, struct volume *vol) +struct bio * +vinum_bounds_check(struct bio *bio, struct volume *vol) { + struct buf *bp = bio->bio_buf; + struct bio *nbio; int maxsize = vol->size; /* size of the partition (sectors) */ int size = (bp->b_bcount + DEV_BSIZE - 1) >> DEV_BSHIFT; /* size of this request (sectors) */ /* Would this transfer overwrite the disk label? */ - if (bp->b_blkno <= LABELSECTOR /* starts before or at the label */ + if (bio->bio_blkno <= LABELSECTOR /* starts before or at the label */ #if LABELSECTOR != 0 - && bp->b_blkno + size > LABELSECTOR /* and finishes after */ + && bio->bio_blkno + size > LABELSECTOR /* and finishes after */ #endif && (!(vol->flags & VF_RAW)) /* and it's not raw */ &&((bp->b_flags & B_READ) == 0) /* and it's a write */ &&(!vol->flags & (VF_WLABEL | VF_LABELLING))) { /* and we're not allowed to write the label */ bp->b_error = EROFS; /* read-only */ bp->b_flags |= B_ERROR; - return -1; + return (NULL); } if (size == 0) /* no transfer specified, */ return 0; /* treat as EOF */ /* beyond partition? */ - if (bp->b_blkno < 0 /* negative start */ - || bp->b_blkno + size > maxsize) { /* or goes beyond the end of the partition */ + if (bio->bio_blkno < 0 /* negative start */ + || bio->bio_blkno + size > maxsize) { /* or goes beyond the end of the partition */ /* if exactly at end of disk, return an EOF */ - if (bp->b_blkno == maxsize) { + if (bio->bio_blkno == maxsize) { bp->b_resid = bp->b_bcount; - return 0; + return (NULL); } /* or truncate if part of it fits */ - size = maxsize - bp->b_blkno; + size = maxsize - bio->bio_blkno; if (size <= 0) { /* nothing to transfer */ bp->b_error = EINVAL; bp->b_flags |= B_ERROR; - return -1; + return (NULL); } bp->b_bcount = size << DEV_BSHIFT; } - bp->b_pblkno = bp->b_blkno; - return 1; + nbio = push_bio(bio); + nbio->bio_blkno = bio->bio_blkno; + return (nbio); } /* diff --git a/sys/dev/raid/vinum/vinumrevive.c b/sys/dev/raid/vinum/vinumrevive.c index 690b88d9aa..1834078190 100644 --- a/sys/dev/raid/vinum/vinumrevive.c +++ b/sys/dev/raid/vinum/vinumrevive.c @@ -39,7 +39,7 @@ * * $Id: vinumrevive.c,v 1.14 2000/12/21 01:55:11 grog Exp grog $ * $FreeBSD: src/sys/dev/vinum/vinumrevive.c,v 1.22.2.5 2001/03/13 02:59:43 grog Exp $ - * $DragonFly: src/sys/dev/raid/vinum/vinumrevive.c,v 1.5 2005/06/11 00:05:46 dillon Exp $ + * $DragonFly: src/sys/dev/raid/vinum/vinumrevive.c,v 1.6 2006/02/17 19:18:06 dillon Exp $ */ #include "vinumhdr.h" @@ -61,6 +61,7 @@ revive_block(int sdno) struct plex *plex; struct volume *vol; struct buf *bp; + dev_t dev; int error = EAGAIN; int size; /* size of revive block, bytes */ daddr_t plexblkno; /* lblkno in plex */ @@ -151,7 +152,7 @@ revive_block(int sdno) */ bp->b_bcount = size; bp->b_resid = bp->b_bcount; - bp->b_blkno = plexblkno; /* start here */ + bp->b_bio1.bio_blkno = plexblkno; /* start here */ if (isstriped(plex)) /* we need to lock striped plexes */ lock = lockrange(plexblkno << DEV_BSHIFT, bp, plex); /* lock it */ if (vol != NULL) /* it's part of a volume, */ @@ -159,12 +160,12 @@ revive_block(int sdno) * First, read the data from the volume. We * don't care which plex, that's bre's job. */ - bp->b_dev = VINUMDEV(plex->volno, 0, 0, VINUM_VOLUME_TYPE); /* create the device number */ + dev = VINUMDEV(plex->volno, 0, 0, VINUM_VOLUME_TYPE); /* create the device number */ else /* it's an unattached plex */ - bp->b_dev = VINUM_PLEX(sd->plexno); /* create the device number */ + dev = VINUM_PLEX(sd->plexno); /* create the device number */ bp->b_flags = B_READ; /* either way, read it */ - vinumstart(bp, 1); + vinumstart(dev, &bp->b_bio1, 1); biowait(bp); } @@ -173,11 +174,12 @@ revive_block(int sdno) else /* Now write to the subdisk */ { - bp->b_dev = VINUM_SD(sdno); /* create the device number */ + dev = VINUM_SD(sdno); /* create the device number */ bp->b_flags = B_ORDERED | B_WRITE; /* and make this an ordered write */ bp->b_resid = bp->b_bcount; - bp->b_blkno = sd->revived; /* write it to here */ - sdio(bp); /* perform the I/O */ + bp->b_bio1.bio_blkno = sd->revived; /* write it to here */ + bp->b_bio1.bio_driver_info = dev; + sdio(&bp->b_bio1); /* perform the I/O */ biowait(bp); if (bp->b_flags & B_ERROR) error = bp->b_error; @@ -196,17 +198,20 @@ revive_block(int sdno) while (sd->waitlist) { /* we have waiting requests */ #if VINUMDEBUG struct request *rq = sd->waitlist; + dev_t dev; - if (debug & DEBUG_REVIVECONFLICT) + if (debug & DEBUG_REVIVECONFLICT) { + dev = rq->bio->bio_driver_info; log(LOG_DEBUG, "Relaunch revive conflict sd %d: %p\n%s dev %d.%d, offset 0x%x, length %ld\n", rq->sdno, rq, - rq->bp->b_flags & B_READ ? "Read" : "Write", - major(rq->bp->b_dev), - minor(rq->bp->b_dev), - rq->bp->b_blkno, - rq->bp->b_bcount); + rq->bio->bio_buf->b_flags & B_READ ? "Read" : "Write", + major(dev), + minor(dev), + rq->bio->bio_blkno, + rq->bio->bio_buf->b_bcount); + } #endif launch_requests(sd->waitlist, 1); /* do them now */ sd->waitlist = sd->waitlist->next; /* and move on to the next */ @@ -292,7 +297,7 @@ parityops(struct vinum_ioctl_msg *data) || (op == rebuildandcheckparity)) { pbp->b_flags &= ~B_READ; pbp->b_resid = pbp->b_bcount; - sdio(pbp); /* write the parity block */ + sdio(&pbp->b_bio1); /* write the parity block */ biowait(pbp); } if (((op == checkparity) @@ -405,13 +410,13 @@ parityrebuild(struct plex *plex, if (sdno == psd) parity_buf = (int *) bpp[sdno]->b_data; if (sdno == newpsd) /* the new one? */ - bpp[sdno]->b_dev = VINUM_SD(plex->sdnos[psd]); /* write back to the parity SD */ + bpp[sdno]->b_bio1.bio_driver_info = VINUM_SD(plex->sdnos[psd]); /* write back to the parity SD */ else - bpp[sdno]->b_dev = VINUM_SD(plex->sdnos[sdno]); /* device number */ + bpp[sdno]->b_bio1.bio_driver_info = VINUM_SD(plex->sdnos[sdno]); /* device number */ bpp[sdno]->b_flags = B_READ; /* either way, read it */ bpp[sdno]->b_bcount = mysize; bpp[sdno]->b_resid = bpp[sdno]->b_bcount; - bpp[sdno]->b_blkno = pstripe; /* transfer from here */ + bpp[sdno]->b_bio1.bio_blkno = pstripe; /* transfer from here */ } } @@ -436,7 +441,7 @@ parityrebuild(struct plex *plex, */ for (sdno = 0; sdno < plex->subdisks; sdno++) { /* for each real subdisk */ if ((sdno != psd) || (op != rebuildparity)) { - sdio(bpp[sdno]); + sdio(&bpp[sdno]->b_bio1); } } @@ -545,11 +550,11 @@ initsd(int sdno, int verify) bp->b_bcount = size; bp->b_resid = bp->b_bcount; - bp->b_blkno = sd->initialized; /* write it to here */ + bp->b_bio1.bio_blkno = sd->initialized; /* write it to here */ + bp->b_bio1.bio_driver_info = VINUM_SD(sdno); bzero(bp->b_data, bp->b_bcount); - bp->b_dev = VINUM_SD(sdno); /* create the device number */ bp->b_flags &= ~B_READ; - sdio(bp); /* perform the I/O */ + sdio(&bp->b_bio1); /* perform the I/O */ biowait(bp); if (bp->b_flags & B_ERROR) error = bp->b_error; @@ -567,11 +572,11 @@ initsd(int sdno, int verify) } else { bp->b_bcount = size; bp->b_resid = bp->b_bcount; - bp->b_blkno = sd->initialized; /* read from here */ - bp->b_dev = VINUM_SD(sdno); /* create the device number */ + bp->b_bio1.bio_blkno = sd->initialized; /* read from here */ + bp->b_bio1.bio_driver_info = VINUM_SD(sdno); bp->b_flags |= B_READ; /* read it back */ crit_exit(); - sdio(bp); + sdio(&bp->b_bio1); biowait(bp); /* * XXX Bug fix code. This is hopefully no diff --git a/sys/dev/raid/vinum/vinumstate.c b/sys/dev/raid/vinum/vinumstate.c index 953728fcee..b3542fd5e3 100644 --- a/sys/dev/raid/vinum/vinumstate.c +++ b/sys/dev/raid/vinum/vinumstate.c @@ -39,7 +39,7 @@ * * $Id: vinumstate.c,v 2.18 2000/05/10 07:30:50 grog Exp grog $ * $FreeBSD: src/sys/dev/vinum/vinumstate.c,v 1.28.2.2 2000/06/08 02:00:23 grog Exp $ - * $DragonFly: src/sys/dev/raid/vinum/vinumstate.c,v 1.4 2003/11/15 21:05:42 dillon Exp $ + * $DragonFly: src/sys/dev/raid/vinum/vinumstate.c,v 1.5 2006/02/17 19:18:06 dillon Exp $ */ #include "vinumhdr.h" @@ -618,7 +618,7 @@ enum requeststatus checksdstate(struct sd *sd, struct request *rq, daddr_t diskaddr, daddr_t diskend) { struct plex *plex = &PLEX[sd->plexno]; - int writeop = (rq->bp->b_flags & B_READ) == 0; /* note if we're writing */ + int writeop = (rq->bio->bio_buf->b_flags & B_READ) == 0; /* note if we're writing */ switch (sd->state) { /* We shouldn't get called if the subdisk is up */ diff --git a/sys/dev/raid/vinum/vinumvar.h b/sys/dev/raid/vinum/vinumvar.h index 4d7af32167..94c9f83407 100644 --- a/sys/dev/raid/vinum/vinumvar.h +++ b/sys/dev/raid/vinum/vinumvar.h @@ -39,7 +39,7 @@ * * $Id: vinumvar.h,v 1.24 2000/03/01 02:34:57 grog Exp grog $ * $FreeBSD: src/sys/dev/vinum/vinumvar.h,v 1.32.2.4 2001/05/28 05:56:27 grog Exp $ - * $DragonFly: src/sys/dev/raid/vinum/vinumvar.h,v 1.5 2004/05/19 22:52:48 dillon Exp $ + * $DragonFly: src/sys/dev/raid/vinum/vinumvar.h,v 1.6 2006/02/17 19:18:06 dillon Exp $ */ #include @@ -311,7 +311,7 @@ struct _vinum_conf { int maxactive; /* maximum number of requests ever outstanding */ #if VINUMDEBUG struct request *lastrq; - struct buf *lastbuf; + struct bio *lastbio; #endif }; diff --git a/sys/i386/i386/machdep.c b/sys/i386/i386/machdep.c index eced7e19c4..c535fb388e 100644 --- a/sys/i386/i386/machdep.c +++ b/sys/i386/i386/machdep.c @@ -36,7 +36,7 @@ * * from: @(#)machdep.c 7.4 (Berkeley) 6/3/91 * $FreeBSD: src/sys/i386/i386/machdep.c,v 1.385.2.30 2003/05/31 08:48:05 alc Exp $ - * $DragonFly: src/sys/i386/i386/Attic/machdep.c,v 1.85 2005/12/12 08:15:03 dillon Exp $ + * $DragonFly: src/sys/i386/i386/Attic/machdep.c,v 1.86 2006/02/17 19:18:06 dillon Exp $ */ #include "use_apm.h" @@ -2515,20 +2515,26 @@ Debugger(const char *msg) * Determine the size of the transfer, and make sure it is * within the boundaries of the partition. Adjust transfer * if needed, and signal errors or early completion. + * + * On success a new bio layer is pushed with the translated + * block number, and returned. */ -int -bounds_check_with_label(struct buf *bp, struct disklabel *lp, int wlabel) +struct bio * +bounds_check_with_label(dev_t dev, struct bio *bio, + struct disklabel *lp, int wlabel) { - struct partition *p = lp->d_partitions + dkpart(bp->b_dev); + struct bio *nbio; + struct buf *bp = bio->bio_buf; + struct partition *p = lp->d_partitions + dkpart(dev); int labelsect = lp->d_partitions[0].p_offset; int maxsz = p->p_size, sz = (bp->b_bcount + DEV_BSIZE - 1) >> DEV_BSHIFT; /* overwriting disk label ? */ /* XXX should also protect bootstrap in first 8K */ - if (bp->b_blkno + p->p_offset <= LABELSECTOR + labelsect && + if (bio->bio_blkno + p->p_offset <= LABELSECTOR + labelsect && #if LABELSECTOR != 0 - bp->b_blkno + p->p_offset + sz > LABELSECTOR + labelsect && + bio->bio_blkno + p->p_offset + sz > LABELSECTOR + labelsect && #endif (bp->b_flags & B_READ) == 0 && wlabel == 0) { bp->b_error = EROFS; @@ -2537,7 +2543,7 @@ bounds_check_with_label(struct buf *bp, struct disklabel *lp, int wlabel) #if defined(DOSBBSECTOR) && defined(notyet) /* overwriting master boot record? */ - if (bp->b_blkno + p->p_offset <= DOSBBSECTOR && + if (bio->bio_blkno + p->p_offset <= DOSBBSECTOR && (bp->b_flags & B_READ) == 0 && wlabel == 0) { bp->b_error = EROFS; goto bad; @@ -2545,27 +2551,27 @@ bounds_check_with_label(struct buf *bp, struct disklabel *lp, int wlabel) #endif /* beyond partition? */ - if (bp->b_blkno < 0 || bp->b_blkno + sz > maxsz) { + if (bio->bio_blkno < 0 || bio->bio_blkno + sz > maxsz) { /* if exactly at end of disk, return an EOF */ - if (bp->b_blkno == maxsz) { + if (bio->bio_blkno == maxsz) { bp->b_resid = bp->b_bcount; return(0); } /* or truncate if part of it fits */ - sz = maxsz - bp->b_blkno; + sz = maxsz - bio->bio_blkno; if (sz <= 0) { bp->b_error = EINVAL; goto bad; } bp->b_bcount = sz << DEV_BSHIFT; } - - bp->b_pblkno = bp->b_blkno + p->p_offset; - return(1); + nbio = push_bio(bio); + nbio->bio_blkno = bio->bio_blkno + p->p_offset; + return (nbio); bad: bp->b_flags |= B_ERROR; - return(-1); + return (NULL); } #ifdef DDB diff --git a/sys/kern/kern_device.c b/sys/kern/kern_device.c index 8344b65270..ca774a18c2 100644 --- a/sys/kern/kern_device.c +++ b/sys/kern/kern_device.c @@ -25,7 +25,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $DragonFly: src/sys/kern/kern_device.c,v 1.15 2005/03/23 02:50:53 dillon Exp $ + * $DragonFly: src/sys/kern/kern_device.c,v 1.16 2006/02/17 19:18:06 dillon Exp $ */ #include #include @@ -34,6 +34,8 @@ #include #include #include +#include +#include #include #include #include @@ -93,7 +95,7 @@ cdevsw_putport(lwkt_port_t port, lwkt_msg_t lmsg) msg->am_close.td); break; case CDEV_CMD_STRATEGY: - devsw->old_strategy(msg->am_strategy.bp); + devsw->old_strategy(msg->am_strategy.msg.dev, msg->am_strategy.bio); error = 0; break; case CDEV_CMD_IOCTL: @@ -194,15 +196,44 @@ dev_dclose(dev_t dev, int fflag, int devtype, thread_t td) return(lwkt_domsg(port, &msg.msg.msg)); } +/* + * Core device strategy call, used to issue I/O on a device. There are + * two versions, a non-chained version and a chained version. The chained + * version reuses a BIO set up by vn_strategy(). The only difference is + * that, for now, we do not push a new tracking structure when chaining + * from vn_strategy. XXX this will ultimately have to change. + */ +void +dev_dstrategy(dev_t dev, struct bio *bio) +{ + struct cdevmsg_strategy msg; + struct bio_track *track; + lwkt_port_t port; + + KKASSERT(bio->bio_track == NULL); + if (bio->bio_buf->b_flags & B_READ) + track = &dev->si_track_read; + else + track = &dev->si_track_write; + atomic_add_int(&track->bk_active, 1); + bio->bio_track = track; + + port = _init_cdevmsg(dev, &msg.msg, CDEV_CMD_STRATEGY); + KKASSERT(port); /* 'nostrategy' function is NULL YYY */ + msg.bio = bio; + lwkt_domsg(port, &msg.msg.msg); +} + void -dev_dstrategy(dev_t dev, struct buf *bp) +dev_dstrategy_chain(dev_t dev, struct bio *bio) { struct cdevmsg_strategy msg; lwkt_port_t port; + KKASSERT(bio->bio_track != NULL); port = _init_cdevmsg(dev, &msg.msg, CDEV_CMD_STRATEGY); KKASSERT(port); /* 'nostrategy' function is NULL YYY */ - msg.bp = bp; + msg.bio = bio; lwkt_domsg(port, &msg.msg.msg); } diff --git a/sys/kern/kern_physio.c b/sys/kern/kern_physio.c index ef75255cd2..d64808f448 100644 --- a/sys/kern/kern_physio.c +++ b/sys/kern/kern_physio.c @@ -17,7 +17,7 @@ * are met. * * $FreeBSD: src/sys/kern/kern_physio.c,v 1.46.2.4 2003/11/14 09:51:47 simokawa Exp $ - * $DragonFly: src/sys/kern/kern_physio.c,v 1.13 2005/11/19 17:58:21 dillon Exp $ + * $DragonFly: src/sys/kern/kern_physio.c,v 1.14 2006/02/17 19:18:06 dillon Exp $ */ #include @@ -33,9 +33,9 @@ #include static void -physwakeup(struct buf *bp) +physwakeup(struct bio *bio) { - wakeup((caddr_t) bp); + wakeup(bio); } int @@ -72,13 +72,14 @@ physio(dev_t dev, struct uio *uio, int ioflag) bp->b_flags = B_PHYS | B_READ; else bp->b_flags = B_PHYS | B_WRITE; - bp->b_dev = dev; - bp->b_iodone = physwakeup; bp->b_data = uio->uio_iov[i].iov_base; bp->b_bcount = uio->uio_iov[i].iov_len; - bp->b_offset = uio->uio_offset; bp->b_saveaddr = sa; + reinitbufbio(bp); /* clear translation cache */ + bp->b_bio1.bio_offset = uio->uio_offset; + bp->b_bio1.bio_done = physwakeup; + /* Don't exceed drivers iosize limit */ if (bp->b_bcount > dev->si_iosize_max) bp->b_bcount = dev->si_iosize_max; @@ -97,23 +98,27 @@ physio(dev_t dev, struct uio *uio, int ioflag) } bp->b_bufsize = bp->b_bcount; - blockno = bp->b_offset >> DEV_BSHIFT; + /* + * XXX we shouldn't have to set the block + * number. + */ + blockno = bp->b_bio1.bio_offset >> DEV_BSHIFT; if (chk_blockno && (daddr_t)blockno != blockno) { error = EINVAL; /* blockno overflow */ goto doerror; } - bp->b_blkno = blockno; + bp->b_bio1.bio_blkno = blockno; - if (uio->uio_segflg == UIO_USERSPACE) + if (uio->uio_segflg == UIO_USERSPACE) { if (vmapbuf(bp) < 0) { error = EFAULT; goto doerror; } - - BUF_STRATEGY(bp, 0); + } + dev_dstrategy(dev, &bp->b_bio1); crit_enter(); while ((bp->b_flags & B_DONE) == 0) - tsleep((caddr_t)bp, 0, "physstr", 0); + tsleep(&bp->b_bio1, 0, "physstr", 0); crit_exit(); if (uio->uio_segflg == UIO_USERSPACE) diff --git a/sys/kern/kern_shutdown.c b/sys/kern/kern_shutdown.c index 798fb6b1d4..46a429a97f 100644 --- a/sys/kern/kern_shutdown.c +++ b/sys/kern/kern_shutdown.c @@ -37,7 +37,7 @@ * * @(#)kern_shutdown.c 8.3 (Berkeley) 1/21/94 * $FreeBSD: src/sys/kern/kern_shutdown.c,v 1.72.2.12 2002/02/21 19:15:10 dillon Exp $ - * $DragonFly: src/sys/kern/kern_shutdown.c,v 1.23 2005/11/04 09:38:15 dillon Exp $ + * $DragonFly: src/sys/kern/kern_shutdown.c,v 1.24 2006/02/17 19:18:06 dillon Exp $ */ #include "opt_ddb.h" @@ -313,16 +313,22 @@ boot(int howto) for (bp = &buf[nbuf]; --bp >= buf; ) { if (((bp->b_flags&B_INVAL) == 0 && BUF_REFCNT(bp)) || ((bp->b_flags & (B_DELWRI|B_INVAL)) == B_DELWRI)) { + /* + * XXX we need a way to detect this condition + * Maybe use B_DONE ? + */ +#if 0 if (bp->b_dev == NODEV) { mountlist_remove(bp->b_vp->v_mount); continue; } +#endif nbusy++; #if defined(SHOW_BUSYBUFS) || defined(DIAGNOSTIC) printf( - "%p %d: dev:%s, flags:%08lx, blkno:%ld, lblkno:%ld\n", - bp, nbusy, devtoname(bp->b_dev), - bp->b_flags, (long)bp->b_blkno, + "%p %d: dev:?, flags:%08lx, blkno:%ld, lblkno:%ld\n", + bp, nbusy, + bp->b_flags, (long)bp->b_bio1.bio_blkno, (long)bp->b_lblkno); #endif } diff --git a/sys/kern/subr_disk.c b/sys/kern/subr_disk.c index ca4e96b432..63128a6372 100644 --- a/sys/kern/subr_disk.c +++ b/sys/kern/subr_disk.c @@ -77,7 +77,7 @@ * @(#)ufs_disksubr.c 8.5 (Berkeley) 1/21/94 * $FreeBSD: src/sys/kern/subr_disk.c,v 1.20.2.6 2001/10/05 07:14:57 peter Exp $ * $FreeBSD: src/sys/ufs/ufs/ufs_disksubr.c,v 1.44.2.3 2001/03/05 05:42:19 obrien Exp $ - * $DragonFly: src/sys/kern/subr_disk.c,v 1.20 2005/09/10 21:01:20 swildner Exp $ + * $DragonFly: src/sys/kern/subr_disk.c,v 1.21 2006/02/17 19:18:06 dillon Exp $ */ #include @@ -115,7 +115,7 @@ static LIST_HEAD(, disk) disklist = LIST_HEAD_INITIALIZER(&disklist); /* * Create a slice and unit managed disk. * - * Our port layer will be responsible for assigning pblkno and handling + * Our port layer will be responsible for assigning blkno and handling * high level partition operations, then forwarding the requests to the * raw device. * @@ -300,7 +300,7 @@ disk_putport(lwkt_port_t port, lwkt_msg_t lmsg) msg->am_ioctl.td); break; case CDEV_CMD_STRATEGY: - diskstrategy(msg->am_strategy.bp); + diskstrategy(msg->am_strategy.msg.dev, msg->am_strategy.bio); error = 0; break; case CDEV_CMD_PSIZE: @@ -452,31 +452,32 @@ diskclose(dev_t dev, int fflag, int devtype, struct thread *td) */ static void -diskstrategy(struct buf *bp) +diskstrategy(dev_t dev, struct bio *bio) { + struct bio *nbio; struct disk *dp; - dp = bp->b_dev->si_disk; + dp = dev->si_disk; if (dp == NULL) { - bp->b_error = ENXIO; - bp->b_flags |= B_ERROR; - biodone(bp); + bio->bio_buf->b_error = ENXIO; + bio->bio_buf->b_flags |= B_ERROR; + biodone(bio); return; } - KKASSERT(bp->b_dev->si_disk == dp); + KKASSERT(dev->si_disk == dp); /* * The dscheck() function will also transform the slice relative - * block number i.e. bp->b_blkno into a block number that can be + * block number i.e. bio->bio_blkno into a block number that can be * passed directly to the underlying raw device. */ - if (dscheck(bp, dp->d_slice) <= 0) { - biodone(bp); + nbio = dscheck(dev, bio, dp->d_slice); + if (nbio == NULL) { + biodone(bio); return; } - bp->b_dev = dp->d_rawdev; - dev_dstrategy(dp->d_rawdev, bp); + dev_dstrategy(dp->d_rawdev, nbio); } /* @@ -535,7 +536,7 @@ SYSCTL_INT(_debug_sizeof, OID_AUTO, disk, CTLFLAG_RD, /* * Seek sort for disks. * - * The buf_queue keep two queues, sorted in ascending block order. The first + * The bio_queue keep two queues, sorted in ascending block order. The first * queue holds those requests which are positioned after the current block * (in the first request); the second, which starts at queue->switch_point, * holds requests which came in after their block number was passed. Thus @@ -547,22 +548,22 @@ SYSCTL_INT(_debug_sizeof, OID_AUTO, disk, CTLFLAG_RD, * allocated. */ void -bufqdisksort(struct buf_queue_head *bufq, struct buf *bp) +bioqdisksort(struct bio_queue_head *bioq, struct bio *bio) { - struct buf *bq; - struct buf *bn; - struct buf *be; + struct bio *bq; + struct bio *bn; + struct bio *be; - be = TAILQ_LAST(&bufq->queue, buf_queue); + be = TAILQ_LAST(&bioq->queue, bio_queue); /* * If the queue is empty or we are an * ordered transaction, then it's easy. */ - if ((bq = bufq_first(bufq)) == NULL || - (bp->b_flags & B_ORDERED) != 0) { - bufq_insert_tail(bufq, bp); + if ((bq = bioq_first(bioq)) == NULL || + (bio->bio_buf->b_flags & B_ORDERED) != 0) { + bioq_insert_tail(bioq, bio); return; - } else if (bufq->insert_point != NULL) { + } else if (bioq->insert_point != NULL) { /* * A certain portion of the list is @@ -570,7 +571,7 @@ bufqdisksort(struct buf_queue_head *bufq, struct buf *bp) * we can only insert after the insert * point. */ - bq = bufq->insert_point; + bq = bioq->insert_point; } else { /* @@ -579,16 +580,16 @@ bufqdisksort(struct buf_queue_head *bufq, struct buf *bp) * "locked" portion of the list, then we must add ourselves * to the second request list. */ - if (bp->b_pblkno < bufq->last_pblkno) { + if (bio->bio_blkno < bioq->last_blkno) { - bq = bufq->switch_point; + bq = bioq->switch_point; /* * If we are starting a new secondary list, * then it's easy. */ if (bq == NULL) { - bufq->switch_point = bp; - bufq_insert_tail(bufq, bp); + bioq->switch_point = bio; + bioq_insert_tail(bioq, bio); return; } /* @@ -596,21 +597,21 @@ bufqdisksort(struct buf_queue_head *bufq, struct buf *bp) * insert us before the switch point and move * the switch point. */ - if (bp->b_pblkno < bq->b_pblkno) { - bufq->switch_point = bp; - TAILQ_INSERT_BEFORE(bq, bp, b_act); + if (bio->bio_blkno < bq->bio_blkno) { + bioq->switch_point = bio; + TAILQ_INSERT_BEFORE(bq, bio, bio_act); return; } } else { - if (bufq->switch_point != NULL) - be = TAILQ_PREV(bufq->switch_point, - buf_queue, b_act); + if (bioq->switch_point != NULL) + be = TAILQ_PREV(bioq->switch_point, + bio_queue, bio_act); /* - * If we lie between last_pblkno and bq, + * If we lie between last_blkno and bq, * insert before bq. */ - if (bp->b_pblkno < bq->b_pblkno) { - TAILQ_INSERT_BEFORE(bq, bp, b_act); + if (bio->bio_blkno < bq->bio_blkno) { + TAILQ_INSERT_BEFORE(bq, bio, bio_act); return; } } @@ -620,25 +621,25 @@ bufqdisksort(struct buf_queue_head *bufq, struct buf *bp) * Request is at/after our current position in the list. * Optimize for sequential I/O by seeing if we go at the tail. */ - if (bp->b_pblkno > be->b_pblkno) { - TAILQ_INSERT_AFTER(&bufq->queue, be, bp, b_act); + if (bio->bio_blkno > be->bio_blkno) { + TAILQ_INSERT_AFTER(&bioq->queue, be, bio, bio_act); return; } /* Otherwise, insertion sort */ - while ((bn = TAILQ_NEXT(bq, b_act)) != NULL) { + while ((bn = TAILQ_NEXT(bq, bio_act)) != NULL) { /* * We want to go after the current request if it is the end * of the first request list, or if the next request is a * larger cylinder than our request. */ - if (bn == bufq->switch_point - || bp->b_pblkno < bn->b_pblkno) + if (bn == bioq->switch_point + || bio->bio_blkno < bn->bio_blkno) break; bq = bn; } - TAILQ_INSERT_AFTER(&bufq->queue, bq, bp, b_act); + TAILQ_INSERT_AFTER(&bioq->queue, bq, bio, bio_act); } @@ -657,12 +658,11 @@ readdisklabel(dev_t dev, struct disklabel *lp) char *msg = NULL; bp = geteblk((int)lp->d_secsize); - bp->b_dev = dev; - bp->b_blkno = LABELSECTOR * ((int)lp->d_secsize/DEV_BSIZE); + bp->b_bio1.bio_blkno = LABELSECTOR * ((int)lp->d_secsize/DEV_BSIZE); bp->b_bcount = lp->d_secsize; bp->b_flags &= ~B_INVAL; bp->b_flags |= B_READ; - BUF_STRATEGY(bp, 1); + dev_dstrategy(dev, &bp->b_bio1); if (biowait(bp)) msg = "I/O error"; else for (dlp = (struct disklabel *)bp->b_data; @@ -748,8 +748,7 @@ writedisklabel(dev_t dev, struct disklabel *lp) if (lp->d_partitions[RAW_PART].p_offset != 0) return (EXDEV); /* not quite right */ bp = geteblk((int)lp->d_secsize); - bp->b_dev = dkmodpart(dev, RAW_PART); - bp->b_blkno = LABELSECTOR * ((int)lp->d_secsize/DEV_BSIZE); + bp->b_bio1.bio_blkno = LABELSECTOR * ((int)lp->d_secsize/DEV_BSIZE); bp->b_bcount = lp->d_secsize; #if 1 /* @@ -761,7 +760,7 @@ writedisklabel(dev_t dev, struct disklabel *lp) */ bp->b_flags &= ~B_INVAL; bp->b_flags |= B_READ; - BUF_STRATEGY(bp, 1); + dev_dstrategy(dkmodpart(dev, RAW_PART), &bp->b_bio1); error = biowait(bp); if (error) goto done; @@ -774,8 +773,7 @@ writedisklabel(dev_t dev, struct disklabel *lp) *dlp = *lp; bp->b_flags &= ~(B_DONE | B_READ); bp->b_flags |= B_WRITE; - bp->b_dev = dkmodpart(dev, RAW_PART); - BUF_STRATEGY(bp, 1); + dev_dstrategy(dkmodpart(dev, RAW_PART), &bp->b_bio1); error = biowait(bp); goto done; } @@ -811,9 +809,10 @@ hp0g: hard error reading fsbn 12345 of 12344-12347 (hp0 bn %d cn %d tn %d sn %d) * or addlog, respectively. There is no trailing space. */ void -diskerr(struct buf *bp, dev_t dev, char *what, int pri, +diskerr(struct bio *bio, dev_t dev, const char *what, int pri, int blkdone, struct disklabel *lp) { + struct buf *bp = bio->bio_buf; int unit = dkunit(dev); int slice = dkslice(dev); int part = dkpart(dev); @@ -824,7 +823,7 @@ diskerr(struct buf *bp, dev_t dev, char *what, int pri, sname = dsname(dev, unit, slice, part, partname); printf("%s%s: %s %sing fsbn ", sname, partname, what, bp->b_flags & B_READ ? "read" : "writ"); - sn = bp->b_blkno; + sn = bio->bio_blkno; if (bp->b_bcount <= DEV_BSIZE) { printf("%ld", (long)sn); } else { @@ -832,17 +831,17 @@ diskerr(struct buf *bp, dev_t dev, char *what, int pri, sn += blkdone; printf("%ld of ", (long)sn); } - printf("%ld-%ld", (long)bp->b_blkno, - (long)(bp->b_blkno + (bp->b_bcount - 1) / DEV_BSIZE)); + printf("%ld-%ld", (long)bio->bio_blkno, + (long)(bio->bio_blkno + (bp->b_bcount - 1) / DEV_BSIZE)); } if (lp && (blkdone >= 0 || bp->b_bcount <= lp->d_secsize)) { sn += lp->d_partitions[part].p_offset; /* * XXX should add slice offset and not print the slice, * but we don't know the slice pointer. - * XXX should print bp->b_pblkno so that this will work + * XXX should print bio->bio_blkno so that this will work * independent of slices, labels and bad sector remapping, - * but some drivers don't set bp->b_pblkno. + * but some drivers don't set bio->bio_blkno. */ printf(" (%s bn %ld; cn %ld", sname, (long)sn, (long)(sn / lp->d_secpercyl)); @@ -851,3 +850,4 @@ diskerr(struct buf *bp, dev_t dev, char *what, int pri, (long)(sn % lp->d_nsectors)); } } + diff --git a/sys/kern/subr_diskmbr.c b/sys/kern/subr_diskmbr.c index f32d7d7ca4..b192d5620f 100644 --- a/sys/kern/subr_diskmbr.c +++ b/sys/kern/subr_diskmbr.c @@ -36,7 +36,7 @@ * from: @(#)ufs_disksubr.c 7.16 (Berkeley) 5/4/91 * from: ufs_disksubr.c,v 1.8 1994/06/07 01:21:39 phk Exp $ * $FreeBSD: src/sys/kern/subr_diskmbr.c,v 1.45 2000/01/28 10:22:07 bde Exp $ - * $DragonFly: src/sys/kern/subr_diskmbr.c,v 1.10 2005/04/30 23:04:21 swildner Exp $ + * $DragonFly: src/sys/kern/subr_diskmbr.c,v 1.11 2006/02/17 19:18:06 dillon Exp $ */ #include @@ -177,14 +177,14 @@ reread_mbr: /* Read master boot record. */ wdev = dkmodpart(dkmodslice(dev, WHOLE_DISK_SLICE), RAW_PART); bp = geteblk((int)lp->d_secsize); - bp->b_dev = wdev; - bp->b_blkno = mbr_offset; + bp->b_bio1.bio_blkno = mbr_offset; bp->b_bcount = lp->d_secsize; bp->b_flags |= B_READ; - BUF_STRATEGY(bp, 1); + dev_dstrategy(wdev, &bp->b_bio1); if (biowait(bp) != 0) { - diskerr(bp, wdev, "reading primary partition table: error", - LOG_PRINTF, 0, (struct disklabel *)NULL); + diskerr(&bp->b_bio1, wdev, + "reading primary partition table: error", + LOG_PRINTF, 0, (struct disklabel *)NULL); printf("\n"); error = EIO; goto done; @@ -386,14 +386,14 @@ mbr_extended(dev_t dev, struct disklabel *lp, struct diskslices *ssp, /* Read extended boot record. */ bp = geteblk((int)lp->d_secsize); - bp->b_dev = dev; - bp->b_blkno = ext_offset; + bp->b_bio1.bio_blkno = ext_offset; bp->b_bcount = lp->d_secsize; bp->b_flags |= B_READ; - BUF_STRATEGY(bp, 1); + dev_dstrategy(dev, &bp->b_bio1); if (biowait(bp) != 0) { - diskerr(bp, dev, "reading extended partition table: error", - LOG_PRINTF, 0, (struct disklabel *)NULL); + diskerr(&bp->b_bio1, dev, + "reading extended partition table: error", + LOG_PRINTF, 0, (struct disklabel *)NULL); printf("\n"); goto done; } diff --git a/sys/kern/subr_diskslice.c b/sys/kern/subr_diskslice.c index bc3aa0cabf..4e14d363d6 100644 --- a/sys/kern/subr_diskslice.c +++ b/sys/kern/subr_diskslice.c @@ -44,7 +44,7 @@ * from: @(#)ufs_disksubr.c 7.16 (Berkeley) 5/4/91 * from: ufs_disksubr.c,v 1.8 1994/06/07 01:21:39 phk Exp $ * $FreeBSD: src/sys/kern/subr_diskslice.c,v 1.82.2.6 2001/07/24 09:49:41 dd Exp $ - * $DragonFly: src/sys/kern/subr_diskslice.c,v 1.12 2005/08/26 12:45:53 hmp Exp $ + * $DragonFly: src/sys/kern/subr_diskslice.c,v 1.13 2006/02/17 19:18:06 dillon Exp $ */ #include @@ -71,7 +71,7 @@ typedef u_char bool_t; static volatile bool_t ds_debug; static struct disklabel *clone_label (struct disklabel *lp); -static void dsiodone (struct buf *bp); +static void dsiodone (struct bio *bio); static char *fixlabel (char *sname, struct diskslice *sp, struct disklabel *lp, int writeflag); static void free_ds_label (struct diskslices *ssp, int slice); @@ -137,9 +137,11 @@ clone_label(struct disklabel *lp) * 'errno' value is also set in bp->b_error and bp->b_flags * is marked with B_ERROR. */ -int -dscheck(struct buf *bp, struct diskslices *ssp) +struct bio * +dscheck(dev_t dev, struct bio *bio, struct diskslices *ssp) { + struct buf *bp = bio->bio_buf; + struct bio *nbio; daddr_t blkno; u_long endsecno; daddr_t labelsect; @@ -151,14 +153,14 @@ dscheck(struct buf *bp, struct diskslices *ssp) daddr_t slicerel_secno; struct diskslice *sp; - blkno = bp->b_blkno; + blkno = bio->bio_blkno; if (blkno < 0) { - printf("dscheck(%s): negative b_blkno %ld\n", - devtoname(bp->b_dev), (long)blkno); + printf("dscheck(%s): negative bio_blkno %ld\n", + devtoname(dev), (long)blkno); bp->b_error = EINVAL; goto bad; } - sp = &ssp->dss_slices[dkslice(bp->b_dev)]; + sp = &ssp->dss_slices[dkslice(dev)]; lp = sp->ds_label; if (ssp->dss_secmult == 1) { if (bp->b_bcount % (u_long)DEV_BSIZE) @@ -188,7 +190,7 @@ dscheck(struct buf *bp, struct diskslices *ssp) labelsect = lp->d_partitions[LABEL_PART].p_offset; if (labelsect != 0) Debugger("labelsect != 0 in dscheck()"); - pp = &lp->d_partitions[dkpart(bp->b_dev)]; + pp = &lp->d_partitions[dkpart(dev)]; endsecno = pp->p_size; slicerel_secno = pp->p_offset + secno; } @@ -229,7 +231,8 @@ dscheck(struct buf *bp, struct diskslices *ssp) bp->b_bcount = nsec * ssp->dss_secsize; } - bp->b_pblkno = sp->ds_offset + slicerel_secno; + nbio = push_bio(bio); + nbio->bio_blkno = sp->ds_offset + slicerel_secno; /* * Snoop on label accesses if the slice offset is nonzero. Fudge @@ -241,18 +244,11 @@ dscheck(struct buf *bp, struct diskslices *ssp) && slicerel_secno + nsec > LABELSECTOR + labelsect #endif && sp->ds_offset != 0) { - struct iodone_chain *ic; - - ic = malloc(sizeof *ic , M_DEVBUF, M_WAITOK); - ic->ic_prev_flags = bp->b_flags; - ic->ic_prev_iodone = bp->b_iodone; - ic->ic_prev_iodone_chain = bp->b_iodone_chain; - ic->ic_args[0].ia_long = (LABELSECTOR + labelsect - - slicerel_secno) * ssp->dss_secsize; - ic->ic_args[1].ia_ptr = sp; - bp->b_iodone = dsiodone; - bp->b_iodone_chain = ic; - if (!(bp->b_flags & B_READ)) { + nbio->bio_done = dsiodone; + nbio->bio_caller_info1.ptr = sp; + nbio->bio_caller_info2.offset = (off_t)(LABELSECTOR + labelsect - + slicerel_secno) * ssp->dss_secsize; + if ((bp->b_flags & B_READ) == 0) { /* * XXX even disklabel(8) writes directly so we need * to adjust writes. Perhaps we should drop support @@ -262,44 +258,41 @@ dscheck(struct buf *bp, struct diskslices *ssp) * XXX probably need to copy the data to avoid even * temporarily corrupting the in-core copy. */ - if (bp->b_vp != NULL) { - crit_enter(); - bp->b_vp->v_numoutput++; - crit_exit(); - } /* XXX need name here. */ - msg = fixlabel((char *)NULL, sp, - (struct disklabel *) - (bp->b_data + ic->ic_args[0].ia_long), - TRUE); + msg = fixlabel( + NULL, sp, + (struct disklabel *) + (bp->b_data + (int)nbio->bio_caller_info2.offset), + TRUE); if (msg != NULL) { printf("dscheck(%s): %s\n", - devtoname(bp->b_dev), msg); + devtoname(dev), msg); bp->b_error = EROFS; + pop_bio(nbio); goto bad; } } } - return (1); + return (nbio); bad_bcount: printf( "dscheck(%s): b_bcount %ld is not on a sector boundary (ssize %d)\n", - devtoname(bp->b_dev), bp->b_bcount, ssp->dss_secsize); + devtoname(dev), bp->b_bcount, ssp->dss_secsize); bp->b_error = EINVAL; goto bad; bad_blkno: printf( - "dscheck(%s): b_blkno %ld is not on a sector boundary (ssize %d)\n", - devtoname(bp->b_dev), (long)blkno, ssp->dss_secsize); + "dscheck(%s): bio_blkno %ld is not on a sector boundary (ssize %d)\n", + devtoname(dev), (long)blkno, ssp->dss_secsize); bp->b_error = EINVAL; goto bad; bad: bp->b_resid = bp->b_bcount; bp->b_flags |= B_ERROR; - return (-1); + return (NULL); } void @@ -536,26 +529,22 @@ dsioctl(dev_t dev, u_long cmd, caddr_t data, } static void -dsiodone(struct buf *bp) +dsiodone(struct bio *bio) { - struct iodone_chain *ic; + struct buf *bp = bio->bio_buf; char *msg; - ic = bp->b_iodone_chain; bp->b_flags = bp->b_flags & ~B_DONE; - bp->b_iodone = ic->ic_prev_iodone; - bp->b_iodone_chain = ic->ic_prev_iodone_chain; if (!(bp->b_flags & B_READ) || (!(bp->b_flags & B_ERROR) && bp->b_error == 0)) { - msg = fixlabel((char *)NULL, ic->ic_args[1].ia_ptr, + msg = fixlabel(NULL, bio->bio_caller_info1.ptr, (struct disklabel *) - (bp->b_data + ic->ic_args[0].ia_long), + (bp->b_data + (int)bio->bio_caller_info2.offset), FALSE); if (msg != NULL) printf("%s\n", msg); } - free(ic, M_DEVBUF); - biodone(bp); + biodone(bio->bio_prev); } int diff --git a/sys/kern/subr_xxx.c b/sys/kern/subr_xxx.c index e8ce92e88f..66212f7c77 100644 --- a/sys/kern/subr_xxx.c +++ b/sys/kern/subr_xxx.c @@ -32,7 +32,7 @@ * * @(#)subr_xxx.c 8.1 (Berkeley) 6/10/93 * $FreeBSD: src/sys/kern/subr_xxx.c,v 1.15.2.1 2001/02/26 04:23:16 jlemon Exp $ - * $DragonFly: src/sys/kern/Attic/subr_xxx.c,v 1.4 2004/05/19 22:52:58 dillon Exp $ + * $DragonFly: src/sys/kern/Attic/subr_xxx.c,v 1.5 2006/02/17 19:18:06 dillon Exp $ */ /* @@ -135,11 +135,11 @@ nopoll(dev_t dev, int events, d_thread_t *td) } void -nostrategy(struct buf *bp) +nostrategy(dev_t dev, struct bio *bio) { - bp->b_flags |= B_ERROR; - bp->b_error = EOPNOTSUPP; - biodone(bp); + bio->bio_buf->b_flags |= B_ERROR; + bio->bio_buf->b_error = EOPNOTSUPP; + biodone(bio); } int diff --git a/sys/kern/tty_cons.c b/sys/kern/tty_cons.c index db1537b127..97a6600344 100644 --- a/sys/kern/tty_cons.c +++ b/sys/kern/tty_cons.c @@ -37,7 +37,7 @@ * * from: @(#)cons.c 7.2 (Berkeley) 5/9/91 * $FreeBSD: src/sys/kern/tty_cons.c,v 1.81.2.4 2001/12/17 18:44:41 guido Exp $ - * $DragonFly: src/sys/kern/tty_cons.c,v 1.14 2004/09/13 16:22:36 dillon Exp $ + * $DragonFly: src/sys/kern/tty_cons.c,v 1.15 2006/02/17 19:18:06 dillon Exp $ */ #include "opt_ddb.h" @@ -305,7 +305,7 @@ console_putport(lwkt_port_t port, lwkt_msg_t lmsg) error = cnclose(&msg->am_close); break; case CDEV_CMD_STRATEGY: - nostrategy(msg->am_strategy.bp); + nostrategy(msg->am_strategy.msg.dev, msg->am_strategy.bio); error = 0; break; case CDEV_CMD_IOCTL: diff --git a/sys/kern/vfs_aio.c b/sys/kern/vfs_aio.c index 6bb07f1208..f745152491 100644 --- a/sys/kern/vfs_aio.c +++ b/sys/kern/vfs_aio.c @@ -14,7 +14,7 @@ * of the author. This software is distributed AS-IS. * * $FreeBSD: src/sys/kern/vfs_aio.c,v 1.70.2.28 2003/05/29 06:15:35 alc Exp $ - * $DragonFly: src/sys/kern/vfs_aio.c,v 1.19 2005/10/11 09:59:56 corecode Exp $ + * $DragonFly: src/sys/kern/vfs_aio.c,v 1.20 2006/02/17 19:18:06 dillon Exp $ */ /* @@ -222,7 +222,7 @@ static int aio_free_entry(struct aiocblist *aiocbe); static void aio_process(struct aiocblist *aiocbe); static int aio_newproc(void); static int aio_aqueue(struct aiocb *job, int type); -static void aio_physwakeup(struct buf *bp); +static void aio_physwakeup(struct bio *bio); static int aio_fphysio(struct aiocblist *aiocbe); static int aio_qphysio(struct proc *p, struct aiocblist *iocb); static void aio_daemon(void *uproc); @@ -950,24 +950,23 @@ aio_qphysio(struct proc *p, struct aiocblist *aiocbe) lj->lioj_buffer_count++; /* Create and build a buffer header for a transfer. */ - bp = (struct buf *)getpbuf(NULL); + bp = getpbuf(NULL); BUF_KERNPROC(bp); /* * Get a copy of the kva from the physical buffer. */ - bp->b_caller1 = p; - bp->b_dev = vp->v_rdev; + bp->b_bio1.bio_caller_info1.ptr = p; error = 0; bp->b_bcount = cb->aio_nbytes; bp->b_bufsize = cb->aio_nbytes; bp->b_flags = B_PHYS | (cb->aio_lio_opcode == LIO_WRITE ? B_WRITE : B_READ); - bp->b_iodone = aio_physwakeup; + bp->b_bio1.bio_done = aio_physwakeup; bp->b_saveaddr = bp->b_data; bp->b_data = (void *)(uintptr_t)cb->aio_buf; - bp->b_blkno = btodb(cb->aio_offset); + bp->b_bio1.bio_blkno = btodb(cb->aio_offset); /* Bring buffer into kernel space. */ if (vmapbuf(bp) < 0) { @@ -978,7 +977,7 @@ aio_qphysio(struct proc *p, struct aiocblist *aiocbe) crit_enter(); aiocbe->bp = bp; - bp->b_spc = (void *)aiocbe; + bp->b_bio1.bio_caller_info2.ptr = aiocbe; TAILQ_INSERT_TAIL(&aio_bufjobs, aiocbe, list); TAILQ_INSERT_TAIL(&ki->kaio_bufqueue, aiocbe, plist); aiocbe->jobstate = JOBST_JOBQBUF; @@ -989,7 +988,7 @@ aio_qphysio(struct proc *p, struct aiocblist *aiocbe) crit_exit(); /* Perform transfer. */ - BUF_STRATEGY(bp, 0); + dev_dstrategy(vp->v_rdev, &bp->b_bio1); notify = 0; crit_enter(); @@ -2002,18 +2001,18 @@ process_signal(void *aioj) * signals. */ static void -aio_physwakeup(struct buf *bp) +aio_physwakeup(struct bio *bio) { + struct buf *bp = bio->bio_buf; struct aiocblist *aiocbe; struct proc *p; struct kaioinfo *ki; struct aio_liojob *lj; - wakeup(bp); + aiocbe = bio->bio_caller_info2.ptr; - aiocbe = (struct aiocblist *)bp->b_spc; if (aiocbe) { - p = bp->b_caller1; + p = bio->bio_caller_info1.ptr; aiocbe->jobstate = JOBST_JOBBFINISHED; aiocbe->uaiocb._aiocb_private.status -= bp->b_resid; @@ -2065,6 +2064,7 @@ aio_physwakeup(struct buf *bp) process_signal, aiocbe); } } + wakeup(bp); } #endif /* VFS_AIO */ diff --git a/sys/kern/vfs_bio.c b/sys/kern/vfs_bio.c index 8821da94f6..0d7a86c12d 100644 --- a/sys/kern/vfs_bio.c +++ b/sys/kern/vfs_bio.c @@ -12,7 +12,7 @@ * John S. Dyson. * * $FreeBSD: src/sys/kern/vfs_bio.c,v 1.242.2.20 2003/05/28 18:38:10 alc Exp $ - * $DragonFly: src/sys/kern/vfs_bio.c,v 1.53 2005/11/19 17:19:47 dillon Exp $ + * $DragonFly: src/sys/kern/vfs_bio.c,v 1.54 2006/02/17 19:18:06 dillon Exp $ */ /* @@ -87,9 +87,6 @@ static void vfs_page_set_valid(struct buf *bp, vm_ooffset_t off, static void vfs_clean_pages(struct buf * bp); static void vfs_setdirty(struct buf *bp); static void vfs_vmio_release(struct buf *bp); -#if 0 -static void vfs_backgroundwritedone(struct buf *bp); -#endif static int flushbufqueues(void); static int bd_request; @@ -168,22 +165,6 @@ SYSCTL_INT(_vfs, OID_AUTO, bufreusecnt, CTLFLAG_RD, &bufreusecnt, 0, SYSCTL_INT(_debug_sizeof, OID_AUTO, buf, CTLFLAG_RD, 0, sizeof(struct buf), "sizeof(struct buf)"); -#if 0 -/* - * Disable background writes for now. There appear to be races in the - * flags tests and locking operations as well as races in the completion - * code modifying the original bp (origbp) without holding a lock, assuming - * critical section protection when there might not be critical section - * protection. - * - * XXX disable also because the RB tree can't handle multiple blocks with - * the same lblkno. - */ -static int dobkgrdwrite = 0; -SYSCTL_INT(_debug, OID_AUTO, dobkgrdwrite, CTLFLAG_RW, &dobkgrdwrite, 0, - "Do background writes (honoring the BV_BKGRDWRITE flag)?"); -#endif - static int bufhashmask; static int bufhashshift; static LIST_HEAD(bufhashhdr, buf) *bufhashtbl, invalhash; @@ -449,12 +430,9 @@ bufinit(void) for (i = 0; i < nbuf; i++) { bp = &buf[i]; bzero(bp, sizeof *bp); - bp->b_bio.bio_buf = bp; /* back pointer (temporary) */ bp->b_flags = B_INVAL; /* we're just an empty header */ - bp->b_dev = NODEV; bp->b_qindex = BQUEUE_EMPTY; - bp->b_xflags = 0; - bp->b_iodone = NULL; + initbufbio(bp); xio_init(&bp->b_xio); LIST_INIT(&bp->b_dep); BUF_LOCKINIT(bp); @@ -531,6 +509,87 @@ bufinit(void) } +/* + * Initialize the embedded bio structures + */ +void +initbufbio(struct buf *bp) +{ + bp->b_bio1.bio_buf = bp; + bp->b_bio1.bio_prev = NULL; + bp->b_bio1.bio_blkno = (daddr_t)-1; + bp->b_bio1.bio_offset = NOOFFSET; + bp->b_bio1.bio_next = &bp->b_bio2; + bp->b_bio1.bio_done = NULL; + + bp->b_bio2.bio_buf = bp; + bp->b_bio2.bio_prev = &bp->b_bio1; + bp->b_bio2.bio_blkno = (daddr_t)-1; + bp->b_bio2.bio_offset = NOOFFSET; + bp->b_bio2.bio_next = NULL; + bp->b_bio2.bio_done = NULL; +} + +/* + * Reinitialize the embedded bio structures as well as any additional + * translation cache layers. + */ +void +reinitbufbio(struct buf *bp) +{ + struct bio *bio; + + for (bio = &bp->b_bio1; bio; bio = bio->bio_next) { + bio->bio_done = NULL; + bio->bio_blkno = (daddr_t)-1; + bio->bio_offset = NOOFFSET; + } +} + +/* + * Push another BIO layer onto an existing BIO and return it. The new + * BIO layer may already exist, holding cached translation data. + */ +struct bio * +push_bio(struct bio *bio) +{ + struct bio *nbio; + + if ((nbio = bio->bio_next) == NULL) { + int index = bio - &bio->bio_buf->b_bio_array[0]; + if (index >= NBUF_BIO) { + panic("push_bio: too many layers bp %p\n", + bio->bio_buf); + } + nbio = &bio->bio_buf->b_bio_array[index + 1]; + bio->bio_next = nbio; + nbio->bio_prev = bio; + nbio->bio_buf = bio->bio_buf; + nbio->bio_blkno = (daddr_t)-1; + nbio->bio_offset = NOOFFSET; + nbio->bio_done = NULL; + nbio->bio_next = NULL; + } + KKASSERT(nbio->bio_done == NULL); + return(nbio); +} + +void +pop_bio(struct bio *bio) +{ + /* NOP */ +} + +void +clearbiocache(struct bio *bio) +{ + while (bio) { + bio->bio_blkno = (daddr_t)-1; + bio->bio_offset = NOOFFSET; + bio = bio->bio_next; + } +} + /* * bfreekva: * @@ -629,7 +688,7 @@ bread(struct vnode * vp, daddr_t blkno, int size, struct buf ** bpp) bp->b_flags |= B_READ; bp->b_flags &= ~(B_ERROR | B_INVAL); vfs_busy_pages(bp, 0); - VOP_STRATEGY(vp, bp); + vn_strategy(vp, &bp->b_bio1); return (biowait(bp)); } return (0); @@ -658,7 +717,7 @@ breadn(struct vnode * vp, daddr_t blkno, int size, daddr_t * rablkno, bp->b_flags |= B_READ; bp->b_flags &= ~(B_ERROR | B_INVAL); vfs_busy_pages(bp, 0); - VOP_STRATEGY(vp, bp); + vn_strategy(vp, &bp->b_bio1); ++readwait; } @@ -672,7 +731,7 @@ breadn(struct vnode * vp, daddr_t blkno, int size, daddr_t * rablkno, rabp->b_flags &= ~(B_ERROR | B_INVAL); vfs_busy_pages(rabp, 0); BUF_KERNPROC(rabp); - VOP_STRATEGY(vp, rabp); + vn_strategy(vp, &rabp->b_bio1); } else { brelse(rabp); } @@ -701,9 +760,6 @@ int bwrite(struct buf * bp) { int oldflags; -#if 0 - struct buf *newbp; -#endif if (bp->b_flags & B_INVAL) { brelse(bp); @@ -735,63 +791,9 @@ bwrite(struct buf * bp) /* Mark the buffer clean */ bundirty(bp); -#if 0 - /* - * If this buffer is marked for background writing and we - * do not have to wait for it, make a copy and write the - * copy so as to leave this buffer ready for further use. - * - * This optimization eats a lot of memory. If we have a page - * or buffer shortfull we can't do it. - * - * XXX DISABLED! This had to be removed to support the RB_TREE - * work and, really, this isn't the best place to do this sort - * of thing anyway. We really need a device copy-on-write feature. - */ - if (dobkgrdwrite && - (bp->b_xflags & BX_BKGRDWRITE) && - (bp->b_flags & B_ASYNC) && - !vm_page_count_severe() && - !buf_dirty_count_severe()) { - if (bp->b_iodone) - panic("bwrite: need chained iodone"); - - /* get a new block */ - newbp = geteblk(bp->b_bufsize); - - /* set it to be identical to the old block */ - memcpy(newbp->b_data, bp->b_data, bp->b_bufsize); - newbp->b_lblkno = bp->b_lblkno; - newbp->b_blkno = bp->b_blkno; - newbp->b_offset = bp->b_offset; - newbp->b_iodone = vfs_backgroundwritedone; - newbp->b_flags |= B_ASYNC; - newbp->b_flags &= ~B_INVAL; - bgetvp(bp->b_vp, newbp); - - /* move over the dependencies */ - if (LIST_FIRST(&bp->b_dep) != NULL && bioops.io_movedeps) - (*bioops.io_movedeps)(bp, newbp); - - /* - * Initiate write on the copy, release the original to - * the B_LOCKED queue so that it cannot go away until - * the background write completes. If not locked it could go - * away and then be reconstituted while it was being written. - * If the reconstituted buffer were written, we could end up - * with two background copies being written at the same time. - */ - bp->b_xflags |= BX_BKGRDINPROG; - bp->b_flags |= B_LOCKED; - bqrelse(bp); - bp = newbp; - } -#endif - bp->b_flags &= ~(B_READ | B_DONE | B_ERROR); bp->b_flags |= B_CACHE; - bp->b_vp->v_numoutput++; vfs_busy_pages(bp, 1); /* @@ -803,7 +805,7 @@ bwrite(struct buf * bp) crit_exit(); if (oldflags & B_ASYNC) BUF_KERNPROC(bp); - VOP_STRATEGY(bp->b_vp, bp); + vn_strategy(bp->b_vp, &bp->b_bio1); if ((oldflags & B_ASYNC) == 0) { int rtval = biowait(bp); @@ -825,60 +827,6 @@ bwrite(struct buf * bp) return (0); } -#if 0 -/* - * Complete a background write started from bwrite. - */ -static void -vfs_backgroundwritedone(struct buf *bp) -{ - struct buf *origbp; - - /* - * Find the original buffer that we are writing. - */ - if ((origbp = gbincore(bp->b_vp, bp->b_lblkno)) == NULL) - panic("backgroundwritedone: lost buffer"); - /* - * Process dependencies then return any unfinished ones. - */ - if (LIST_FIRST(&bp->b_dep) != NULL && bioops.io_complete) - (*bioops.io_complete)(bp); - if (LIST_FIRST(&bp->b_dep) != NULL && bioops.io_movedeps) - (*bioops.io_movedeps)(bp, origbp); - /* - * Clear the BX_BKGRDINPROG flag in the original buffer - * and awaken it if it is waiting for the write to complete. - * If BX_BKGRDINPROG is not set in the original buffer it must - * have been released and re-instantiated - which is not legal. - */ - KASSERT((origbp->b_xflags & BX_BKGRDINPROG), ("backgroundwritedone: lost buffer2")); - origbp->b_xflags &= ~BX_BKGRDINPROG; - if (origbp->b_xflags & BX_BKGRDWAIT) { - origbp->b_xflags &= ~BX_BKGRDWAIT; - wakeup(&origbp->b_xflags); - } - /* - * Clear the B_LOCKED flag and remove it from the locked - * queue if it currently resides there. - */ - origbp->b_flags &= ~B_LOCKED; - if (BUF_LOCK(origbp, LK_EXCLUSIVE | LK_NOWAIT) == 0) { - bremfree(origbp); - bqrelse(origbp); - } - /* - * This buffer is marked B_NOCACHE, so when it is released - * by biodone, it will be tossed. We mark it with B_READ - * to avoid biodone doing a second vwakeup. - */ - bp->b_flags |= B_NOCACHE | B_READ; - bp->b_flags &= ~(B_CACHE | B_DONE); - bp->b_iodone = NULL; - biodone(bp); -} -#endif - /* * bdwrite: * @@ -917,8 +865,9 @@ bdwrite(struct buf *bp) * requesting a sync -- there might not be enough memory to do * the bmap then... So, this is important to do. */ - if (bp->b_lblkno == bp->b_blkno) { - VOP_BMAP(bp->b_vp, bp->b_lblkno, NULL, &bp->b_blkno, NULL, NULL); + if (bp->b_bio2.bio_blkno == (daddr_t)-1) { + VOP_BMAP(bp->b_vp, bp->b_lblkno, NULL, &bp->b_bio2.bio_blkno, + NULL, NULL); } /* @@ -1195,7 +1144,7 @@ brelse(struct buf * bp) */ resid = bp->b_bufsize; - foff = bp->b_offset; + foff = bp->b_loffset; for (i = 0; i < bp->b_xio.xio_npages; i++) { m = bp->b_xio.xio_pages[i]; @@ -1209,7 +1158,7 @@ brelse(struct buf * bp) */ if (m == bogus_page) { VOP_GETVOBJECT(vp, &obj); - poff = OFF_TO_IDX(bp->b_offset); + poff = OFF_TO_IDX(bp->b_loffset); for (j = i; j < bp->b_xio.xio_npages; j++) { vm_page_t mtmp; @@ -1337,7 +1286,6 @@ brelse(struct buf * bp) TAILQ_INSERT_HEAD(&bufqueues[bp->b_qindex], bp, b_freelist); LIST_REMOVE(bp, b_hash); LIST_INSERT_HEAD(&invalhash, bp, b_hash); - bp->b_dev = NODEV; } else if (bp->b_flags & (B_ERROR | B_INVAL | B_NOCACHE | B_RELBUF)) { /* * Buffers with junk contents. Again these buffers had better @@ -1352,7 +1300,6 @@ brelse(struct buf * bp) TAILQ_INSERT_HEAD(&bufqueues[BQUEUE_CLEAN], bp, b_freelist); LIST_REMOVE(bp, b_hash); LIST_INSERT_HEAD(&invalhash, bp, b_hash); - bp->b_dev = NODEV; } else if (bp->b_flags & B_LOCKED) { /* * Buffers that are locked. @@ -1596,6 +1543,10 @@ vfs_bio_awrite(struct buf * bp) * right now we support clustered writing only to regular files. If * we find a clusterable block we could be in the middle of a cluster * rather then at the beginning. + * + * NOTE: b_bio1 contains the logical loffset/lblkno and is aliased + * to b_lblkno and b_loffset. b_bio2 contains the translated block + * number. */ if ((vp->v_type == VREG) && (vp->v_mount != 0) && /* Only on nodes that have the size info */ @@ -1610,9 +1561,9 @@ vfs_bio_awrite(struct buf * bp) ((bpa->b_flags & (B_DELWRI | B_CLUSTEROK | B_INVAL)) == (B_DELWRI | B_CLUSTEROK)) && (bpa->b_bufsize == size)) { - if ((bpa->b_blkno == bpa->b_lblkno) || - (bpa->b_blkno != - bp->b_blkno + ((i * size) >> DEV_BSHIFT))) + if ((bpa->b_bio2.bio_blkno == (daddr_t)-1) || + (bpa->b_bio2.bio_blkno != + bp->b_bio2.bio_blkno + ((i * size) >> DEV_BSHIFT))) break; } else { break; @@ -1624,9 +1575,9 @@ vfs_bio_awrite(struct buf * bp) ((bpa->b_flags & (B_DELWRI | B_CLUSTEROK | B_INVAL)) == (B_DELWRI | B_CLUSTEROK)) && (bpa->b_bufsize == size)) { - if ((bpa->b_blkno == bpa->b_lblkno) || - (bpa->b_blkno != - bp->b_blkno - ((j * size) >> DEV_BSHIFT))) + if ((bpa->b_bio2.bio_blkno == (daddr_t)-1) || + (bpa->b_bio2.bio_blkno != + bp->b_bio2.bio_blkno - ((j * size) >> DEV_BSHIFT))) break; } else { break; @@ -1851,16 +1802,13 @@ restart: bp->b_flags = 0; bp->b_xflags = 0; - bp->b_dev = NODEV; bp->b_vp = NULL; - bp->b_blkno = bp->b_lblkno = 0; - bp->b_offset = NOOFFSET; - bp->b_iodone = NULL; bp->b_error = 0; bp->b_resid = 0; bp->b_bcount = 0; bp->b_xio.xio_npages = 0; bp->b_dirtyoff = bp->b_dirtyend = 0; + reinitbufbio(bp); LIST_INIT(&bp->b_dep); @@ -2222,14 +2170,14 @@ vfs_setdirty(struct buf *bp) if (bp->b_xio.xio_pages[i]->dirty) break; } - boffset = (i << PAGE_SHIFT) - (bp->b_offset & PAGE_MASK); + boffset = (i << PAGE_SHIFT) - (bp->b_loffset & PAGE_MASK); for (i = bp->b_xio.xio_npages - 1; i >= 0; --i) { if (bp->b_xio.xio_pages[i]->dirty) { break; } } - eoffset = ((i + 1) << PAGE_SHIFT) - (bp->b_offset & PAGE_MASK); + eoffset = ((i + 1) << PAGE_SHIFT) - (bp->b_loffset & PAGE_MASK); /* * Fit it to the buffer. @@ -2355,9 +2303,9 @@ loop: * Make sure that B_INVAL buffers do not have a cached * block number translation. */ - if ((bp->b_flags & B_INVAL) && (bp->b_blkno != bp->b_lblkno)) { - printf("Warning invalid buffer %p (vp %p lblkno %d) did not have cleared b_blkno cache\n", bp, vp, (int)blkno); - bp->b_blkno = bp->b_lblkno; + if ((bp->b_flags & B_INVAL) && (bp->b_bio2.bio_blkno != (daddr_t)-1)) { + printf("Warning invalid buffer %p (vp %p lblkno %d) did not have cleared bio_blkno cache\n", bp, vp, (int)blkno); + clearbiocache(&bp->b_bio2); } /* @@ -2406,8 +2354,8 @@ loop: if (bp->b_bcount != size) allocbuf(bp, size); - KASSERT(bp->b_offset != NOOFFSET, - ("getblk: no buffer offset")); + KASSERT(bp->b_loffset != NOOFFSET, + ("getblk: no buffer offset")); /* * A buffer with B_DELWRI set and B_CACHE clear must @@ -2508,10 +2456,12 @@ loop: /* * Insert the buffer into the hash, so that it can * be found by incore. bgetvp() and bufhash() - * must be synchronized with each other. + * must be synchronized with each other. Make sure the + * translation layer has been cleared. */ - bp->b_blkno = bp->b_lblkno = blkno; - bp->b_offset = offset; + bp->b_lblkno = blkno; + bp->b_loffset = offset; + bp->b_bio2.bio_blkno = (daddr_t)-1; bgetvp(vp, bp); LIST_REMOVE(bp, b_hash); @@ -2688,7 +2638,7 @@ allocbuf(struct buf *bp, int size) newbsize = (size + DEV_BSIZE - 1) & ~(DEV_BSIZE - 1); desiredpages = (size == 0) ? 0 : - num_pages((bp->b_offset & PAGE_MASK) + newbsize); + num_pages((bp->b_loffset & PAGE_MASK) + newbsize); if (bp->b_flags & B_MALLOC) panic("allocbuf: VMIO buffer can't be malloced"); @@ -2754,7 +2704,7 @@ allocbuf(struct buf *bp, int size) vm_page_t m; vm_pindex_t pi; - pi = OFF_TO_IDX(bp->b_offset) + bp->b_xio.xio_npages; + pi = OFF_TO_IDX(bp->b_loffset) + bp->b_xio.xio_npages; if ((m = vm_page_lookup(obj, pi)) == NULL) { /* * note: must allocate system pages @@ -2825,7 +2775,7 @@ allocbuf(struct buf *bp, int size) */ toff = bp->b_bcount; - tinc = PAGE_SIZE - ((bp->b_offset + toff) & PAGE_MASK); + tinc = PAGE_SIZE - ((bp->b_loffset + toff) & PAGE_MASK); while ((bp->b_flags & B_CACHE) && toff < size) { vm_pindex_t pi; @@ -2833,12 +2783,12 @@ allocbuf(struct buf *bp, int size) if (tinc > (size - toff)) tinc = size - toff; - pi = ((bp->b_offset & PAGE_MASK) + toff) >> + pi = ((bp->b_loffset & PAGE_MASK) + toff) >> PAGE_SHIFT; vfs_buf_test_cache( bp, - bp->b_offset, + bp->b_loffset, toff, tinc, bp->b_xio.xio_pages[pi] @@ -2849,8 +2799,8 @@ allocbuf(struct buf *bp, int size) /* * Step 3, fixup the KVM pmap. Remember that - * bp->b_data is relative to bp->b_offset, but - * bp->b_offset may be offset into the first page. + * bp->b_data is relative to bp->b_loffset, but + * bp->b_loffset may be offset into the first page. */ bp->b_data = (caddr_t) @@ -2861,7 +2811,7 @@ allocbuf(struct buf *bp, int size) bp->b_xio.xio_npages ); bp->b_data = (caddr_t)((vm_offset_t)bp->b_data | - (vm_offset_t)(bp->b_offset & PAGE_MASK)); + (vm_offset_t)(bp->b_loffset & PAGE_MASK)); } } if (newbsize < bp->b_bufsize) @@ -2900,6 +2850,39 @@ biowait(struct buf * bp) } } +/* + * This associates a tracking count with an I/O. vn_strategy() and + * dev_dstrategy() do this automatically but there are a few cases + * where a vnode or device layer is bypassed when a block translation + * is cached. In such cases bio_start_transaction() may be called on + * the bypassed layers so the system gets an I/O in progress indication + * for those higher layers. + */ +void +bio_start_transaction(struct bio *bio, struct bio_track *track) +{ + bio->bio_track = track; + atomic_add_int(&track->bk_active, 1); +} + +/* + * Initiate I/O on a vnode. + */ +void +vn_strategy(struct vnode *vp, struct bio *bio) +{ + struct bio_track *track; + + if (bio->bio_buf->b_flags & B_READ) + track = &vp->v_track_read; + else + track = &vp->v_track_write; + bio->bio_track = track; + atomic_add_int(&track->bk_active, 1); + vop_strategy(*vp->v_ops, vp, bio); +} + + /* * biodone: * @@ -2918,44 +2901,69 @@ biowait(struct buf * bp) * biodone does not mess with B_INVAL, allowing the I/O routine or the * initiator to leave B_INVAL set to brelse the buffer out of existance * in the biodone routine. - * - * b_dev is required to be reinitialized prior to the top level strategy - * call in a device stack. To avoid improper reuse, biodone() sets - * b_dev to NODEV. */ void -biodone(struct buf *bp) +biodone(struct bio *bio) { + struct buf *bp = bio->bio_buf; int error; crit_enter(); - KASSERT(BUF_REFCNTNB(bp) > 0, ("biodone: bp %p not busy %d", bp, BUF_REFCNTNB(bp))); - KASSERT(!(bp->b_flags & B_DONE), ("biodone: bp %p already done", bp)); - biodone_t *biodone_func; + KASSERT(BUF_REFCNTNB(bp) > 0, + ("biodone: bp %p not busy %d", bp, BUF_REFCNTNB(bp))); + KASSERT(!(bp->b_flags & B_DONE), + ("biodone: bp %p already done", bp)); bp->b_flags |= B_DONE; - bp->b_dev = NODEV; runningbufwakeup(bp); - if (bp->b_flags & B_FREEBUF) { - brelse(bp); - crit_exit(); - return; - } + /* + * Run up the chain of BIO's. + */ + while (bio) { + biodone_t *done_func; + struct bio_track *track; - if ((bp->b_flags & B_READ) == 0) { - vwakeup(bp); + /* + * BIO tracking. Most but not all BIOs are tracked. + */ + if ((track = bio->bio_track) != NULL) { + atomic_subtract_int(&track->bk_active, 1); + if (track->bk_active < 0) { + panic("biodone: bad active count bio %p\n", + bio); + } + if (track->bk_waitflag) { + track->bk_waitflag = 0; + wakeup(track); + } + bio->bio_track = NULL; + } + + /* + * A bio_done function terminates the loop. The function + * will be responsible for any further chaining and/or + * buffer management. + */ + if ((done_func = bio->bio_done) != NULL) { + bio->bio_done = NULL; + done_func(bio); + crit_exit(); + return; + } + bio = bio->bio_prev; } - /* call optional completion function if requested */ - if (bp->b_iodone != NULL) { - biodone_func = bp->b_iodone; - bp->b_iodone = NULL; - (*biodone_func) (bp); + /* + * Special case (XXX) - not a read or write. + */ + if (bp->b_flags & B_FREEBUF) { + brelse(bp); crit_exit(); return; } + if (LIST_FIRST(&bp->b_dep) != NULL && bioops.io_complete) (*bioops.io_complete)(bp); @@ -2983,9 +2991,8 @@ biodone(struct buf *bp) } #endif - foff = bp->b_offset; - KASSERT(bp->b_offset != NOOFFSET, - ("biodone: no buffer offset")); + foff = bp->b_loffset; + KASSERT(foff != NOOFFSET, ("biodone: no buffer offset")); if (error) { panic("biodone: no object"); @@ -3128,7 +3135,7 @@ vfs_unbusy_pages(struct buf *bp) * critical section protection particularly. */ if (m == bogus_page) { - m = vm_page_lookup(obj, OFF_TO_IDX(bp->b_offset) + i); + m = vm_page_lookup(obj, OFF_TO_IDX(bp->b_loffset) + i); if (!m) { panic("vfs_unbusy_pages: page missing"); } @@ -3165,8 +3172,8 @@ vfs_page_set_valid(struct buf *bp, vm_ooffset_t off, int pageno, vm_page_t m) */ soff = off; eoff = (off + PAGE_SIZE) & ~(off_t)PAGE_MASK; - if (eoff > bp->b_offset + bp->b_bcount) - eoff = bp->b_offset + bp->b_bcount; + if (eoff > bp->b_loffset + bp->b_bcount) + eoff = bp->b_loffset + bp->b_bcount; /* * Set valid range. This is typically the entire buffer and thus the @@ -3207,9 +3214,9 @@ vfs_busy_pages(struct buf *bp, int clear_modify) vm_ooffset_t foff; VOP_GETVOBJECT(vp, &obj); - foff = bp->b_offset; - KASSERT(bp->b_offset != NOOFFSET, - ("vfs_busy_pages: no buffer offset")); + foff = bp->b_loffset; + KASSERT(bp->b_loffset != NOOFFSET, + ("vfs_busy_pages: no buffer offset")); vfs_setdirty(bp); retry: @@ -3290,16 +3297,15 @@ vfs_clean_pages(struct buf *bp) if (bp->b_flags & B_VMIO) { vm_ooffset_t foff; - foff = bp->b_offset; - KASSERT(bp->b_offset != NOOFFSET, - ("vfs_clean_pages: no buffer offset")); + foff = bp->b_loffset; + KASSERT(foff != NOOFFSET, ("vfs_clean_pages: no buffer offset")); for (i = 0; i < bp->b_xio.xio_npages; i++) { vm_page_t m = bp->b_xio.xio_pages[i]; vm_ooffset_t noff = (foff + PAGE_SIZE) & ~(off_t)PAGE_MASK; vm_ooffset_t eoff = noff; - if (eoff > bp->b_offset + bp->b_bufsize) - eoff = bp->b_offset + bp->b_bufsize; + if (eoff > bp->b_loffset + bp->b_bufsize) + eoff = bp->b_loffset + bp->b_bufsize; vfs_page_set_valid(bp, foff, i, m); /* vm_page_clear_dirty(m, foff & PAGE_MASK, eoff - foff); */ foff = noff; @@ -3311,8 +3317,8 @@ vfs_clean_pages(struct buf *bp) * vfs_bio_set_validclean: * * Set the range within the buffer to valid and clean. The range is - * relative to the beginning of the buffer, b_offset. Note that b_offset - * itself may be offset from the beginning of the first page. + * relative to the beginning of the buffer, b_loffset. Note that + * b_loffset itself may be offset from the beginning of the first page. */ void @@ -3328,7 +3334,7 @@ vfs_bio_set_validclean(struct buf *bp, int base, int size) * first page that can be validated. */ - base += (bp->b_offset & PAGE_MASK); + base += (bp->b_loffset & PAGE_MASK); n = PAGE_SIZE - (base & PAGE_MASK); for (i = base / PAGE_SIZE; size > 0 && i < bp->b_xio.xio_npages; ++i) { @@ -3363,7 +3369,7 @@ vfs_bio_clrbuf(struct buf *bp) if ((bp->b_flags & (B_VMIO | B_MALLOC)) == B_VMIO) { bp->b_flags &= ~(B_INVAL|B_ERROR); if ((bp->b_xio.xio_npages == 1) && (bp->b_bufsize < PAGE_SIZE) && - (bp->b_offset & PAGE_MASK) == 0) { + (bp->b_loffset & PAGE_MASK) == 0) { mask = (1 << (bp->b_bufsize / DEV_BSIZE)) - 1; if ((bp->b_xio.xio_pages[0]->valid & mask) == mask) { bp->b_resid = 0; @@ -3481,7 +3487,7 @@ vm_hold_free_pages(struct buf *bp, vm_offset_t from, vm_offset_t to) if (p && (index < bp->b_xio.xio_npages)) { if (p->busy) { printf("vm_hold_free_pages: blkno: %d, lblkno: %d\n", - bp->b_blkno, bp->b_lblkno); + bp->b_bio2.bio_blkno, bp->b_lblkno); } bp->b_xio.xio_pages[index] = NULL; pmap_kremove(pg); @@ -3638,11 +3644,10 @@ DB_SHOW_COMMAND(buffer, db_show_buffer) db_printf("b_flags = 0x%b\n", (u_int)bp->b_flags, PRINT_BUF_FLAGS); db_printf("b_error = %d, b_bufsize = %ld, b_bcount = %ld, " - "b_resid = %ld\nb_dev = (%d,%d), b_data = %p, " - "b_blkno = %d, b_pblkno = %d\n", + "b_resid = %ld\n, b_data = %p, " + "bio_blkno(disk) = %d, bio_blkno(phys) = %d\n", bp->b_error, bp->b_bufsize, bp->b_bcount, bp->b_resid, - major(bp->b_dev), minor(bp->b_dev), - bp->b_data, bp->b_blkno, bp->b_pblkno); + bp->b_data, bp->b_bio2.bio_blkno, (bp->b_bio2.bio_next ? bp->b_bio2.bio_next->bio_blkno : (daddr_t)-1)); if (bp->b_xio.xio_npages) { int i; db_printf("b_xio.xio_npages = %d, pages(OBJ, IDX, PA): ", diff --git a/sys/kern/vfs_cluster.c b/sys/kern/vfs_cluster.c index 776dcb8425..2fe26b07e6 100644 --- a/sys/kern/vfs_cluster.c +++ b/sys/kern/vfs_cluster.c @@ -34,7 +34,7 @@ * * @(#)vfs_cluster.c 8.7 (Berkeley) 2/13/94 * $FreeBSD: src/sys/kern/vfs_cluster.c,v 1.92.2.9 2001/11/18 07:10:59 dillon Exp $ - * $DragonFly: src/sys/kern/vfs_cluster.c,v 1.14 2005/08/03 16:36:33 hmp Exp $ + * $DragonFly: src/sys/kern/vfs_cluster.c,v 1.15 2006/02/17 19:18:06 dillon Exp $ */ #include "opt_debug_cluster.h" @@ -69,6 +69,8 @@ static struct cluster_save * static struct buf * cluster_rbuild (struct vnode *vp, u_quad_t filesize, daddr_t lbn, daddr_t blkno, long size, int run, struct buf *fbp); +static void cluster_callback (struct bio *); + static int write_behind = 1; SYSCTL_INT(_vfs, OID_AUTO, write_behind, CTLFLAG_RW, &write_behind, 0, ""); @@ -158,10 +160,10 @@ cluster_read(struct vnode *vp, u_quad_t filesize, daddr_t lblkno, } reqbp = bp = NULL; } else { - off_t firstread = bp->b_offset; + off_t firstread = bp->b_loffset; - KASSERT(bp->b_offset != NOOFFSET, - ("cluster_read: no buffer offset")); + KASSERT(firstread != NOOFFSET, + ("cluster_read: no buffer offset")); if (firstread + totread > filesize) totread = filesize - firstread; if (totread > size) { @@ -225,7 +227,7 @@ single_block_read: } else { rbp = getblk(vp, lblkno, size, 0, 0); rbp->b_flags |= B_READ | B_ASYNC | B_RAM; - rbp->b_blkno = blkno; + rbp->b_bio2.bio_blkno = blkno; } } } @@ -243,9 +245,10 @@ single_block_read: vfs_busy_pages(bp, 0); } bp->b_flags &= ~(B_ERROR|B_INVAL); - if ((bp->b_flags & B_ASYNC) || bp->b_iodone != NULL) + if ((bp->b_flags & B_ASYNC) || bp->b_bio1.bio_done != NULL) BUF_KERNPROC(bp); - error = VOP_STRATEGY(vp, bp); + vn_strategy(vp, &bp->b_bio1); + error = bp->b_error; } /* @@ -278,9 +281,9 @@ single_block_read: vfs_busy_pages(rbp, 0); } rbp->b_flags &= ~(B_ERROR|B_INVAL); - if ((rbp->b_flags & B_ASYNC) || rbp->b_iodone != NULL) + if ((rbp->b_flags & B_ASYNC) || rbp->b_bio1.bio_done != NULL) BUF_KERNPROC(rbp); - (void) VOP_STRATEGY(vp, rbp); + vn_strategy(vp, &rbp->b_bio1); } } if (reqbp) @@ -323,7 +326,7 @@ cluster_rbuild(struct vnode *vp, u_quad_t filesize, daddr_t lbn, tbp->b_flags |= B_ASYNC | B_READ | B_RAM; } - tbp->b_blkno = blkno; + tbp->b_bio2.bio_blkno = blkno; if( (tbp->b_flags & B_MALLOC) || ((tbp->b_flags & B_VMIO) == 0) || (run <= 1) ) return tbp; @@ -341,15 +344,16 @@ cluster_rbuild(struct vnode *vp, u_quad_t filesize, daddr_t lbn, bp->b_data = (char *)((vm_offset_t)bp->b_data | ((vm_offset_t)tbp->b_data & PAGE_MASK)); bp->b_flags = B_ASYNC | B_READ | B_CLUSTER | B_VMIO; - bp->b_iodone = cluster_callback; - bp->b_blkno = blkno; + bp->b_bio1.bio_done = cluster_callback; + bp->b_bio1.bio_caller_info1.cluster_head = NULL; + bp->b_bio1.bio_caller_info2.cluster_tail = NULL; bp->b_lblkno = lbn; - bp->b_offset = tbp->b_offset; - KASSERT(bp->b_offset != NOOFFSET, ("cluster_rbuild: no buffer offset")); + bp->b_loffset = tbp->b_loffset; + bp->b_bio2.bio_blkno = (daddr_t)-1; + KASSERT(bp->b_loffset != NOOFFSET, + ("cluster_rbuild: no buffer offset")); pbgetvp(vp, bp); - TAILQ_INIT(&bp->b_cluster.cluster_head); - bp->b_bcount = 0; bp->b_bufsize = 0; bp->b_xio.xio_npages = 0; @@ -427,9 +431,9 @@ cluster_rbuild(struct vnode *vp, u_quad_t filesize, daddr_t lbn, * expect. */ tbp->b_flags |= B_READ | B_ASYNC; - if (tbp->b_blkno == tbp->b_lblkno) { - tbp->b_blkno = bn; - } else if (tbp->b_blkno != bn) { + if (tbp->b_bio2.bio_blkno == (daddr_t)-1) { + tbp->b_bio2.bio_blkno = bn; + } else if (tbp->b_bio2.bio_blkno != bn) { brelse(tbp); break; } @@ -439,8 +443,7 @@ cluster_rbuild(struct vnode *vp, u_quad_t filesize, daddr_t lbn, * to biodone() it in cluster_callback() anyway */ BUF_KERNPROC(tbp); - TAILQ_INSERT_TAIL(&bp->b_cluster.cluster_head, - tbp, b_cluster.cluster_entry); + cluster_append(&bp->b_bio1, tbp); for (j = 0; j < tbp->b_xio.xio_npages; j += 1) { vm_page_t m; m = tbp->b_xio.xio_pages[j]; @@ -495,11 +498,14 @@ cluster_rbuild(struct vnode *vp, u_quad_t filesize, daddr_t lbn, * This is complicated by the fact that any of the buffers might have * extra memory (if there were no empty buffer headers at allocbuf time) * that we will need to shift around. + * + * The returned bio is &bp->b_bio1 */ void -cluster_callback(struct buf *bp) +cluster_callback(struct bio *bio) { - struct buf *nbp, *tbp; + struct buf *bp = bio->bio_buf; + struct buf *tbp; int error = 0; /* @@ -511,11 +517,11 @@ cluster_callback(struct buf *bp) pmap_qremove(trunc_page((vm_offset_t) bp->b_data), bp->b_xio.xio_npages); /* * Move memory from the large cluster buffer into the component - * buffers and mark IO as done on these. + * buffers and mark IO as done on these. Since the memory map + * is the same, no actual copying is required. */ - for (tbp = TAILQ_FIRST(&bp->b_cluster.cluster_head); - tbp; tbp = nbp) { - nbp = TAILQ_NEXT(&tbp->b_cluster, cluster_entry); + while ((tbp = bio->bio_caller_info1.cluster_head) != NULL) { + bio->bio_caller_info1.cluster_head = tbp->b_cluster_next; if (error) { tbp->b_flags |= B_ERROR; tbp->b_error = error; @@ -532,7 +538,7 @@ cluster_callback(struct buf *bp) if (tbp->b_flags & B_DIRECT) tbp->b_flags |= B_RELBUF; } - biodone(tbp); + biodone(&tbp->b_bio1); } relpbuf(bp, &cluster_pbuf_freecnt); } @@ -596,14 +602,16 @@ cluster_write(struct buf *bp, u_quad_t filesize, int seqcount) lblocksize = bp->b_bufsize; } lbn = bp->b_lblkno; - KASSERT(bp->b_offset != NOOFFSET, ("cluster_write: no buffer offset")); + KASSERT(bp->b_loffset != NOOFFSET, + ("cluster_write: no buffer offset")); /* Initialize vnode to beginning of file. */ if (lbn == 0) vp->v_lasta = vp->v_clen = vp->v_cstart = vp->v_lastw = 0; if (vp->v_clen == 0 || lbn != vp->v_lastw + 1 || - (bp->b_blkno != vp->v_lasta + btodb(lblocksize))) { + bp->b_bio2.bio_blkno == (daddr_t)-1 || + (bp->b_bio2.bio_blkno != vp->v_lasta + btodb(lblocksize))) { maxclen = vp->v_mount->mnt_iosize_max / lblocksize - 1; if (vp->v_clen != 0) { /* @@ -623,7 +631,7 @@ cluster_write(struct buf *bp, u_quad_t filesize, int seqcount) * flush. */ cursize = vp->v_lastw - vp->v_cstart + 1; - if (((u_quad_t) bp->b_offset + lblocksize) != filesize || + if (((u_quad_t) bp->b_loffset + lblocksize) != filesize || lbn != vp->v_lastw + 1 || vp->v_clen <= cursize) { if (!async && seqcount > 0) { cluster_wbuild_wb(vp, lblocksize, @@ -663,7 +671,7 @@ cluster_write(struct buf *bp, u_quad_t filesize, int seqcount) bdwrite(*bpp); free(buflist, M_SEGMENT); vp->v_lastw = lbn; - vp->v_lasta = bp->b_blkno; + vp->v_lasta = bp->b_bio2.bio_blkno; return; } } @@ -674,13 +682,13 @@ cluster_write(struct buf *bp, u_quad_t filesize, int seqcount) * existing cluster. */ if ((vp->v_type == VREG) && - ((u_quad_t) bp->b_offset + lblocksize) != filesize && - (bp->b_blkno == bp->b_lblkno) && - (VOP_BMAP(vp, lbn, NULL, &bp->b_blkno, &maxclen, NULL) || - bp->b_blkno == -1)) { + ((u_quad_t) bp->b_loffset + lblocksize) != filesize && + (bp->b_bio2.bio_blkno == (daddr_t)-1) && + (VOP_BMAP(vp, lbn, NULL, &bp->b_bio2.bio_blkno, &maxclen, NULL) || + bp->b_bio2.bio_blkno == (daddr_t)-1)) { bawrite(bp); vp->v_clen = 0; - vp->v_lasta = bp->b_blkno; + vp->v_lasta = bp->b_bio2.bio_blkno; vp->v_cstart = lbn + 1; vp->v_lastw = lbn; return; @@ -716,7 +724,7 @@ cluster_write(struct buf *bp, u_quad_t filesize, int seqcount) bdwrite(bp); } vp->v_lastw = lbn; - vp->v_lasta = bp->b_blkno; + vp->v_lasta = bp->b_bio2.bio_blkno; } @@ -777,13 +785,12 @@ cluster_wbuild(struct vnode *vp, long size, daddr_t start_lbn, int len) * We got a pbuf to make the cluster in. * so initialise it. */ - TAILQ_INIT(&bp->b_cluster.cluster_head); bp->b_bcount = 0; bp->b_bufsize = 0; bp->b_xio.xio_npages = 0; - bp->b_blkno = tbp->b_blkno; bp->b_lblkno = tbp->b_lblkno; - bp->b_offset = tbp->b_offset; + bp->b_loffset = tbp->b_loffset; + bp->b_bio2.bio_blkno = tbp->b_bio2.bio_blkno; /* * We are synthesizing a buffer out of vm_page_t's, but @@ -795,7 +802,9 @@ cluster_wbuild(struct vnode *vp, long size, daddr_t start_lbn, int len) ((vm_offset_t)tbp->b_data & PAGE_MASK)); bp->b_flags |= B_CLUSTER | (tbp->b_flags & (B_VMIO | B_NEEDCOMMIT | B_NOWDRAIN)); - bp->b_iodone = cluster_callback; + bp->b_bio1.bio_done = cluster_callback; + bp->b_bio1.bio_caller_info1.cluster_head = NULL; + bp->b_bio1.bio_caller_info2.cluster_tail = NULL; pbgetvp(vp, bp); /* * From this location in the file, scan forward to see @@ -837,8 +846,8 @@ cluster_wbuild(struct vnode *vp, long size, daddr_t start_lbn, int len) * and would not be too large */ if ((tbp->b_bcount != size) || - ((bp->b_blkno + (dbsize * i)) != - tbp->b_blkno) || + ((bp->b_bio2.bio_blkno + (dbsize * i)) != + tbp->b_bio2.bio_blkno) || ((tbp->b_xio.xio_npages + bp->b_xio.xio_npages) > (vp->v_mount->mnt_iosize_max / PAGE_SIZE))) { BUF_UNLOCK(tbp); @@ -854,10 +863,13 @@ cluster_wbuild(struct vnode *vp, long size, daddr_t start_lbn, int len) tbp->b_flags &= ~B_DONE; crit_exit(); } /* end of code for non-first buffers only */ - /* check for latent dependencies to be handled */ - if ((LIST_FIRST(&tbp->b_dep)) != NULL && - bioops.io_start) + + /* + * check for latent dependencies to be handled + */ + if (LIST_FIRST(&tbp->b_dep) != NULL && bioops.io_start) (*bioops.io_start)(tbp); + /* * If the IO is via the VM then we do some * special VM hackery (yuck). Since the buffer's @@ -898,11 +910,9 @@ cluster_wbuild(struct vnode *vp, long size, daddr_t start_lbn, int len) tbp->b_flags &= ~(B_READ | B_DONE | B_ERROR); tbp->b_flags |= B_ASYNC; reassignbuf(tbp, tbp->b_vp); /* put on clean list */ - ++tbp->b_vp->v_numoutput; crit_exit(); BUF_KERNPROC(tbp); - TAILQ_INSERT_TAIL(&bp->b_cluster.cluster_head, - tbp, b_cluster.cluster_entry); + cluster_append(&bp->b_bio1, tbp); } finishcluster: pmap_qenter(trunc_page((vm_offset_t) bp->b_data), @@ -942,14 +952,28 @@ cluster_collectbufs(struct vnode *vp, struct buf *last_bp) for (lbn = vp->v_cstart, i = 0; i < len; lbn++, i++) { (void) bread(vp, lbn, last_bp->b_bcount, &bp); buflist->bs_children[i] = bp; - if (bp->b_blkno == bp->b_lblkno) - VOP_BMAP(bp->b_vp, bp->b_lblkno, NULL, &bp->b_blkno, + if (bp->b_bio2.bio_blkno == (daddr_t)-1) + VOP_BMAP(bp->b_vp, bp->b_lblkno, NULL, &bp->b_bio2.bio_blkno, NULL, NULL); } buflist->bs_children[i] = bp = last_bp; - if (bp->b_blkno == bp->b_lblkno) - VOP_BMAP(bp->b_vp, bp->b_lblkno, NULL, &bp->b_blkno, + if (bp->b_bio2.bio_blkno == (daddr_t)-1) + VOP_BMAP(bp->b_vp, bp->b_lblkno, NULL, &bp->b_bio2.bio_blkno, NULL, NULL); buflist->bs_nchildren = i + 1; return (buflist); } + +void +cluster_append(struct bio *bio, struct buf *tbp) +{ + tbp->b_cluster_next = NULL; + if (bio->bio_caller_info1.cluster_head == NULL) { + bio->bio_caller_info1.cluster_head = tbp; + bio->bio_caller_info2.cluster_tail = tbp; + } else { + bio->bio_caller_info2.cluster_tail->b_cluster_next = tbp; + bio->bio_caller_info2.cluster_tail = tbp; + } +} + diff --git a/sys/kern/vfs_default.c b/sys/kern/vfs_default.c index 5cd84f83ca..47137ef73e 100644 --- a/sys/kern/vfs_default.c +++ b/sys/kern/vfs_default.c @@ -37,7 +37,7 @@ * * * $FreeBSD: src/sys/kern/vfs_default.c,v 1.28.2.7 2003/01/10 18:23:26 bde Exp $ - * $DragonFly: src/sys/kern/vfs_default.c,v 1.28 2005/09/17 07:43:00 dillon Exp $ + * $DragonFly: src/sys/kern/vfs_default.c,v 1.29 2006/02/17 19:18:06 dillon Exp $ */ #include @@ -1156,12 +1156,12 @@ vop_nolookup(ap) static int vop_nostrategy (struct vop_strategy_args *ap) { - printf("No strategy for buffer at %p\n", ap->a_bp); + printf("No strategy for buffer at %p\n", ap->a_bio->bio_buf); vprint("", ap->a_vp); - vprint("", ap->a_bp->b_vp); - ap->a_bp->b_flags |= B_ERROR; - ap->a_bp->b_error = EOPNOTSUPP; - biodone(ap->a_bp); + vprint("", ap->a_bio->bio_buf->b_vp); + ap->a_bio->bio_buf->b_flags |= B_ERROR; + ap->a_bio->bio_buf->b_error = EOPNOTSUPP; + biodone(ap->a_bio); return (EOPNOTSUPP); } diff --git a/sys/kern/vfs_lock.c b/sys/kern/vfs_lock.c index 5b66b49bb3..dac1263e71 100644 --- a/sys/kern/vfs_lock.c +++ b/sys/kern/vfs_lock.c @@ -31,7 +31,7 @@ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $DragonFly: src/sys/kern/vfs_lock.c,v 1.7 2005/04/20 17:01:50 dillon Exp $ + * $DragonFly: src/sys/kern/vfs_lock.c,v 1.8 2006/02/17 19:18:06 dillon Exp $ */ /* @@ -459,7 +459,7 @@ allocvnode(int lktimeout, int lkflags) #ifdef INVARIANTS if (vp->v_data) panic("cleaned vnode isn't"); - if (vp->v_numoutput) + if (vp->v_track_read.bk_active + vp->v_track_write.bk_active) panic("Clean vnode has pending I/O's"); KKASSERT(vp->v_mount == NULL); #endif diff --git a/sys/kern/vfs_subr.c b/sys/kern/vfs_subr.c index e39dda8f4b..7941451e34 100644 --- a/sys/kern/vfs_subr.c +++ b/sys/kern/vfs_subr.c @@ -37,7 +37,7 @@ * * @(#)vfs_subr.c 8.31 (Berkeley) 5/26/95 * $FreeBSD: src/sys/kern/vfs_subr.c,v 1.249.2.30 2003/04/04 20:35:57 tegge Exp $ - * $DragonFly: src/sys/kern/vfs_subr.c,v 1.65 2005/10/31 21:48:53 dillon Exp $ + * $DragonFly: src/sys/kern/vfs_subr.c,v 1.66 2006/02/17 19:18:06 dillon Exp $ */ /* @@ -259,25 +259,6 @@ vattr_null(struct vattr *vap) vap->va_fsmid = VNOVAL; } -/* - * Update outstanding I/O count and do wakeup if requested. - */ -void -vwakeup(struct buf *bp) -{ - struct vnode *vp; - - if ((vp = bp->b_vp)) { - vp->v_numoutput--; - if (vp->v_numoutput < 0) - panic("vwakeup: neg numoutput"); - if ((vp->v_numoutput == 0) && (vp->v_flag & VBWAIT)) { - vp->v_flag &= ~VBWAIT; - wakeup((caddr_t) &vp->v_numoutput); - } - } -} - /* * Flush out and invalidate all buffers associated with a vnode. * @@ -306,10 +287,10 @@ vinvalbuf(struct vnode *vp, int flags, struct thread *td, */ if (flags & V_SAVE) { crit_enter(); - while (vp->v_numoutput) { - vp->v_flag |= VBWAIT; - error = tsleep((caddr_t)&vp->v_numoutput, - slpflag, "vinvlbuf", slptimeo); + while (vp->v_track_write.bk_active) { + vp->v_track_write.bk_waitflag = 1; + error = tsleep(&vp->v_track_write, slpflag, + "vinvlbuf", slptimeo); if (error) { crit_exit(); return (error); @@ -320,7 +301,7 @@ vinvalbuf(struct vnode *vp, int flags, struct thread *td, if ((error = VOP_FSYNC(vp, MNT_WAIT, td)) != 0) return (error); crit_enter(); - if (vp->v_numoutput > 0 || + if (vp->v_track_write.bk_active > 0 || !RB_EMPTY(&vp->v_rbdirty_tree)) panic("vinvalbuf: dirty bufs"); } @@ -351,15 +332,15 @@ vinvalbuf(struct vnode *vp, int flags, struct thread *td, * VM object can also have read-I/O in-progress. */ do { - while (vp->v_numoutput > 0) { - vp->v_flag |= VBWAIT; - tsleep(&vp->v_numoutput, 0, "vnvlbv", 0); + while (vp->v_track_write.bk_active > 0) { + vp->v_track_write.bk_waitflag = 1; + tsleep(&vp->v_track_write, 0, "vnvlbv", 0); } if (VOP_GETVOBJECT(vp, &object) == 0) { while (object->paging_in_progress) vm_object_pip_sleep(object, "vnvlbx"); } - } while (vp->v_numoutput > 0); + } while (vp->v_track_write.bk_active > 0); crit_exit(); @@ -478,9 +459,9 @@ vtruncbuf(struct vnode *vp, struct thread *td, off_t length, int blksize) /* * Wait for any in-progress I/O to complete before returning (why?) */ - while (vp->v_numoutput > 0) { - vp->v_flag |= VBWAIT; - tsleep(&vp->v_numoutput, 0, "vbtrunc", 0); + while (vp->v_track_write.bk_active > 0) { + vp->v_track_write.bk_waitflag = 1; + tsleep(&vp->v_track_write, 0, "vbtrunc", 0); } crit_exit(); @@ -680,9 +661,9 @@ vfsync_wait_output(struct vnode *vp, int (*waitoutput)(struct vnode *, struct th { int error = 0; - while (vp->v_numoutput) { - vp->v_flag |= VBWAIT; - tsleep(&vp->v_numoutput, 0, "fsfsn", 0); + while (vp->v_track_write.bk_active) { + vp->v_track_write.bk_waitflag = 1; + tsleep(&vp->v_track_write, 0, "fsfsn", 0); } if (waitoutput) error = waitoutput(vp, curthread); @@ -805,7 +786,6 @@ bgetvp(struct vnode *vp, struct buf *bp) vhold(vp); bp->b_vp = vp; - bp->b_dev = vn_todev(vp); /* * Insert onto list for new vnode. */ @@ -862,7 +842,6 @@ pbgetvp(struct vnode *vp, struct buf *bp) bp->b_vp = vp; bp->b_flags |= B_PAGING; - bp->b_dev = vn_todev(vp); } /* @@ -1339,8 +1318,6 @@ vprint(char *label, struct vnode *vp) strcat(buf, "|VTEXT"); if (vp->v_flag & VSYSTEM) strcat(buf, "|VSYSTEM"); - if (vp->v_flag & VBWAIT) - strcat(buf, "|VBWAIT"); if (vp->v_flag & VFREE) strcat(buf, "|VFREE"); if (vp->v_flag & VOBJBUF) diff --git a/sys/kern/vfs_vopops.c b/sys/kern/vfs_vopops.c index df81850c65..0bc15995ee 100644 --- a/sys/kern/vfs_vopops.c +++ b/sys/kern/vfs_vopops.c @@ -32,7 +32,7 @@ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $DragonFly: src/sys/kern/vfs_vopops.c,v 1.16 2005/09/17 07:43:00 dillon Exp $ + * $DragonFly: src/sys/kern/vfs_vopops.c,v 1.17 2006/02/17 19:18:06 dillon Exp $ */ #include @@ -883,7 +883,7 @@ vop_bmap(struct vop_ops *ops, struct vnode *vp, daddr_t bn, struct vnode **vpp, } int -vop_strategy(struct vop_ops *ops, struct vnode *vp, struct buf *bp) +vop_strategy(struct vop_ops *ops, struct vnode *vp, struct bio *bio) { struct vop_strategy_args ap; int error; @@ -891,10 +891,10 @@ vop_strategy(struct vop_ops *ops, struct vnode *vp, struct buf *bp) ap.a_head.a_desc = &vop_strategy_desc; ap.a_head.a_ops = ops; ap.a_vp = vp; - ap.a_bp = bp; + ap.a_bio = bio; DO_OPS(ops, error, &ap, vop_strategy); - if (error == 0 && (bp->b_flags & B_READ) == 0) + if (error == 0 && (bio->bio_buf->b_flags & B_READ) == 0) cache_update_fsmid_vp(vp); return(error); } diff --git a/sys/platform/pc32/i386/machdep.c b/sys/platform/pc32/i386/machdep.c index 454e962a26..ae7ea32367 100644 --- a/sys/platform/pc32/i386/machdep.c +++ b/sys/platform/pc32/i386/machdep.c @@ -36,7 +36,7 @@ * * from: @(#)machdep.c 7.4 (Berkeley) 6/3/91 * $FreeBSD: src/sys/i386/i386/machdep.c,v 1.385.2.30 2003/05/31 08:48:05 alc Exp $ - * $DragonFly: src/sys/platform/pc32/i386/machdep.c,v 1.85 2005/12/12 08:15:03 dillon Exp $ + * $DragonFly: src/sys/platform/pc32/i386/machdep.c,v 1.86 2006/02/17 19:18:06 dillon Exp $ */ #include "use_apm.h" @@ -2515,20 +2515,26 @@ Debugger(const char *msg) * Determine the size of the transfer, and make sure it is * within the boundaries of the partition. Adjust transfer * if needed, and signal errors or early completion. + * + * On success a new bio layer is pushed with the translated + * block number, and returned. */ -int -bounds_check_with_label(struct buf *bp, struct disklabel *lp, int wlabel) +struct bio * +bounds_check_with_label(dev_t dev, struct bio *bio, + struct disklabel *lp, int wlabel) { - struct partition *p = lp->d_partitions + dkpart(bp->b_dev); + struct bio *nbio; + struct buf *bp = bio->bio_buf; + struct partition *p = lp->d_partitions + dkpart(dev); int labelsect = lp->d_partitions[0].p_offset; int maxsz = p->p_size, sz = (bp->b_bcount + DEV_BSIZE - 1) >> DEV_BSHIFT; /* overwriting disk label ? */ /* XXX should also protect bootstrap in first 8K */ - if (bp->b_blkno + p->p_offset <= LABELSECTOR + labelsect && + if (bio->bio_blkno + p->p_offset <= LABELSECTOR + labelsect && #if LABELSECTOR != 0 - bp->b_blkno + p->p_offset + sz > LABELSECTOR + labelsect && + bio->bio_blkno + p->p_offset + sz > LABELSECTOR + labelsect && #endif (bp->b_flags & B_READ) == 0 && wlabel == 0) { bp->b_error = EROFS; @@ -2537,7 +2543,7 @@ bounds_check_with_label(struct buf *bp, struct disklabel *lp, int wlabel) #if defined(DOSBBSECTOR) && defined(notyet) /* overwriting master boot record? */ - if (bp->b_blkno + p->p_offset <= DOSBBSECTOR && + if (bio->bio_blkno + p->p_offset <= DOSBBSECTOR && (bp->b_flags & B_READ) == 0 && wlabel == 0) { bp->b_error = EROFS; goto bad; @@ -2545,27 +2551,27 @@ bounds_check_with_label(struct buf *bp, struct disklabel *lp, int wlabel) #endif /* beyond partition? */ - if (bp->b_blkno < 0 || bp->b_blkno + sz > maxsz) { + if (bio->bio_blkno < 0 || bio->bio_blkno + sz > maxsz) { /* if exactly at end of disk, return an EOF */ - if (bp->b_blkno == maxsz) { + if (bio->bio_blkno == maxsz) { bp->b_resid = bp->b_bcount; return(0); } /* or truncate if part of it fits */ - sz = maxsz - bp->b_blkno; + sz = maxsz - bio->bio_blkno; if (sz <= 0) { bp->b_error = EINVAL; goto bad; } bp->b_bcount = sz << DEV_BSHIFT; } - - bp->b_pblkno = bp->b_blkno + p->p_offset; - return(1); + nbio = push_bio(bio); + nbio->bio_blkno = bio->bio_blkno + p->p_offset; + return (nbio); bad: bp->b_flags |= B_ERROR; - return(-1); + return (NULL); } #ifdef DDB diff --git a/sys/sys/bio.h b/sys/sys/bio.h index 9ad8414409..616d965799 100644 --- a/sys/sys/bio.h +++ b/sys/sys/bio.h @@ -31,29 +31,55 @@ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $DragonFly: src/sys/sys/bio.h,v 1.2 2005/08/12 00:17:26 hmp Exp $ + * $DragonFly: src/sys/sys/bio.h,v 1.3 2006/02/17 19:18:07 dillon Exp $ */ +#ifndef _SYS_BIO_H_ +#define _SYS_BIO_H_ + #ifndef _SYS_QUEUE_H_ #include #endif -typedef void biodone_t(struct buf *); +struct bio; +struct bio_track; + +typedef void biodone_t(struct bio *); /* * BIO encapsulation for storage drivers and systems that do not require * caching support for underlying blocks. + * + * NOTE: bio_done and bio_caller_info belong to the caller, while + * bio_driver_info belongs to the driver. + * + * bio_track is only non-NULL when an I/O is in progress. */ struct bio { - LIST_ENTRY(bio) bio_chain; /* Chaining. */ + TAILQ_ENTRY(bio) bio_act; /* driver queue when active */ + struct bio_track *bio_track; /* BIO tracking structure */ + struct bio *bio_prev; /* BIO stack */ + struct bio *bio_next; /* BIO stack / cached translations */ struct buf *bio_buf; /* High-level buffer back-pointer. */ - daddr_t bio_blkno; /* Underlying physical block number. */ - daddr_t bio_pblkno; /* Physical block number. */ - dev_t bio_dev; /* Device associated to this I/O. */ - biodone_t *bio_done; /* Completion function (optional). */ - long bio_resid; /* Remaining I/O. */ - int bio_flags; /* Operational flags. */ - int bio_error; /* Error value. */ - void *bio_driver_ctx; /* Private context for drivers. */ - void *bio_caller_ctx; /* Private context for callers. */ + biodone_t *bio_done; /* Caller completion function */ + daddr_t bio_blkno; /* Block number relative to device */ + off_t bio_offset; /* Logical offset relative to device */ + void *bio_driver_info; + union { + void *ptr; + off_t offset; + int index; + struct buf *cluster_head; + struct bio *cluster_parent; + } bio_caller_info1; + union { + void *ptr; + off_t offset; + int index; + struct buf *cluster_tail; + } bio_caller_info2; }; + +void bio_start_transaction(struct bio *, struct bio_track *); + +#endif diff --git a/sys/sys/biotrack.h b/sys/sys/biotrack.h new file mode 100644 index 0000000000..8de423a1e0 --- /dev/null +++ b/sys/sys/biotrack.h @@ -0,0 +1,18 @@ +/* + * SYS/BIOTRACK.H + * + * $DragonFly: src/sys/sys/biotrack.h,v 1.1 2006/02/17 19:18:07 dillon Exp $ + */ + +#ifndef _SYS_BIOTRACK_H_ +#define _SYS_BIOTRACK_H_ + +/* + * BIO tracking structure - tracks in-progress BIOs + */ +struct bio_track { + int bk_active; /* I/O's currently in progress */ + int bk_waitflag; +}; + +#endif diff --git a/sys/sys/buf.h b/sys/sys/buf.h index 1119ab96d5..11755365a1 100644 --- a/sys/sys/buf.h +++ b/sys/sys/buf.h @@ -37,7 +37,7 @@ * * @(#)buf.h 8.9 (Berkeley) 3/30/95 * $FreeBSD: src/sys/sys/buf.h,v 1.88.2.10 2003/01/25 19:02:23 dillon Exp $ - * $DragonFly: src/sys/sys/buf.h,v 1.21 2005/11/19 17:19:48 dillon Exp $ + * $DragonFly: src/sys/sys/buf.h,v 1.22 2006/02/17 19:18:07 dillon Exp $ */ #ifndef _SYS_BUF_H_ @@ -67,10 +67,13 @@ #endif struct buf; +struct bio; struct mount; struct vnode; struct xio; +#define NBUF_BIO 4 + struct buf_rb_tree; RB_PROTOTYPE(buf_rb_tree, buf, b_rbnode, rb_buf_compare); @@ -94,16 +97,6 @@ extern struct bio_ops { int (*io_countdeps) (struct buf *, int); } bioops; -struct iodone_chain { - long ic_prev_flags; - void (*ic_prev_iodone) (struct buf *); - void *ic_prev_iodone_chain; - struct { - long ia_long; - void *ia_ptr; - } ic_args[5]; -}; - /* * The buffer header describes an I/O operation in the kernel. * @@ -119,13 +112,38 @@ struct iodone_chain { * * b_resid. Number of bytes remaining in I/O. After an I/O operation * completes, b_resid is usually 0 indicating 100% success. + * + * b_bio1 and b_bio2 represent the two primary I/O layers. Additional + * I/O layers are allocated out of the object cache and may also exist. + * + * b_bio1 is the logical layer and contains offset or block number + * data for the primary vnode, b_vp. I/O operations are almost + * universally initiated from the logical layer, so you will often + * see things like: vn_strategy(bp->b_vp, &bp->b_bio1). + * + * b_bio2 is the first physical layer (typically the slice-relative + * layer) and contains the translated offset or block number for + * the block device underlying a filesystem. Filesystems such as UFS + * will maintain cached translations and you may see them initiate + * a 'physical' I/O using vn_strategy(devvp, &bp->b_bio2). BUT, + * remember that the layering is relative to bp->b_vp, so the + * device-relative block numbers for buffer cache operations that occur + * directly on a block device will be in the first BIO layer. + * + * NOTE!!! Only the BIO subsystem accesses b_bio1 and b_bio2 directly. + * ALL STRATEGY LAYERS FOR BOTH VNODES AND DEVICES ONLY ACCESS THE BIO + * PASSED TO THEM, AND WILL PUSH ANOTHER BIO LAYER IF FORWARDING THE + * I/O DEEPER. In particular, a vn_strategy() or dev_dstrategy() + * call should not ever access buf->b_vp as this vnode may be totally + * unrelated to the vnode/device whos strategy routine was called. */ struct buf { LIST_ENTRY(buf) b_hash; /* Hash chain. */ RB_ENTRY(buf) b_rbnode; /* Red-Black node in vnode RB tree */ TAILQ_ENTRY(buf) b_freelist; /* Free list position if not active. */ - TAILQ_ENTRY(buf) b_act; /* driver queue when active. *new* */ - struct bio b_bio; /* Underlying I/O */ + struct buf *b_cluster_next; /* Next buffer (cluster code) */ + struct vnode *b_vp; /* (vp, lblkno) index */ + struct bio b_bio_array[NBUF_BIO]; /* BIO translation layers */ long b_flags; /* B_* flags. */ unsigned short b_qindex; /* buffer queue index */ unsigned char b_xflags; /* extra flags */ @@ -133,42 +151,25 @@ struct buf { long b_bufsize; /* Allocated buffer size. */ long b_runningbufspace; /* when I/O is running, pipelining */ long b_bcount; /* Valid bytes in buffer. */ + long b_resid; /* Remaining I/O */ + int b_error; /* Error return */ caddr_t b_data; /* Memory, superblocks, indirect etc. */ caddr_t b_kvabase; /* base kva for buffer */ int b_kvasize; /* size of kva for buffer */ - daddr_t b_lblkno; /* Logical block number. */ - off_t b_offset; /* Offset into file */ - /* For nested b_iodone's. */ - struct iodone_chain *b_iodone_chain; - struct vnode *b_vp; /* Device vnode. */ int b_dirtyoff; /* Offset in buffer of dirty region. */ int b_dirtyend; /* Offset of end of dirty region. */ void *b_saveaddr; /* Original b_addr for physio. */ - union pager_info { - void *pg_spc; - int pg_reqpage; - } b_pager; - union cluster_info { - TAILQ_HEAD(cluster_list_head, buf) cluster_head; - TAILQ_ENTRY(buf) cluster_entry; - } b_cluster; - struct xio b_xio; /* page list management for buffer head. */ + struct xio b_xio; /* data buffer page list management */ struct workhead b_dep; /* List of filesystem dependencies. */ - struct chain_info { /* buffer chaining */ - struct buf *parent; - int count; - } b_chain; }; -#define b_dev b_bio.bio_dev -#define b_resid b_bio.bio_resid -#define b_error b_bio.bio_error -#define b_blkno b_bio.bio_blkno -#define b_pblkno b_bio.bio_pblkno -#define b_driver1 b_bio.bio_driver_ctx -#define b_caller1 b_bio.bio_caller_ctx -#define b_iodone b_bio.bio_done -#define b_spc b_pager.pg_spc +/* + * XXX temporary + */ +#define b_bio1 b_bio_array[0] /* logical layer */ +#define b_bio2 b_bio_array[1] /* (typically) the disk layer */ +#define b_loffset b_bio1.bio_offset +#define b_lblkno b_bio1.bio_blkno /* * These flags are kept in b_flags. @@ -284,11 +285,11 @@ extern char *buf_wmesg; /* Default buffer lock message */ #endif /* _KERNEL */ -struct buf_queue_head { - TAILQ_HEAD(buf_queue, buf) queue; - daddr_t last_pblkno; - struct buf *insert_point; - struct buf *switch_point; +struct bio_queue_head { + TAILQ_HEAD(bio_queue, bio) queue; + daddr_t last_blkno; + struct bio *insert_point; + struct bio *switch_point; }; /* @@ -343,6 +344,9 @@ caddr_t bufhashinit (caddr_t); void bufinit (void); void bwillwrite (void); int buf_dirty_count_severe (void); +void initbufbio(struct buf *); +void reinitbufbio(struct buf *); +void clearbiocache(struct bio *); void bremfree (struct buf *); int bread (struct vnode *, daddr_t, int, struct buf **); int breadn (struct vnode *, daddr_t, int, daddr_t *, int *, int, @@ -356,16 +360,18 @@ int bowrite (struct buf *); void brelse (struct buf *); void bqrelse (struct buf *); int vfs_bio_awrite (struct buf *); -struct buf * getpbuf (int *); +struct buf *getpbuf (int *); struct buf *incore (struct vnode *, daddr_t); struct buf *gbincore (struct vnode *, daddr_t); int inmem (struct vnode *, daddr_t); struct buf *getblk (struct vnode *, daddr_t, int, int, int); struct buf *geteblk (int); +struct bio *push_bio(struct bio *); +void pop_bio(struct bio *); int biowait (struct buf *); -void biodone (struct buf *); +void biodone (struct bio *); -void cluster_callback (struct buf *); +void cluster_append(struct bio *, struct buf *); int cluster_read (struct vnode *, u_quad_t, daddr_t, long, long, int, struct buf **); int cluster_wbuild (struct vnode *, long, daddr_t, int); @@ -377,7 +383,6 @@ void vfs_bio_set_validclean (struct buf *, int base, int size); void vfs_bio_clrbuf (struct buf *); void vfs_busy_pages (struct buf *, int clear_modify); void vfs_unbusy_pages (struct buf *); -void vwakeup (struct buf *); int vmapbuf (struct buf *); void vunmapbuf (struct buf *); void relpbuf (struct buf *, int *); diff --git a/sys/sys/buf2.h b/sys/sys/buf2.h index c7d9bc639e..1c61be2e6a 100644 --- a/sys/sys/buf2.h +++ b/sys/sys/buf2.h @@ -37,7 +37,7 @@ * * @(#)buf.h 8.9 (Berkeley) 3/30/95 * $FreeBSD: src/sys/sys/buf.h,v 1.88.2.10 2003/01/25 19:02:23 dillon Exp $ - * $DragonFly: src/sys/sys/buf2.h,v 1.11 2005/11/19 17:19:48 dillon Exp $ + * $DragonFly: src/sys/sys/buf2.h,v 1.12 2006/02/17 19:18:07 dillon Exp $ */ #ifndef _SYS_BUF2_H_ @@ -145,42 +145,42 @@ BUF_REFCNTNB(struct buf *bp) panic("free locked buf") static __inline void -bufq_init(struct buf_queue_head *head) +bioq_init(struct bio_queue_head *head) { TAILQ_INIT(&head->queue); - head->last_pblkno = 0; + head->last_blkno = 0; head->insert_point = NULL; head->switch_point = NULL; } static __inline void -bufq_insert_tail(struct buf_queue_head *head, struct buf *bp) +bioq_insert_tail(struct bio_queue_head *head, struct bio *bio) { - if ((bp->b_flags & B_ORDERED) != 0) { - head->insert_point = bp; + if ((bio->bio_buf->b_flags & B_ORDERED) != 0) { + head->insert_point = bio; head->switch_point = NULL; } - TAILQ_INSERT_TAIL(&head->queue, bp, b_act); + TAILQ_INSERT_TAIL(&head->queue, bio, bio_act); } static __inline void -bufq_remove(struct buf_queue_head *head, struct buf *bp) +bioq_remove(struct bio_queue_head *head, struct bio *bio) { - if (bp == head->switch_point) - head->switch_point = TAILQ_NEXT(bp, b_act); - if (bp == head->insert_point) { - head->insert_point = TAILQ_PREV(bp, buf_queue, b_act); + if (bio == head->switch_point) + head->switch_point = TAILQ_NEXT(bio, bio_act); + if (bio == head->insert_point) { + head->insert_point = TAILQ_PREV(bio, bio_queue, bio_act); if (head->insert_point == NULL) - head->last_pblkno = 0; - } else if (bp == TAILQ_FIRST(&head->queue)) - head->last_pblkno = bp->b_pblkno; - TAILQ_REMOVE(&head->queue, bp, b_act); + head->last_blkno = 0; + } else if (bio == TAILQ_FIRST(&head->queue)) + head->last_blkno = bio->bio_blkno; + TAILQ_REMOVE(&head->queue, bio, bio_act); if (TAILQ_FIRST(&head->queue) == head->switch_point) head->switch_point = NULL; } -static __inline struct buf * -bufq_first(struct buf_queue_head *head) +static __inline struct bio * +bioq_first(struct bio_queue_head *head) { return (TAILQ_FIRST(&head->queue)); } diff --git a/sys/sys/conf.h b/sys/sys/conf.h index a583e85fbf..50e3547081 100644 --- a/sys/sys/conf.h +++ b/sys/sys/conf.h @@ -37,7 +37,7 @@ * * @(#)conf.h 8.5 (Berkeley) 1/9/95 * $FreeBSD: src/sys/sys/conf.h,v 1.103.2.6 2002/03/11 01:14:55 dd Exp $ - * $DragonFly: src/sys/sys/conf.h,v 1.9 2005/02/21 18:56:02 dillon Exp $ + * $DragonFly: src/sys/sys/conf.h,v 1.10 2006/02/17 19:18:07 dillon Exp $ */ #ifndef _SYS_CONF_H_ @@ -45,6 +45,7 @@ #include #include +#include #define SPECNAMELEN 15 @@ -76,6 +77,8 @@ struct specinfo { int __sid_bsize_best; /* optimal block size */ } __si_disk; } __si_u; + struct bio_track si_track_read; + struct bio_track si_track_write; time_t si_lastread; /* time_second */ time_t si_lastwrite; /* time_second */ }; @@ -103,6 +106,7 @@ struct specinfo { */ struct buf; +struct bio; struct proc; struct uio; struct knote; @@ -130,7 +134,7 @@ typedef struct thread d_thread_t; typedef int d_clone_t (dev_t dev); typedef int d_open_t (dev_t dev, int oflags, int devtype, d_thread_t *td); typedef int d_close_t (dev_t dev, int fflag, int devtype, d_thread_t *td); -typedef void d_strategy_t (struct buf *bp); +typedef void d_strategy_t (dev_t dev, struct bio *bio); typedef int d_ioctl_t (dev_t dev, u_long cmd, caddr_t data, int fflag, d_thread_t *td); typedef int d_dump_t (dev_t dev, u_int count, u_int blkno, u_int secsize); @@ -152,15 +156,6 @@ typedef int l_rint_t (int c, struct tty *tp); typedef int l_start_t (struct tty *tp); typedef int l_modem_t (struct tty *tp, int flag); -/* - * XXX: The dummy argument can be used to do what strategy1() never - * did anywhere: Create a per device flag to lock the device during - * label/slice surgery, all calls with a dummy == 0 gets stalled on - * a queue somewhere, whereas dummy == 1 are let through. Once out - * of surgery, reset the flag and restart all the stuff on the stall - * queue. - */ -#define BUF_STRATEGY(bp, dummy) dev_dstrategy((bp)->b_dev, bp) /* * Types for d_flags. */ diff --git a/sys/sys/device.h b/sys/sys/device.h index 2fec2ac23e..cff7597422 100644 --- a/sys/sys/device.h +++ b/sys/sys/device.h @@ -31,7 +31,7 @@ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $DragonFly: src/sys/sys/device.h,v 1.3 2004/07/16 05:51:57 dillon Exp $ + * $DragonFly: src/sys/sys/device.h,v 1.4 2006/02/17 19:18:07 dillon Exp $ */ #ifndef _SYS_DEVICE_H_ @@ -70,11 +70,11 @@ struct cdevmsg_close { }; /* - * void d_strategy(struct buf *bp) + * void d_strategy(dev_t dev, struct bio *bio) */ struct cdevmsg_strategy { struct cdevmsg msg; - struct buf *bp; + struct bio *bio; }; /* @@ -204,7 +204,8 @@ int dev_dflags(dev_t dev); int dev_dmaj(dev_t dev); int dev_dopen(dev_t dev, int oflags, int devtype, struct thread *td); int dev_dclose(dev_t dev, int fflag, int devtype, struct thread *td); -void dev_dstrategy(dev_t dev, struct buf *bp); +void dev_dstrategy(dev_t dev, struct bio *bio); +void dev_dstrategy_chain(dev_t dev, struct bio *bio); int dev_dioctl(dev_t dev, u_long cmd, caddr_t data, int fflag, struct thread *td); int dev_ddump(dev_t dev); int dev_dpsize(dev_t dev); diff --git a/sys/sys/disklabel.h b/sys/sys/disklabel.h index d0d6ee1b72..ea199cb849 100644 --- a/sys/sys/disklabel.h +++ b/sys/sys/disklabel.h @@ -32,7 +32,7 @@ * * @(#)disklabel.h 8.2 (Berkeley) 7/10/94 * $FreeBSD: src/sys/sys/disklabel.h,v 1.49.2.7 2001/05/27 05:58:26 jkh Exp $ - * $DragonFly: src/sys/sys/disklabel.h,v 1.11 2005/04/30 23:04:21 swildner Exp $ + * $DragonFly: src/sys/sys/disklabel.h,v 1.12 2006/02/17 19:18:07 dillon Exp $ */ #ifndef _SYS_DISKLABEL_H_ @@ -423,15 +423,16 @@ dkunit(dev_t dev) } struct buf; -struct buf_queue_head; +struct bio; +struct bio_queue_head; -int bounds_check_with_label (struct buf *bp, struct disklabel *lp, - int wlabel); -void diskerr (struct buf *bp, dev_t dev, char *what, int pri, int blkdone, - struct disklabel *lp); +struct bio *bounds_check_with_label (dev_t dev, struct bio *bio, + struct disklabel *lp, int wlabel); +void diskerr (struct bio *bio, dev_t dev, const char *what, int pri, + int blkdone, struct disklabel *lp); void disksort (struct buf *ap, struct buf *bp); char *readdisklabel (dev_t dev, struct disklabel *lp); -void bufqdisksort (struct buf_queue_head *ap, struct buf *bp); +void bioqdisksort (struct bio_queue_head *ap, struct bio *bio); int setdisklabel (struct disklabel *olp, struct disklabel *nlp, u_long openmask); int writedisklabel (dev_t dev, struct disklabel *lp); diff --git a/sys/sys/disklabel32.h b/sys/sys/disklabel32.h index c29bc715a5..87fb20fa37 100644 --- a/sys/sys/disklabel32.h +++ b/sys/sys/disklabel32.h @@ -32,7 +32,7 @@ * * @(#)disklabel.h 8.2 (Berkeley) 7/10/94 * $FreeBSD: src/sys/sys/disklabel.h,v 1.49.2.7 2001/05/27 05:58:26 jkh Exp $ - * $DragonFly: src/sys/sys/disklabel32.h,v 1.11 2005/04/30 23:04:21 swildner Exp $ + * $DragonFly: src/sys/sys/disklabel32.h,v 1.12 2006/02/17 19:18:07 dillon Exp $ */ #ifndef _SYS_DISKLABEL_H_ @@ -423,15 +423,16 @@ dkunit(dev_t dev) } struct buf; -struct buf_queue_head; +struct bio; +struct bio_queue_head; -int bounds_check_with_label (struct buf *bp, struct disklabel *lp, - int wlabel); -void diskerr (struct buf *bp, dev_t dev, char *what, int pri, int blkdone, - struct disklabel *lp); +struct bio *bounds_check_with_label (dev_t dev, struct bio *bio, + struct disklabel *lp, int wlabel); +void diskerr (struct bio *bio, dev_t dev, const char *what, int pri, + int blkdone, struct disklabel *lp); void disksort (struct buf *ap, struct buf *bp); char *readdisklabel (dev_t dev, struct disklabel *lp); -void bufqdisksort (struct buf_queue_head *ap, struct buf *bp); +void bioqdisksort (struct bio_queue_head *ap, struct bio *bio); int setdisklabel (struct disklabel *olp, struct disklabel *nlp, u_long openmask); int writedisklabel (dev_t dev, struct disklabel *lp); diff --git a/sys/sys/diskslice.h b/sys/sys/diskslice.h index d63e6b11c3..644f74aa17 100644 --- a/sys/sys/diskslice.h +++ b/sys/sys/diskslice.h @@ -24,7 +24,7 @@ * SUCH DAMAGE. * * $FreeBSD: src/sys/sys/diskslice.h,v 1.36.2.1 2001/01/29 01:50:50 ken Exp $ - * $DragonFly: src/sys/sys/diskslice.h,v 1.5 2005/03/05 18:08:50 swildner Exp $ + * $DragonFly: src/sys/sys/diskslice.h,v 1.6 2006/02/17 19:18:07 dillon Exp $ */ #ifndef _SYS_DISKSLICE_H_ @@ -82,9 +82,10 @@ struct diskslices { #define dsgetlabel(dev, ssp) (ssp->dss_slices[dkslice(dev)].ds_label) struct buf; +struct bio; struct disklabel; -int dscheck (struct buf *bp, struct diskslices *ssp); +struct bio *dscheck (dev_t dev, struct bio *bio, struct diskslices *ssp); void dsclose (dev_t dev, int mode, struct diskslices *ssp); void dsgone (struct diskslices **sspp); int dsinit (dev_t dev, struct disklabel *lp, diff --git a/sys/sys/odisklabel.h b/sys/sys/odisklabel.h index 434b13d25c..991a7be0f6 100644 --- a/sys/sys/odisklabel.h +++ b/sys/sys/odisklabel.h @@ -32,7 +32,7 @@ * * @(#)disklabel.h 8.2 (Berkeley) 7/10/94 * $FreeBSD: src/sys/sys/disklabel.h,v 1.49.2.7 2001/05/27 05:58:26 jkh Exp $ - * $DragonFly: src/sys/sys/Attic/odisklabel.h,v 1.11 2005/04/30 23:04:21 swildner Exp $ + * $DragonFly: src/sys/sys/Attic/odisklabel.h,v 1.12 2006/02/17 19:18:07 dillon Exp $ */ #ifndef _SYS_DISKLABEL_H_ @@ -423,15 +423,16 @@ dkunit(dev_t dev) } struct buf; -struct buf_queue_head; +struct bio; +struct bio_queue_head; -int bounds_check_with_label (struct buf *bp, struct disklabel *lp, - int wlabel); -void diskerr (struct buf *bp, dev_t dev, char *what, int pri, int blkdone, - struct disklabel *lp); +struct bio *bounds_check_with_label (dev_t dev, struct bio *bio, + struct disklabel *lp, int wlabel); +void diskerr (struct bio *bio, dev_t dev, const char *what, int pri, + int blkdone, struct disklabel *lp); void disksort (struct buf *ap, struct buf *bp); char *readdisklabel (dev_t dev, struct disklabel *lp); -void bufqdisksort (struct buf_queue_head *ap, struct buf *bp); +void bioqdisksort (struct bio_queue_head *ap, struct bio *bio); int setdisklabel (struct disklabel *olp, struct disklabel *nlp, u_long openmask); int writedisklabel (dev_t dev, struct disklabel *lp); diff --git a/sys/sys/vfsops.h b/sys/sys/vfsops.h index f4dd817523..c65c22bd72 100644 --- a/sys/sys/vfsops.h +++ b/sys/sys/vfsops.h @@ -31,7 +31,7 @@ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $DragonFly: src/sys/sys/vfsops.h,v 1.14 2005/09/17 07:43:01 dillon Exp $ + * $DragonFly: src/sys/sys/vfsops.h,v 1.15 2006/02/17 19:18:07 dillon Exp $ */ /* @@ -337,7 +337,7 @@ struct vop_bmap_args { struct vop_strategy_args { struct vop_generic_args a_head; struct vnode *a_vp; - struct buf *a_bp; + struct bio *a_bio; }; struct vop_print_args { @@ -820,7 +820,7 @@ int vop_unlock(struct vop_ops *ops, struct vnode *vp, int flags, struct thread *td); int vop_bmap(struct vop_ops *ops, struct vnode *vp, daddr_t bn, struct vnode **vpp, daddr_t *bnp, int *runp, int *runb); -int vop_strategy(struct vop_ops *ops, struct vnode *vp, struct buf *bp); +int vop_strategy(struct vop_ops *ops, struct vnode *vp, struct bio *bio); int vop_print(struct vop_ops *ops, struct vnode *vp); int vop_pathconf(struct vop_ops *ops, struct vnode *vp, int name, register_t *retval); @@ -1075,8 +1075,6 @@ extern struct vnodeop_desc vop_nrename_desc; vop_unlock(*(vp)->v_ops, vp, flags, td) #define VOP_BMAP(vp, bn, vpp, bnp, runp, runb) \ vop_bmap(*(vp)->v_ops, vp, bn, vpp, bnp, runp, runb) -#define VOP_STRATEGY(vp, bp) \ - vop_strategy(*(vp)->v_ops, vp, bp) #define VOP_PRINT(vp) \ vop_print(*(vp)->v_ops, vp) #define VOP_PATHCONF(vp, name, retval) \ @@ -1112,6 +1110,7 @@ extern struct vnodeop_desc vop_nrename_desc; #define VOP_GETVOBJECT(vp, objpp) \ vop_getvobject(*(vp)->v_ops, vp, objpp) /* no VOP_VFSSET() */ +/* VOP_STRATEGY - does not exist, use vn_strategy() */ /* * 'OLD' VOP calls. These calls may only be made by the new API diff --git a/sys/sys/vnode.h b/sys/sys/vnode.h index c839615644..7e417c2668 100644 --- a/sys/sys/vnode.h +++ b/sys/sys/vnode.h @@ -32,7 +32,7 @@ * * @(#)vnode.h 8.7 (Berkeley) 2/4/94 * $FreeBSD: src/sys/sys/vnode.h,v 1.111.2.19 2002/12/29 18:19:53 dillon Exp $ - * $DragonFly: src/sys/sys/vnode.h,v 1.39 2005/09/17 07:43:01 dillon Exp $ + * $DragonFly: src/sys/sys/vnode.h,v 1.40 2006/02/17 19:18:07 dillon Exp $ */ #ifndef _SYS_VNODE_H_ @@ -41,6 +41,7 @@ #include #include #include +#include #include #include #include @@ -158,9 +159,11 @@ RB_HEAD(buf_rb_tree, buf); struct vnode { u_long v_flag; /* vnode flags (see below) */ int v_usecount; /* reference count of users */ - int v_writecount; /* reference count of writers */ + int v_writecount; int v_holdcnt; /* page & buffer references */ int v_opencount; /* number of explicit opens */ + struct bio_track v_track_read; /* track I/O's in progress */ + struct bio_track v_track_write; /* track I/O's in progress */ u_long v_id; /* capability identifier */ struct mount *v_mount; /* ptr to vfs we are in */ struct vop_ops **v_ops; /* vnode operations vector */ @@ -169,7 +172,6 @@ struct vnode { struct buf_rb_tree v_rbclean_tree; /* RB tree of clean bufs */ struct buf_rb_tree v_rbdirty_tree; /* RB tree of dirty bufs */ LIST_ENTRY(vnode) v_synclist; /* vnodes with dirty buffers */ - long v_numoutput; /* num of writes in progress */ enum vtype v_type; /* vnode type */ union { struct mount *vu_mountedhere;/* ptr to mounted vfs (VDIR) */ @@ -232,7 +234,7 @@ struct vnode { /* open for business 0x00080 */ /* open for business 0x00100 */ /* open for business 0x00200 */ -#define VBWAIT 0x00400 /* waiting for output to complete */ +/* open for business 0x00400 */ /* open for business 0x00800 */ /* open for business 0x01000 */ #define VOBJBUF 0x02000 /* Allocate buffers in VM object */ @@ -622,6 +624,7 @@ int vfsync(struct vnode *vp, int waitfor, int passes, daddr_t lbn, int (*waitoutput)(struct vnode *, struct thread *)); void vprint (char *label, struct vnode *vp); int vrecycle (struct vnode *vp, struct thread *td); +void vn_strategy(struct vnode *vp, struct bio *bio); int vn_close (struct vnode *vp, int flags, struct thread *td); int vn_isdisk (struct vnode *vp, int *errp); int vn_lock (struct vnode *vp, int flags, struct thread *td); diff --git a/sys/vfs/coda/coda_vnops.c b/sys/vfs/coda/coda_vnops.c index 68a74b4c40..0707492ceb 100644 --- a/sys/vfs/coda/coda_vnops.c +++ b/sys/vfs/coda/coda_vnops.c @@ -28,7 +28,7 @@ * * @(#) src/sys/coda/coda_vnops.c,v 1.1.1.1 1998/08/29 21:14:52 rvb Exp $ * $FreeBSD: src/sys/coda/coda_vnops.c,v 1.22.2.1 2001/06/29 16:26:22 shafeeq Exp $ - * $DragonFly: src/sys/vfs/coda/Attic/coda_vnops.c,v 1.28 2006/01/13 21:09:27 swildner Exp $ + * $DragonFly: src/sys/vfs/coda/Attic/coda_vnops.c,v 1.29 2006/02/17 19:18:07 dillon Exp $ * */ @@ -1652,14 +1652,8 @@ coda_bmap(void *v) * int async_daemon_count; */ int -coda_strategy(void *v) +coda_strategy(struct vop_strategy_args *ap __unused) { -/* true args */ - struct vop_strategy_args *ap = v; - struct buf *bp __attribute__((unused)) = ap->a_bp; -/* upcall decl */ -/* locals */ - printf("coda_strategy: called ???\n"); return(EOPNOTSUPP); } diff --git a/sys/vfs/coda/coda_vnops.h b/sys/vfs/coda/coda_vnops.h index 6ed3defef1..5b293cb1d6 100644 --- a/sys/vfs/coda/coda_vnops.h +++ b/sys/vfs/coda/coda_vnops.h @@ -28,7 +28,7 @@ * * @(#) src/sys/coda/coda_vnops.h,v 1.1.1.1 1998/08/29 21:14:52 rvb Exp $ * $FreeBSD: src/sys/coda/coda_vnops.h,v 1.6 1999/08/28 00:40:58 peter Exp $ - * $DragonFly: src/sys/vfs/coda/Attic/coda_vnops.h,v 1.7 2004/08/17 18:57:32 dillon Exp $ + * $DragonFly: src/sys/vfs/coda/Attic/coda_vnops.h,v 1.8 2006/02/17 19:18:07 dillon Exp $ * */ @@ -71,7 +71,7 @@ int coda_rmdir (void *); int coda_symlink (void *); int coda_readdir (void *); int coda_bmap (void *); -int coda_strategy (void *); +int coda_strategy (struct vop_strategy_args *); int coda_reclaim (void *); int coda_lock (void *); int coda_unlock (void *); diff --git a/sys/vfs/gnu/ext2fs/ext2_alloc.c b/sys/vfs/gnu/ext2fs/ext2_alloc.c index da981bf444..4a7b369c41 100644 --- a/sys/vfs/gnu/ext2fs/ext2_alloc.c +++ b/sys/vfs/gnu/ext2fs/ext2_alloc.c @@ -38,7 +38,7 @@ * * @(#)ext2_alloc.c 8.8 (Berkeley) 2/21/94 * $FreeBSD: src/sys/gnu/ext2fs/ext2_alloc.c,v 1.28.2.2 2002/07/01 00:18:51 iedowse Exp $ - * $DragonFly: src/sys/vfs/gnu/ext2fs/ext2_alloc.c,v 1.8 2006/01/13 21:09:27 swildner Exp $ + * $DragonFly: src/sys/vfs/gnu/ext2fs/ext2_alloc.c,v 1.9 2006/02/17 19:18:07 dillon Exp $ */ #include "opt_quota.h" @@ -253,8 +253,8 @@ return ENOSPC; * the filesystem has decided to move and do not force it back to * the previous cylinder group. */ - if (dtog(fs, dbtofsb(fs, buflist->bs_children[0]->b_blkno)) != - dtog(fs, dbtofsb(fs, buflist->bs_children[len - 1]->b_blkno))) + if (dtog(fs, dbtofsb(fs, buflist->bs_children[0]->b_bio2.bio_blkno)) != + dtog(fs, dbtofsb(fs, buflist->bs_children[len - 1]->b_bio2.bio_blkno))) return (ENOSPC); if (ufs_getlbns(vp, start_lbn, start_ap, &start_lvl) || ufs_getlbns(vp, end_lbn, end_ap, &end_lvl)) @@ -311,7 +311,7 @@ return ENOSPC; if (i == ssize) bap = ebap; #if DIAGNOSTIC - if (buflist->bs_children[i]->b_blkno != fsbtodb(fs, *bap)) + if (buflist->bs_children[i]->b_bio2.bio_blkno != fsbtodb(fs, *bap)) panic("ext2_reallocblks: alloc mismatch"); #endif *bap++ = blkno; @@ -349,9 +349,9 @@ return ENOSPC; * Last, free the old blocks and assign the new blocks to the buffers. */ for (blkno = newblk, i = 0; i < len; i++, blkno += fs->s_frags_per_block) { - ext2_blkfree(ip, dbtofsb(fs, buflist->bs_children[i]->b_blkno), + ext2_blkfree(ip, dbtofsb(fs, buflist->bs_children[i]->b_bio2.bio_blkno), fs->s_blocksize); - buflist->bs_children[i]->b_blkno = fsbtodb(fs, blkno); + buflist->bs_children[i]->b_bio2.bio_blkno = fsbtodb(fs, blkno); } return (0); diff --git a/sys/vfs/gnu/ext2fs/ext2_balloc.c b/sys/vfs/gnu/ext2fs/ext2_balloc.c index 7e32174434..dad2245b78 100644 --- a/sys/vfs/gnu/ext2fs/ext2_balloc.c +++ b/sys/vfs/gnu/ext2fs/ext2_balloc.c @@ -38,7 +38,7 @@ * * @(#)ffs_balloc.c 8.4 (Berkeley) 9/23/93 * $FreeBSD: src/sys/gnu/ext2fs/ext2_balloc.c,v 1.9.2.1 2000/08/03 00:52:57 peter Exp $ - * $DragonFly: src/sys/vfs/gnu/ext2fs/ext2_balloc.c,v 1.6 2004/04/08 20:57:52 cpressey Exp $ + * $DragonFly: src/sys/vfs/gnu/ext2fs/ext2_balloc.c,v 1.7 2006/02/17 19:18:07 dillon Exp $ */ #include @@ -144,11 +144,11 @@ ext2_debug("ext2_balloc called (%d, %d, %d)\n", if (error) return (error); bp = getblk(vp, bn, nsize, 0, 0); - bp->b_blkno = fsbtodb(fs, newb); + bp->b_bio2.bio_blkno = fsbtodb(fs, newb); if (flags & B_CLRBUF) vfs_bio_clrbuf(bp); } - ip->i_db[bn] = dbtofsb(fs, bp->b_blkno); + ip->i_db[bn] = dbtofsb(fs, bp->b_bio2.bio_blkno); ip->i_flag |= IN_CHANGE | IN_UPDATE; *bpp = bp; return (0); @@ -191,7 +191,7 @@ ext2_debug("ext2_balloc called (%d, %d, %d)\n", return (error); nb = newb; bp = getblk(vp, indirs[1].in_lbn, fs->s_blocksize, 0, 0); - bp->b_blkno = fsbtodb(fs, newb); + bp->b_bio2.bio_blkno = fsbtodb(fs, newb); vfs_bio_clrbuf(bp); /* * Write synchronously so that indirect blocks @@ -243,7 +243,7 @@ ext2_debug("ext2_balloc called (%d, %d, %d)\n", } nb = newb; nbp = getblk(vp, indirs[i].in_lbn, fs->s_blocksize, 0, 0); - nbp->b_blkno = fsbtodb(fs, nb); + nbp->b_bio2.bio_blkno = fsbtodb(fs, nb); vfs_bio_clrbuf(nbp); /* * Write synchronously so that indirect blocks @@ -278,7 +278,7 @@ ext2_debug("ext2_balloc called (%d, %d, %d)\n", } nb = newb; nbp = getblk(vp, lbn, fs->s_blocksize, 0, 0); - nbp->b_blkno = fsbtodb(fs, nb); + nbp->b_bio2.bio_blkno = fsbtodb(fs, nb); if (flags & B_CLRBUF) vfs_bio_clrbuf(nbp); bap[indirs[i].in_off] = nb; @@ -303,7 +303,7 @@ ext2_debug("ext2_balloc called (%d, %d, %d)\n", } } else { nbp = getblk(vp, lbn, fs->s_blocksize, 0, 0); - nbp->b_blkno = fsbtodb(fs, nb); + nbp->b_bio2.bio_blkno = fsbtodb(fs, nb); } *bpp = nbp; return (0); diff --git a/sys/vfs/gnu/ext2fs/ext2_inode.c b/sys/vfs/gnu/ext2fs/ext2_inode.c index e4d82b7309..48d58f327f 100644 --- a/sys/vfs/gnu/ext2fs/ext2_inode.c +++ b/sys/vfs/gnu/ext2fs/ext2_inode.c @@ -38,7 +38,7 @@ * * @(#)ext2_inode.c 8.5 (Berkeley) 12/30/93 * $FreeBSD: src/sys/gnu/ext2fs/ext2_inode.c,v 1.24.2.1 2000/08/03 00:52:57 peter Exp $ - * $DragonFly: src/sys/vfs/gnu/ext2fs/ext2_inode.c,v 1.10 2006/01/13 21:09:27 swildner Exp $ + * $DragonFly: src/sys/vfs/gnu/ext2fs/ext2_inode.c,v 1.11 2006/02/17 19:18:07 dillon Exp $ */ #include "opt_quota.h" @@ -395,7 +395,7 @@ ext2_indirtrunc(struct inode *ip, daddr_t lbn, daddr_t dbn, daddr_t lastbn, * to blocks to be free'd, and update on disk copy first. Since * double(triple) indirect before single(double) indirect, calls * to bmap on these blocks will fail. However, we already have - * the on disk address, so we have to set the b_blkno field + * the on disk address, so we have to set the bio_blkno field * explicitly instead of letting bread do everything for us. */ vp = ITOV(ip); @@ -405,9 +405,9 @@ ext2_indirtrunc(struct inode *ip, daddr_t lbn, daddr_t dbn, daddr_t lastbn, bp->b_flags |= B_READ; if (bp->b_bcount > bp->b_bufsize) panic("ext2_indirtrunc: bad buffer size"); - bp->b_blkno = dbn; + bp->b_bio2.bio_blkno = dbn; vfs_busy_pages(bp, 0); - VOP_STRATEGY(vp, bp); + vn_strategy(vp, &bp->b_bio1); error = biowait(bp); } if (error) { diff --git a/sys/vfs/gnu/ext2fs/ext2_subr.c b/sys/vfs/gnu/ext2fs/ext2_subr.c index 8d2658824e..fee027a826 100644 --- a/sys/vfs/gnu/ext2fs/ext2_subr.c +++ b/sys/vfs/gnu/ext2fs/ext2_subr.c @@ -38,7 +38,7 @@ * * @(#)ext2_subr.c 8.2 (Berkeley) 9/21/93 * $FreeBSD: src/sys/gnu/ext2fs/ext2_subr.c,v 1.13.2.2 2000/08/03 18:48:27 peter Exp $ - * $DragonFly: src/sys/vfs/gnu/ext2fs/ext2_subr.c,v 1.8 2006/01/13 21:09:27 swildner Exp $ + * $DragonFly: src/sys/vfs/gnu/ext2fs/ext2_subr.c,v 1.9 2006/02/17 19:18:07 dillon Exp $ */ #include @@ -99,24 +99,24 @@ ext2_checkoverlap(struct buf *bp, struct inode *ip) struct vnode *vp; ebp = &buf[nbuf]; - start = bp->b_blkno; + start = bp->b_bio2.bio_blkno; last = start + btodb(bp->b_bcount) - 1; for (ep = buf; ep < ebp; ep++) { if (ep == bp || (ep->b_flags & B_INVAL) || - ep->b_vp == NULLVP) + ep->b_vp == NULLVP || ep->b_bio2.bio_blkno == (daddr_t)-1) continue; - if (VOP_BMAP(ep->b_vp, (daddr_t)0, &vp, (daddr_t)0, NULL, NULL)) + if (VOP_BMAP(ep->b_vp, (daddr_t)0, &vp, NULL, NULL, NULL)) continue; if (vp != ip->i_devvp) continue; /* look for overlap */ - if (ep->b_bcount == 0 || ep->b_blkno > last || - ep->b_blkno + btodb(ep->b_bcount) <= start) + if (ep->b_bcount == 0 || ep->b_bio2.bio_blkno > last || + ep->b_bio2.bio_blkno + btodb(ep->b_bcount) <= start) continue; vprint("Disk overlap", vp); printf("\tstart %d, end %d overlap start %d, end %d\n", - start, last, ep->b_blkno, - ep->b_blkno + btodb(ep->b_bcount) - 1); + start, last, ep->b_bio2.bio_blkno, + ep->b_bio2.bio_blkno + btodb(ep->b_bcount) - 1); panic("Disk buffer overlap"); } } diff --git a/sys/vfs/gnu/ext2fs/ext2_vnops.c b/sys/vfs/gnu/ext2fs/ext2_vnops.c index 400627eb0a..0575f8a3ed 100644 --- a/sys/vfs/gnu/ext2fs/ext2_vnops.c +++ b/sys/vfs/gnu/ext2fs/ext2_vnops.c @@ -44,7 +44,7 @@ * @(#)ufs_vnops.c 8.27 (Berkeley) 5/27/95 * @(#)ext2_vnops.c 8.7 (Berkeley) 2/3/94 * $FreeBSD: src/sys/gnu/ext2fs/ext2_vnops.c,v 1.51.2.2 2003/01/02 17:26:18 bde Exp $ - * $DragonFly: src/sys/vfs/gnu/ext2fs/ext2_vnops.c,v 1.24 2006/01/13 21:09:27 swildner Exp $ + * $DragonFly: src/sys/vfs/gnu/ext2fs/ext2_vnops.c,v 1.25 2006/02/17 19:18:07 dillon Exp $ */ #include "opt_quota.h" @@ -211,9 +211,9 @@ loop: goto loop; if (ap->a_waitfor == MNT_WAIT) { - while (vp->v_numoutput) { - vp->v_flag |= VBWAIT; - tsleep(&vp->v_numoutput, 0, "e2fsyn", 0); + while (vp->v_track_write.bk_active) { + vp->v_track_write.bk_waitflag = 1; + tsleep(&vp->v_track_write, 0, "e2fsyn", 0); } #if DIAGNOSTIC if (!RB_EMPTY(&vp->v_rbdirty_tree)) { diff --git a/sys/vfs/hpfs/hpfs_vnops.c b/sys/vfs/hpfs/hpfs_vnops.c index fb9bc9eb45..4b26ea2a5b 100644 --- a/sys/vfs/hpfs/hpfs_vnops.c +++ b/sys/vfs/hpfs/hpfs_vnops.c @@ -24,7 +24,7 @@ * SUCH DAMAGE. * * $FreeBSD: src/sys/fs/hpfs/hpfs_vnops.c,v 1.2.2.2 2002/01/15 18:35:09 semenu Exp $ - * $DragonFly: src/sys/vfs/hpfs/hpfs_vnops.c,v 1.28 2006/01/22 04:44:18 swildner Exp $ + * $DragonFly: src/sys/vfs/hpfs/hpfs_vnops.c,v 1.29 2006/02/17 19:18:07 dillon Exp $ */ #include @@ -672,38 +672,45 @@ hpfs_print(struct vop_print_args *ap) * In order to be able to swap to a file, the VOP_BMAP operation may not * deadlock on memory. See hpfs_bmap() for details. XXXXXXX (not impl) * - * hpfs_strategy(struct buf *a_bp) + * hpfs_strategy(struct vnode *a_vp, struct bio *a_bio) */ int hpfs_strategy(struct vop_strategy_args *ap) { - struct buf *bp = ap->a_bp; + struct bio *bio = ap->a_bio; + struct bio *nbio; + struct buf *bp = bio->bio_buf; struct vnode *vp = ap->a_vp; - struct vnode *nvp; + struct hpfsnode *hp; int error; dprintf(("hpfs_strategy(): \n")); if (vp->v_type == VBLK || vp->v_type == VCHR) panic("hpfs_strategy: spec"); - if (bp->b_blkno == bp->b_lblkno) { - error = VOP_BMAP(vp, bp->b_lblkno, &nvp, &bp->b_blkno, NULL, NULL); + + nbio = push_bio(bio); + if (nbio->bio_blkno == (daddr_t)-1) { + error = VOP_BMAP(vp, bio->bio_blkno, NULL, &nbio->bio_blkno, + NULL, NULL); if (error) { printf("hpfs_strategy: VOP_BMAP FAILED %d\n", error); bp->b_error = error; bp->b_flags |= B_ERROR; - biodone(bp); + /* I/O was never started on nbio, must biodone(bio) */ + biodone(bio); return (error); } - if ((long)bp->b_blkno == -1) + if (nbio->bio_blkno == (daddr_t)-1) vfs_bio_clrbuf(bp); } - if ((long)bp->b_blkno == -1) { - biodone(bp); + if (nbio->bio_blkno == (daddr_t)-1) { + /* I/O was never started on nbio, must biodone(bio) */ + biodone(bio); return (0); } - bp->b_dev = nvp->v_rdev; - VOP_STRATEGY(nvp, bp); + hp = VTOHP(ap->a_vp); + vn_strategy(hp->h_devvp, nbio); return (0); } diff --git a/sys/vfs/isofs/cd9660/cd9660_lookup.c b/sys/vfs/isofs/cd9660/cd9660_lookup.c index 3096f13770..b3625e0c53 100644 --- a/sys/vfs/isofs/cd9660/cd9660_lookup.c +++ b/sys/vfs/isofs/cd9660/cd9660_lookup.c @@ -39,7 +39,7 @@ * * @(#)cd9660_lookup.c 8.2 (Berkeley) 1/23/94 * $FreeBSD: src/sys/isofs/cd9660/cd9660_lookup.c,v 1.23.2.2 2001/11/04 06:19:47 dillon Exp $ - * $DragonFly: src/sys/vfs/isofs/cd9660/cd9660_lookup.c,v 1.16 2005/09/14 01:13:37 dillon Exp $ + * $DragonFly: src/sys/vfs/isofs/cd9660/cd9660_lookup.c,v 1.17 2006/02/17 19:18:07 dillon Exp $ */ #include @@ -243,7 +243,7 @@ searchloop: if (isoflags & 2) ino = isodirino(ep, imp); else - ino = dbtob(bp->b_blkno) + ino = dbtob(bp->b_bio2.bio_blkno) + entryoffsetinblock; saveoffset = dp->i_offset; } else if (ino) @@ -260,7 +260,7 @@ searchloop: if (isonum_711(ep->flags)&2) ino = isodirino(ep, imp); else - ino = dbtob(bp->b_blkno) + entryoffsetinblock; + ino = dbtob(bp->b_bio2.bio_blkno) + entryoffsetinblock; dp->i_ino = ino; cd9660_rrip_getname(ep,altname,&namelen,&dp->i_ino,imp); if (namelen == cnp->cn_namelen @@ -408,17 +408,17 @@ cd9660_blkatoff(struct vnode *vp, off_t offset, char **res, struct buf **bpp) } /* - * We must BMAP the buffer because the directory code may use b_blkno + * We must BMAP the buffer because the directory code may use bio_blkno * to calculate the inode for certain types of directory entries. * We could get away with not doing it before we VMIO-backed the * directories because the buffers would get freed atomically with * the invalidation of their data. But with VMIO-backed buffers * the buffers may be freed and then later reconstituted - and the - * reconstituted buffer will have no knowledge of b_blkno. + * reconstituted buffer will have no knowledge of bio_blkno. */ - if (bp->b_blkno == bp->b_lblkno) { - error = VOP_BMAP(vp, bp->b_lblkno, NULL, - &bp->b_blkno, NULL, NULL); + if (bp->b_bio2.bio_blkno == (daddr_t)-1) { + error = VOP_BMAP(vp, bp->b_bio1.bio_blkno, NULL, + &bp->b_bio2.bio_blkno, NULL, NULL); if (error) { bp->b_error = error; bp->b_flags |= B_ERROR; @@ -433,3 +433,4 @@ cd9660_blkatoff(struct vnode *vp, off_t offset, char **res, struct buf **bpp) *bpp = bp; return (0); } + diff --git a/sys/vfs/isofs/cd9660/cd9660_vnops.c b/sys/vfs/isofs/cd9660/cd9660_vnops.c index 89ebf76794..d62ba6cea0 100644 --- a/sys/vfs/isofs/cd9660/cd9660_vnops.c +++ b/sys/vfs/isofs/cd9660/cd9660_vnops.c @@ -37,7 +37,7 @@ * * @(#)cd9660_vnops.c 8.19 (Berkeley) 5/27/95 * $FreeBSD: src/sys/isofs/cd9660/cd9660_vnops.c,v 1.62 1999/12/15 23:01:51 eivind Exp $ - * $DragonFly: src/sys/vfs/isofs/cd9660/cd9660_vnops.c,v 1.18 2006/01/13 21:09:27 swildner Exp $ + * $DragonFly: src/sys/vfs/isofs/cd9660/cd9660_vnops.c,v 1.19 2006/02/17 19:18:07 dillon Exp $ */ #include @@ -549,7 +549,7 @@ cd9660_readdir(struct vop_readdir_args *ap) if (isonum_711(ep->flags)&2) idp->current.de.d_ino = isodirino(ep, imp); else - idp->current.de.d_ino = dbtob(bp->b_blkno) + + idp->current.de.d_ino = dbtob(bp->b_bio2.bio_blkno) + entryoffsetinblock; idp->curroff += reclen; @@ -722,37 +722,42 @@ cd9660_readlink(struct vop_readlink_args *ap) * Calculate the logical to physical mapping if not done already, * then call the device strategy routine. * - * cd9660_strategy(struct buf *a_vp, struct buf *a_bp) + * cd9660_strategy(struct buf *a_vp, struct buf *a_bio) */ static int cd9660_strategy(struct vop_strategy_args *ap) { - struct buf *bp = ap->a_bp; - struct vnode *vp = bp->b_vp; + struct bio *bio = ap->a_bio; + struct bio *nbio; + struct buf *bp = bio->bio_buf; + struct vnode *vp = ap->a_vp; struct iso_node *ip; int error; ip = VTOI(vp); if (vp->v_type == VBLK || vp->v_type == VCHR) panic("cd9660_strategy: spec"); - if (bp->b_blkno == bp->b_lblkno) { - if ((error = - VOP_BMAP(vp, bp->b_lblkno, NULL, &bp->b_blkno, NULL, NULL))) { + nbio = push_bio(bio); + if (nbio->bio_blkno == (daddr_t)-1) { + error = VOP_BMAP(vp, bio->bio_blkno, NULL, &nbio->bio_blkno, + NULL, NULL); + if (error) { bp->b_error = error; bp->b_flags |= B_ERROR; - biodone(bp); + /* I/O was never started on nbio, must biodone(bio) */ + biodone(bio); return (error); } - if ((long)bp->b_blkno == -1) + if (nbio->bio_blkno == (daddr_t)-1) clrbuf(bp); } - if ((long)bp->b_blkno == -1) { - biodone(bp); + if (nbio->bio_blkno == (daddr_t)-1) { + /* I/O was never started on nbio, must biodone(bio) */ + biodone(bio); return (0); } vp = ip->i_devvp; - bp->b_dev = vp->v_rdev; - VOP_STRATEGY(vp, bp); + vn_strategy(vp, nbio); return (0); } diff --git a/sys/vfs/mfs/mfs_extern.h b/sys/vfs/mfs/mfs_extern.h index aa9c5879fa..a8b07c8de8 100644 --- a/sys/vfs/mfs/mfs_extern.h +++ b/sys/vfs/mfs/mfs_extern.h @@ -32,7 +32,7 @@ * * @(#)mfs_extern.h 8.4 (Berkeley) 3/30/95 * $FreeBSD: src/sys/ufs/mfs/mfs_extern.h,v 1.15 1999/08/28 00:52:24 peter Exp $ - * $DragonFly: src/sys/vfs/mfs/mfs_extern.h,v 1.4 2003/08/20 09:56:32 rob Exp $ + * $DragonFly: src/sys/vfs/mfs/mfs_extern.h,v 1.5 2006/02/17 19:18:07 dillon Exp $ */ #ifndef _UFS_MFS_MFS_EXTERN_H_ @@ -44,7 +44,7 @@ struct mount; struct thread; struct vnode; -void mfs_doio (struct buf *bp, struct mfsnode *mfsnode); +void mfs_doio (struct bio *bio, struct mfsnode *mfsnode); u_char *mfs_getimage (void); int mfs_mountfs (struct vnode *, struct mount *, struct thread *); int mfs_mountroot (void); diff --git a/sys/vfs/mfs/mfs_vfsops.c b/sys/vfs/mfs/mfs_vfsops.c index 6010f31522..3ddf80d84b 100644 --- a/sys/vfs/mfs/mfs_vfsops.c +++ b/sys/vfs/mfs/mfs_vfsops.c @@ -32,7 +32,7 @@ * * @(#)mfs_vfsops.c 8.11 (Berkeley) 6/19/95 * $FreeBSD: src/sys/ufs/mfs/mfs_vfsops.c,v 1.81.2.3 2001/07/04 17:35:21 tegge Exp $ - * $DragonFly: src/sys/vfs/mfs/mfs_vfsops.c,v 1.24 2006/01/13 21:09:27 swildner Exp $ + * $DragonFly: src/sys/vfs/mfs/mfs_vfsops.c,v 1.25 2006/02/17 19:18:07 dillon Exp $ */ @@ -142,32 +142,33 @@ mfsclose(dev_t dev, int flags, int mode, struct thread *td) } void -mfsstrategy(struct buf *bp) +mfsstrategy(dev_t dev, struct bio *bio) { + struct buf *bp = bio->bio_buf; struct mfsnode *mfsp; - if ((mfsp = bp->b_dev->si_drv1) != NULL) { - off_t boff = (off_t)bp->b_blkno << DEV_BSHIFT; + if ((mfsp = dev->si_drv1) != NULL) { + off_t boff = (off_t)bio->bio_blkno << DEV_BSHIFT; off_t eoff = boff + bp->b_bcount; if (eoff <= mfsp->mfs_size) { - bufq_insert_tail(&mfsp->buf_queue, bp); + bioq_insert_tail(&mfsp->bio_queue, bio); wakeup((caddr_t)mfsp); } else if (boff < mfsp->mfs_size) { bp->b_bcount = mfsp->mfs_size - boff; - bufq_insert_tail(&mfsp->buf_queue, bp); + bioq_insert_tail(&mfsp->bio_queue, bio); wakeup((caddr_t)mfsp); } else if (boff == mfsp->mfs_size) { bp->b_resid = bp->b_bcount; - biodone(bp); + biodone(bio); } else { bp->b_error = EINVAL; - biodone(bp); + biodone(bio); } } else { bp->b_error = ENXIO; bp->b_flags |= B_ERROR; - biodone(bp); + biodone(bio); } } @@ -312,7 +313,7 @@ mfs_mount(struct mount *mp, char *path, caddr_t data, struct thread *td) mfsp->mfs_dev = reference_dev(dev); mfsp->mfs_td = td; mfsp->mfs_active = 1; - bufq_init(&mfsp->buf_queue); + bioq_init(&mfsp->bio_queue); /* Save "mounted from" info for mount point (NULL pad)*/ copyinstr( args.fspec, /* device name*/ @@ -362,7 +363,7 @@ mfs_start(struct mount *mp, int flags, struct thread *td) { struct vnode *vp = VFSTOUFS(mp)->um_devvp; struct mfsnode *mfsp = VTOMFS(vp); - struct buf *bp; + struct bio *bio; int gotsig = 0, sig; /* @@ -376,14 +377,13 @@ mfs_start(struct mount *mp, int flags, struct thread *td) PHOLD(curproc); while (mfsp->mfs_active) { - crit_enter(); - while ((bp = bufq_first(&mfsp->buf_queue)) != NULL) { - bufq_remove(&mfsp->buf_queue, bp); + while ((bio = bioq_first(&mfsp->bio_queue)) != NULL) { + bioq_remove(&mfsp->bio_queue, bio); crit_exit(); - mfs_doio(bp, mfsp); - wakeup((caddr_t)bp); + mfs_doio(bio, mfsp); + wakeup((caddr_t)bio->bio_buf); crit_enter(); } diff --git a/sys/vfs/mfs/mfs_vnops.c b/sys/vfs/mfs/mfs_vnops.c index 9d32981ff4..af66bfa0c3 100644 --- a/sys/vfs/mfs/mfs_vnops.c +++ b/sys/vfs/mfs/mfs_vnops.c @@ -32,7 +32,7 @@ * * @(#)mfs_vnops.c 8.11 (Berkeley) 5/22/95 * $FreeBSD: src/sys/ufs/mfs/mfs_vnops.c,v 1.47.2.1 2001/05/22 02:06:43 bp Exp $ - * $DragonFly: src/sys/vfs/mfs/mfs_vnops.c,v 1.19 2005/09/17 07:43:09 dillon Exp $ + * $DragonFly: src/sys/vfs/mfs/mfs_vnops.c,v 1.20 2006/02/17 19:18:07 dillon Exp $ */ #include @@ -148,33 +148,32 @@ mfs_freeblks(struct vop_freeblks_args *ap) bp = geteblk(ap->a_length); bp->b_flags |= B_FREEBUF | B_ASYNC; - bp->b_dev = vp->v_rdev; - bp->b_blkno = ap->a_addr; - bp->b_offset = dbtob(ap->a_addr); + bp->b_bio1.bio_blkno = ap->a_addr; + bp->b_bio1.bio_offset = dbtob(ap->a_addr); bp->b_bcount = ap->a_length; BUF_KERNPROC(bp); - VOP_STRATEGY(vp, bp); + vn_strategy(vp, &bp->b_bio1); return(0); } /* * Pass I/O requests to the memory filesystem process. * - * mfs_strategy(struct vnode *a_vp, struct buf *a_bp) + * mfs_strategy(struct vnode *a_vp, struct bio *a_bio) */ static int mfs_strategy(struct vop_strategy_args *ap) { - struct buf *bp = ap->a_bp; + struct bio *bio = ap->a_bio; + struct buf *bp = bio->bio_buf; struct mfsnode *mfsp; struct thread *td = curthread; /* XXX */ - bp->b_dev = ap->a_vp->v_rdev; - mfsp = bp->b_dev->si_drv1; + mfsp = ap->a_vp->v_rdev->si_drv1; if (mfsp == NULL) { bp->b_error = ENXIO; bp->b_flags |= B_ERROR; - biodone(bp); + biodone(bio); return(0); } @@ -192,27 +191,27 @@ mfs_strategy(struct vop_strategy_args *ap) */ caddr_t base; - base = mfsp->mfs_baseoff + (bp->b_blkno << DEV_BSHIFT); + base = mfsp->mfs_baseoff + (bio->bio_blkno << DEV_BSHIFT); if (bp->b_flags & B_FREEBUF) ; if (bp->b_flags & B_READ) bcopy(base, bp->b_data, bp->b_bcount); else bcopy(bp->b_data, base, bp->b_bcount); - biodone(bp); + biodone(bio); } else if (mfsp->mfs_td == td) { /* * VOP to self */ crit_exit(); - mfs_doio(bp, mfsp); + mfs_doio(bio, mfsp); crit_enter(); } else { /* * VOP from some other process, queue to MFS process and * wake it up. */ - bufq_insert_tail(&mfsp->buf_queue, bp); + bioq_insert_tail(&mfsp->bio_queue, bio); wakeup((caddr_t)mfsp); } crit_exit(); @@ -231,9 +230,10 @@ mfs_strategy(struct vop_strategy_args *ap) * implement it for page-aligned requests. */ void -mfs_doio(struct buf *bp, struct mfsnode *mfsp) +mfs_doio(struct bio *bio, struct mfsnode *mfsp) { - caddr_t base = mfsp->mfs_baseoff + (bp->b_blkno << DEV_BSHIFT); + struct buf *bp = bio->bio_buf; + caddr_t base = mfsp->mfs_baseoff + (bio->bio_blkno << DEV_BSHIFT); if (bp->b_flags & B_FREEBUF) { /* @@ -276,7 +276,7 @@ mfs_doio(struct buf *bp, struct mfsnode *mfsp) } if (bp->b_error) bp->b_flags |= B_ERROR; - biodone(bp); + biodone(bio); } /* @@ -309,16 +309,16 @@ mfs_close(struct vop_close_args *ap) { struct vnode *vp = ap->a_vp; struct mfsnode *mfsp = VTOMFS(vp); - struct buf *bp; + struct bio *bio; int error; /* * Finish any pending I/O requests. */ - while ((bp = bufq_first(&mfsp->buf_queue)) != NULL) { - bufq_remove(&mfsp->buf_queue, bp); - mfs_doio(bp, mfsp); - wakeup((caddr_t)bp); + while ((bio = bioq_first(&mfsp->bio_queue)) != NULL) { + bioq_remove(&mfsp->bio_queue, bio); + mfs_doio(bio, mfsp); + wakeup((caddr_t)bio->bio_buf); } /* * On last close of a memory filesystem @@ -333,7 +333,7 @@ mfs_close(struct vop_close_args *ap) */ if (vp->v_usecount > 1) printf("mfs_close: ref count %d > 1\n", vp->v_usecount); - if (vp->v_usecount > 1 || (bufq_first(&mfsp->buf_queue) != NULL)) + if (vp->v_usecount > 1 || (bioq_first(&mfsp->bio_queue) != NULL)) panic("mfs_close"); /* * Send a request to the filesystem server to exit. @@ -360,9 +360,9 @@ mfs_inactive(struct vop_inactive_args *ap) struct vnode *vp = ap->a_vp; struct mfsnode *mfsp = VTOMFS(vp); - if (bufq_first(&mfsp->buf_queue) != NULL) + if (bioq_first(&mfsp->bio_queue) != NULL) panic("mfs_inactive: not inactive (next buffer %p)", - bufq_first(&mfsp->buf_queue)); + bioq_first(&mfsp->bio_queue)); return (0); } diff --git a/sys/vfs/mfs/mfsnode.h b/sys/vfs/mfs/mfsnode.h index 5318a35f41..f7557a2266 100644 --- a/sys/vfs/mfs/mfsnode.h +++ b/sys/vfs/mfs/mfsnode.h @@ -32,7 +32,7 @@ * * @(#)mfsnode.h 8.3 (Berkeley) 5/19/95 * $FreeBSD: src/sys/ufs/mfs/mfsnode.h,v 1.12.2.2 2001/07/04 17:35:21 tegge Exp $ - * $DragonFly: src/sys/vfs/mfs/mfsnode.h,v 1.4 2004/05/19 22:53:04 dillon Exp $ + * $DragonFly: src/sys/vfs/mfs/mfsnode.h,v 1.5 2006/02/17 19:18:07 dillon Exp $ */ #ifndef _UFS_MFS_MFSNODE_H_ @@ -47,7 +47,7 @@ struct mfsnode { caddr_t mfs_baseoff; /* base of file system in memory */ long mfs_size; /* size of memory file system */ struct thread *mfs_td; /* supporting thread */ - struct buf_queue_head buf_queue; /* list of I/O requests */ + struct bio_queue_head bio_queue; /* list of I/O requests */ dev_t mfs_dev; /* underlying device */ int mfs_active; long mfs_spare[1]; diff --git a/sys/vfs/msdosfs/msdosfs_fat.c b/sys/vfs/msdosfs/msdosfs_fat.c index 41f0220ebc..3920bd932a 100644 --- a/sys/vfs/msdosfs/msdosfs_fat.c +++ b/sys/vfs/msdosfs/msdosfs_fat.c @@ -1,5 +1,5 @@ /* $FreeBSD: src/sys/msdosfs/msdosfs_fat.c,v 1.23 2000/01/27 14:43:06 nyan Exp $ */ -/* $DragonFly: src/sys/vfs/msdosfs/msdosfs_fat.c,v 1.6 2004/04/17 00:30:17 cpressey Exp $ */ +/* $DragonFly: src/sys/vfs/msdosfs/msdosfs_fat.c,v 1.7 2006/02/17 19:18:07 dillon Exp $ */ /* $NetBSD: msdosfs_fat.c,v 1.28 1997/11/17 15:36:49 ws Exp $ */ /*- @@ -1032,10 +1032,11 @@ extendfile(struct denode *dep, u_long count, struct buf **bpp, u_long *ncp, * Do the bmap now, as in msdosfs_write */ if (pcbmap(dep, - de_bn2cn(pmp, bp->b_lblkno), - &bp->b_blkno, 0, 0)) - bp->b_blkno = -1; - if (bp->b_blkno == -1) + de_bn2cn(pmp, bp->b_bio1.bio_blkno), + &bp->b_bio2.bio_blkno, 0, 0)) { + bp->b_bio2.bio_blkno = (daddr_t)-1; + } + if (bp->b_bio2.bio_blkno == (daddr_t)-1) panic("extendfile: pcbmap"); } clrbuf(bp); diff --git a/sys/vfs/msdosfs/msdosfs_vfsops.c b/sys/vfs/msdosfs/msdosfs_vfsops.c index aa888954ef..a3c575c469 100644 --- a/sys/vfs/msdosfs/msdosfs_vfsops.c +++ b/sys/vfs/msdosfs/msdosfs_vfsops.c @@ -1,5 +1,5 @@ /* $FreeBSD: /usr/local/www/cvsroot/FreeBSD/src/sys/msdosfs/Attic/msdosfs_vfsops.c,v 1.60.2.8 2004/03/02 09:43:04 tjr Exp $ */ -/* $DragonFly: src/sys/vfs/msdosfs/msdosfs_vfsops.c,v 1.29 2006/01/13 21:09:27 swildner Exp $ */ +/* $DragonFly: src/sys/vfs/msdosfs/msdosfs_vfsops.c,v 1.30 2006/02/17 19:18:07 dillon Exp $ */ /* $NetBSD: msdosfs_vfsops.c,v 1.51 1997/11/17 15:36:58 ws Exp $ */ /*- @@ -711,7 +711,7 @@ msdosfs_unmount(struct mount *mp, int mntflags, struct thread *td) printf("cleanblkhd %p, dirtyblkhd %p, numoutput %ld, type %d\n", RB_EMPTY(&vp->v_rbclean_tree), RB_EMPTY(&vp->v_rbdirty_tree), - vp->v_numoutput, vp->v_type); + vp->v_track_write.bk_active, vp->v_type); printf("union %p, tag %d, data[0] %08x, data[1] %08x\n", vp->v_socket, vp->v_tag, ((u_int *)vp->v_data)[0], diff --git a/sys/vfs/msdosfs/msdosfs_vnops.c b/sys/vfs/msdosfs/msdosfs_vnops.c index ecd7bc3f17..522b136e8f 100644 --- a/sys/vfs/msdosfs/msdosfs_vnops.c +++ b/sys/vfs/msdosfs/msdosfs_vnops.c @@ -1,5 +1,5 @@ /* $FreeBSD: src/sys/msdosfs/msdosfs_vnops.c,v 1.95.2.4 2003/06/13 15:05:47 trhodes Exp $ */ -/* $DragonFly: src/sys/vfs/msdosfs/msdosfs_vnops.c,v 1.28 2006/01/13 21:09:27 swildner Exp $ */ +/* $DragonFly: src/sys/vfs/msdosfs/msdosfs_vnops.c,v 1.29 2006/02/17 19:18:07 dillon Exp $ */ /* $NetBSD: msdosfs_vnops.c,v 1.68 1998/02/10 14:10:04 mrg Exp $ */ /*- @@ -744,13 +744,14 @@ msdosfs_write(struct vop_write_args *ap) * Do the bmap now, since pcbmap needs buffers * for the fat table. (see msdosfs_strategy) */ - if (bp->b_blkno == bp->b_lblkno) { - error = pcbmap(dep, bp->b_lblkno, &bp->b_blkno, - 0, 0); + if (bp->b_bio2.bio_blkno == (daddr_t)-1) { + error = pcbmap(dep, bp->b_lblkno, + &bp->b_bio2.bio_blkno, + 0, 0); if (error) - bp->b_blkno = -1; + bp->b_bio2.bio_blkno = (daddr_t)-1; } - if (bp->b_blkno == -1) { + if (bp->b_bio2.bio_blkno == (daddr_t)-1) { brelse(bp); if (!error) error = EIO; /* XXX */ @@ -1799,17 +1800,19 @@ msdosfs_bmap(struct vop_bmap_args *ap) } /* - * msdosfs_strategy(struct vnode *a_vp, struct buf *a_bp) + * msdosfs_strategy(struct vnode *a_vp, struct bio *a_bio) */ static int msdosfs_strategy(struct vop_strategy_args *ap) { - struct buf *bp = ap->a_bp; - struct denode *dep = VTODE(bp->b_vp); - struct vnode *vp; + struct bio *bio = ap->a_bio; + struct bio *nbio; + struct buf *bp = bio->bio_buf; + struct vnode *vp = ap->a_vp; + struct denode *dep = VTODE(vp); int error = 0; - if (bp->b_vp->v_type == VBLK || bp->b_vp->v_type == VCHR) + if (vp->v_type == VBLK || vp->v_type == VCHR) panic("msdosfs_strategy: spec"); /* * If we don't already know the filesystem relative block number @@ -1817,28 +1820,29 @@ msdosfs_strategy(struct vop_strategy_args *ap) * number as -1 then we've got a hole in the file. DOS filesystems * don't allow files with holes, so we shouldn't ever see this. */ - if (bp->b_blkno == bp->b_lblkno) { - error = pcbmap(dep, bp->b_lblkno, &bp->b_blkno, 0, 0); + nbio = push_bio(bio); + if (nbio->bio_blkno == (daddr_t)-1) { + error = pcbmap(dep, bio->bio_blkno, &nbio->bio_blkno, 0, 0); if (error) { bp->b_error = error; bp->b_flags |= B_ERROR; - biodone(bp); + /* I/O was never started on nbio, must biodone(bio) */ + biodone(bio); return (error); } - if ((long)bp->b_blkno == -1) + if (nbio->bio_blkno == (daddr_t)-1) vfs_bio_clrbuf(bp); } - if (bp->b_blkno == -1) { - biodone(bp); + if (nbio->bio_blkno == (daddr_t)-1) { + /* I/O was never started on nbio, must biodone(bio) */ + biodone(bio); return (0); } /* * Read/write the block from/to the disk that contains the desired * file block. */ - vp = dep->de_devvp; - bp->b_dev = vp->v_rdev; - VOP_STRATEGY(vp, bp); + vn_strategy(dep->de_devvp, nbio); return (0); } diff --git a/sys/vfs/nfs/nfs.h b/sys/vfs/nfs/nfs.h index eb3c9eee59..8b8681c15b 100644 --- a/sys/vfs/nfs/nfs.h +++ b/sys/vfs/nfs/nfs.h @@ -35,7 +35,7 @@ * * @(#)nfs.h 8.4 (Berkeley) 5/1/95 * $FreeBSD: src/sys/nfs/nfs.h,v 1.53.2.5 2002/02/20 01:35:34 iedowse Exp $ - * $DragonFly: src/sys/vfs/nfs/nfs.h,v 1.10 2005/03/27 23:51:42 dillon Exp $ + * $DragonFly: src/sys/vfs/nfs/nfs.h,v 1.11 2006/02/17 19:18:07 dillon Exp $ */ #ifndef _NFS_NFS_H_ @@ -309,6 +309,7 @@ extern struct callout nfs_timer_handle; struct uio; struct buf; +struct bio; struct vattr; struct nlookupdata; @@ -608,8 +609,8 @@ int nfs_writerpc (struct vnode *, struct uio *, int *, int *); int nfs_commit (struct vnode *vp, u_quad_t offset, int cnt, struct thread *td); int nfs_readdirrpc (struct vnode *, struct uio *); -int nfs_asyncio (struct buf *, struct thread *); -int nfs_doio (struct buf *, struct thread *); +int nfs_asyncio (struct vnode *vp, struct bio *, struct thread *); +int nfs_doio (struct vnode *vp, struct bio *, struct thread *); int nfs_readlinkrpc (struct vnode *, struct uio *); int nfs_sigintr (struct nfsmount *, struct nfsreq *, struct thread *); int nfs_readdirplusrpc (struct vnode *, struct uio *); diff --git a/sys/vfs/nfs/nfs_bio.c b/sys/vfs/nfs/nfs_bio.c index a3437a25c4..7d4ebaaa31 100644 --- a/sys/vfs/nfs/nfs_bio.c +++ b/sys/vfs/nfs/nfs_bio.c @@ -35,7 +35,7 @@ * * @(#)nfs_bio.c 8.9 (Berkeley) 3/30/95 * $FreeBSD: /repoman/r/ncvs/src/sys/nfsclient/nfs_bio.c,v 1.130 2004/04/14 23:23:55 peadar Exp $ - * $DragonFly: src/sys/vfs/nfs/nfs_bio.c,v 1.25 2005/11/19 17:58:22 dillon Exp $ + * $DragonFly: src/sys/vfs/nfs/nfs_bio.c,v 1.26 2006/02/17 19:18:07 dillon Exp $ */ @@ -465,7 +465,7 @@ nfs_bioread(struct vnode *vp, struct uio *uio, int ioflag) if ((rabp->b_flags & (B_CACHE|B_DELWRI)) == 0) { rabp->b_flags |= (B_READ | B_ASYNC); vfs_busy_pages(rabp, 0); - if (nfs_asyncio(rabp, td)) { + if (nfs_asyncio(vp, &rabp->b_bio2, td)) { rabp->b_flags |= B_INVAL|B_ERROR; vfs_unbusy_pages(rabp); brelse(rabp); @@ -526,7 +526,7 @@ again: if ((bp->b_flags & B_CACHE) == 0) { bp->b_flags |= B_READ; vfs_busy_pages(bp, 0); - error = nfs_doio(bp, td); + error = nfs_doio(vp, &bp->b_bio2, td); if (error) { brelse(bp); return (error); @@ -548,12 +548,12 @@ again: case VLNK: nfsstats.biocache_readlinks++; bp = nfs_getcacheblk(vp, (daddr_t)0, NFS_MAXPATHLEN, td); - if (!bp) + if (bp == NULL) return (EINTR); if ((bp->b_flags & B_CACHE) == 0) { bp->b_flags |= B_READ; vfs_busy_pages(bp, 0); - error = nfs_doio(bp, td); + error = nfs_doio(vp, &bp->b_bio2, td); if (error) { bp->b_flags |= B_ERROR; brelse(bp); @@ -572,12 +572,12 @@ again: lbn = (uoff_t)uio->uio_offset / NFS_DIRBLKSIZ; on = uio->uio_offset & (NFS_DIRBLKSIZ - 1); bp = nfs_getcacheblk(vp, lbn, NFS_DIRBLKSIZ, td); - if (!bp) + if (bp == NULL) return (EINTR); if ((bp->b_flags & B_CACHE) == 0) { bp->b_flags |= B_READ; vfs_busy_pages(bp, 0); - error = nfs_doio(bp, td); + error = nfs_doio(vp, &bp->b_bio2, td); if (error) { brelse(bp); } @@ -605,7 +605,7 @@ again: if ((bp->b_flags & B_CACHE) == 0) { bp->b_flags |= B_READ; vfs_busy_pages(bp, 0); - error = nfs_doio(bp, td); + error = nfs_doio(vp, &bp->b_bio2, td); /* * no error + B_INVAL == directory EOF, * use the block. @@ -648,7 +648,7 @@ again: if ((rabp->b_flags & (B_CACHE|B_DELWRI)) == 0) { rabp->b_flags |= (B_READ | B_ASYNC); vfs_busy_pages(rabp, 0); - if (nfs_asyncio(rabp, td)) { + if (nfs_asyncio(vp, &rabp->b_bio2, td)) { rabp->b_flags |= B_INVAL|B_ERROR; vfs_unbusy_pages(rabp); brelse(rabp); @@ -732,7 +732,6 @@ again: int nfs_write(struct vop_write_args *ap) { - int biosize; struct uio *uio = ap->a_uio; struct thread *td = uio->uio_td; struct vnode *vp = ap->a_vp; @@ -742,9 +741,10 @@ nfs_write(struct vop_write_args *ap) struct vattr vattr; struct nfsmount *nmp = VFSTONFS(vp->v_mount); daddr_t lbn; - int bcount; int n, on, error = 0, iomode, must_commit; int haverslock = 0; + int bcount; + int biosize; #ifdef DIAGNOSTIC if (uio->uio_rw != UIO_WRITE) @@ -918,7 +918,7 @@ again: } } - if (!bp) { + if (bp == NULL) { error = EINTR; break; } @@ -950,7 +950,7 @@ again: if ((bp->b_flags & B_CACHE) == 0) { bp->b_flags |= B_READ; vfs_busy_pages(bp, 0); - error = nfs_doio(bp, td); + error = nfs_doio(vp, &bp->b_bio2, td); if (error) { brelse(bp); break; @@ -972,8 +972,8 @@ again: */ if (bp->b_dirtyend > bcount) { - printf("NFS append race @%lx:%d\n", - (long)bp->b_blkno * DEV_BSIZE, + printf("NFS append race @%llx:%d\n", + (off_t)bp->b_bio2.bio_blkno << DEV_BSHIFT, bp->b_dirtyend - bcount); bp->b_dirtyend = bcount; } @@ -1000,7 +1000,7 @@ again: if (bp->b_dirtyend > 0 && (on > bp->b_dirtyend || (on + n) < bp->b_dirtyoff)) { - if (VOP_BWRITE(bp->b_vp, bp) == EINTR) { + if (VOP_BWRITE(vp, bp) == EINTR) { error = EINTR; break; } @@ -1077,7 +1077,7 @@ again: if ((np->n_flag & NQNFSNONCACHE) || (ioflag & IO_SYNC)) { if (ioflag & IO_INVAL) bp->b_flags |= B_NOCACHE; - error = VOP_BWRITE(bp->b_vp, bp); + error = VOP_BWRITE(vp, bp); if (error) break; if (np->n_flag & NQNFSNONCACHE) { @@ -1088,7 +1088,7 @@ again: } else if ((n + on) == biosize && (nmp->nm_flag & NFSMNT_NQNFS) == 0) { bp->b_flags |= B_ASYNC; - (void)nfs_writebp(bp, 0, 0); + nfs_writebp(bp, 0, 0); } else { bdwrite(bp); } @@ -1127,20 +1127,25 @@ nfs_getcacheblk(struct vnode *vp, daddr_t bn, int size, struct thread *td) if (nmp->nm_flag & NFSMNT_INT) { bp = getblk(vp, bn, size, PCATCH, 0); - while (bp == (struct buf *)0) { + while (bp == NULL) { if (nfs_sigintr(nmp, (struct nfsreq *)0, td)) - return ((struct buf *)0); + return (NULL); bp = getblk(vp, bn, size, 0, 2 * hz); } } else { bp = getblk(vp, bn, size, 0, 0); } + /* + * bio2, the 'device' layer, is normalized to DEV_BSIZE'd blocks. + */ if (vp->v_type == VREG) { int biosize; biosize = mp->mnt_stat.f_iosize; - bp->b_blkno = bn * (biosize / DEV_BSIZE); + bp->b_bio2.bio_blkno = ((off_t)bn * biosize) >> DEV_BSHIFT; + } else { + bp->b_bio2.bio_blkno = ((off_t)bn * NFS_DIRBLKSIZ) >> DEV_BSHIFT; } return (bp); } @@ -1212,8 +1217,9 @@ nfs_vinvalbuf(struct vnode *vp, int flags, * is eventually dequeued by the async daemon, nfs_doio() *will*. */ int -nfs_asyncio(struct buf *bp, struct thread *td) +nfs_asyncio(struct vnode *vp, struct bio *bio, struct thread *td) { + struct buf *bp = bio->bio_buf; struct nfsmount *nmp; int i; int gotiod; @@ -1228,7 +1234,8 @@ nfs_asyncio(struct buf *bp, struct thread *td) if (nfs_numasync == 0) return (EIO); - nmp = VFSTONFS(bp->b_vp->v_mount); + KKASSERT(vp->v_tag == VT_NFS); + nmp = VFSTONFS(vp->v_mount); /* * Commits are usually short and sweet so lets save some cpu and @@ -1236,7 +1243,7 @@ nfs_asyncio(struct buf *bp, struct thread *td) * and writes). */ if ((bp->b_flags & (B_READ|B_NEEDCOMMIT)) == B_NEEDCOMMIT && - (nmp->nm_bufqiods > nfs_numasync / 2)) { + (nmp->nm_bioqiods > nfs_numasync / 2)) { return(EIO); } @@ -1259,7 +1266,7 @@ again: i, nmp)); nfs_iodwant[i] = NULL; nfs_iodmount[i] = nmp; - nmp->nm_bufqiods++; + nmp->nm_bioqiods++; wakeup((caddr_t)&nfs_iodwant[i]); gotiod = TRUE; break; @@ -1270,10 +1277,10 @@ again: * point. If so, it will process our request. */ if (!gotiod) { - if (nmp->nm_bufqiods > 0) { + if (nmp->nm_bioqiods > 0) { NFS_DPF(ASYNCIO, ("nfs_asyncio: %d iods are already processing mount %p\n", - nmp->nm_bufqiods, nmp)); + nmp->nm_bioqiods, nmp)); gotiod = TRUE; } } @@ -1287,11 +1294,11 @@ again: * Ensure that the queue never grows too large. We still want * to asynchronize so we block rather then return EIO. */ - while (nmp->nm_bufqlen >= 2*nfs_numasync) { + while (nmp->nm_bioqlen >= 2*nfs_numasync) { NFS_DPF(ASYNCIO, ("nfs_asyncio: waiting for mount %p queue to drain\n", nmp)); - nmp->nm_bufqwant = TRUE; - error = tsleep(&nmp->nm_bufq, slpflag, + nmp->nm_bioqwant = TRUE; + error = tsleep(&nmp->nm_bioq, slpflag, "nfsaio", slptimeo); if (error) { if (nfs_sigintr(nmp, NULL, td)) @@ -1305,15 +1312,22 @@ again: * We might have lost our iod while sleeping, * so check and loop if nescessary. */ - if (nmp->nm_bufqiods == 0) { + if (nmp->nm_bioqiods == 0) { NFS_DPF(ASYNCIO, ("nfs_asyncio: no iods after mount %p queue was drained, looping\n", nmp)); goto again; } } BUF_KERNPROC(bp); - TAILQ_INSERT_TAIL(&nmp->nm_bufq, bp, b_freelist); - nmp->nm_bufqlen++; + + /* + * The passed bio's buffer is not necessary associated with + * the NFS vnode it is being written to. Store the NFS vnode + * in the BIO driver info. + */ + bio->bio_driver_info = vp; + TAILQ_INSERT_TAIL(&nmp->nm_bioq, bio, bio_act); + nmp->nm_bioqlen++; return (0); } @@ -1327,22 +1341,22 @@ again: /* * Do an I/O operation to/from a cache block. This may be called - * synchronously or from an nfsiod. + * synchronously or from an nfsiod. The BIO is normalized for DEV_BSIZE. * * NOTE! TD MIGHT BE NULL */ int -nfs_doio(struct buf *bp, struct thread *td) +nfs_doio(struct vnode *vp, struct bio *bio, struct thread *td) { + struct buf *bp = bio->bio_buf; struct uio *uiop; - struct vnode *vp; struct nfsnode *np; struct nfsmount *nmp; int error = 0, iomode, must_commit = 0; struct uio uio; struct iovec io; - vp = bp->b_vp; + KKASSERT(vp->v_tag == VT_NFS); np = VTONFS(vp); nmp = VFSTONFS(vp->v_mount); uiop = &uio; @@ -1370,7 +1384,7 @@ nfs_doio(struct buf *bp, struct thread *td) io.iov_len = uiop->uio_resid = bp->b_bcount; /* mapping was done by vmapbuf() */ io.iov_base = bp->b_data; - uiop->uio_offset = ((off_t)bp->b_blkno) * DEV_BSIZE; + uiop->uio_offset = (off_t)bio->bio_blkno << DEV_BSHIFT; if (bp->b_flags & B_READ) { uiop->uio_rw = UIO_READ; nfsstats.read_physios++; @@ -1394,7 +1408,7 @@ nfs_doio(struct buf *bp, struct thread *td) switch (vp->v_type) { case VREG: - uiop->uio_offset = ((off_t)bp->b_blkno) * DEV_BSIZE; + uiop->uio_offset = (off_t)bio->bio_blkno << DEV_BSHIFT; nfsstats.read_bios++; error = nfs_readrpc(vp, uiop); @@ -1427,13 +1441,13 @@ nfs_doio(struct buf *bp, struct thread *td) } break; case VLNK: - uiop->uio_offset = (off_t)0; + uiop->uio_offset = 0; nfsstats.readlink_bios++; error = nfs_readlinkrpc(vp, uiop); break; case VDIR: nfsstats.readdir_bios++; - uiop->uio_offset = ((u_quad_t)bp->b_lblkno) * NFS_DIRBLKSIZ; + uiop->uio_offset = (off_t)bio->bio_blkno << DEV_BSHIFT; if (nmp->nm_flag & NFSMNT_RDIRPLUS) { error = nfs_readdirplusrpc(vp, uiop); if (error == NFSERR_NOTSUPP) @@ -1464,18 +1478,19 @@ nfs_doio(struct buf *bp, struct thread *td) int retv; off_t off; - off = ((u_quad_t)bp->b_blkno) * DEV_BSIZE + bp->b_dirtyoff; - retv = nfs_commit(bp->b_vp, off, + off = ((off_t)bio->bio_blkno << DEV_BSHIFT) + + bp->b_dirtyoff; + retv = nfs_commit(vp, off, bp->b_dirtyend - bp->b_dirtyoff, td); if (retv == 0) { bp->b_dirtyoff = bp->b_dirtyend = 0; bp->b_flags &= ~(B_NEEDCOMMIT | B_CLUSTEROK); bp->b_resid = 0; - biodone(bp); + biodone(bio); return (0); } if (retv == NFSERR_STALEWRITEVERF) { - nfs_clearcommit(bp->b_vp->v_mount); + nfs_clearcommit(vp->v_mount); } } @@ -1483,13 +1498,13 @@ nfs_doio(struct buf *bp, struct thread *td) * Setup for actual write */ - if ((off_t)bp->b_blkno * DEV_BSIZE + bp->b_dirtyend > np->n_size) - bp->b_dirtyend = np->n_size - (off_t)bp->b_blkno * DEV_BSIZE; + if (((off_t)bio->bio_blkno << DEV_BSHIFT) + bp->b_dirtyend > np->n_size) + bp->b_dirtyend = np->n_size - ((off_t)bio->bio_blkno << DEV_BSHIFT); if (bp->b_dirtyend > bp->b_dirtyoff) { io.iov_len = uiop->uio_resid = bp->b_dirtyend - bp->b_dirtyoff; - uiop->uio_offset = (off_t)bp->b_blkno * DEV_BSIZE + uiop->uio_offset = ((off_t)bio->bio_blkno << DEV_BSHIFT) + bp->b_dirtyoff; io.iov_base = (char *)bp->b_data + bp->b_dirtyoff; uiop->uio_rw = UIO_WRITE; @@ -1563,14 +1578,14 @@ nfs_doio(struct buf *bp, struct thread *td) } } else { bp->b_resid = 0; - biodone(bp); + biodone(bio); return (0); } } bp->b_resid = uiop->uio_resid; if (must_commit) nfs_clearcommit(vp->v_mount); - biodone(bp); + biodone(bio); return (error); } diff --git a/sys/vfs/nfs/nfs_syscalls.c b/sys/vfs/nfs/nfs_syscalls.c index 578803490f..de9b355c99 100644 --- a/sys/vfs/nfs/nfs_syscalls.c +++ b/sys/vfs/nfs/nfs_syscalls.c @@ -35,7 +35,7 @@ * * @(#)nfs_syscalls.c 8.5 (Berkeley) 3/30/95 * $FreeBSD: src/sys/nfs/nfs_syscalls.c,v 1.58.2.1 2000/11/26 02:30:06 dillon Exp $ - * $DragonFly: src/sys/vfs/nfs/nfs_syscalls.c,v 1.21 2005/06/06 15:09:38 drhodus Exp $ + * $DragonFly: src/sys/vfs/nfs/nfs_syscalls.c,v 1.22 2006/02/17 19:18:07 dillon Exp $ */ #include @@ -918,7 +918,7 @@ SYSCTL_INT(_vfs_nfs, OID_AUTO, defect, CTLFLAG_RW, &nfs_defect, 0, ""); static int nfssvc_iod(struct thread *td) { - struct buf *bp; + struct bio *bio; int i, myiod; struct nfsmount *nmp; int error = 0; @@ -941,10 +941,10 @@ nfssvc_iod(struct thread *td) */ for (;;) { while (((nmp = nfs_iodmount[myiod]) == NULL - || TAILQ_EMPTY(&nmp->nm_bufq)) + || TAILQ_EMPTY(&nmp->nm_bioq)) && error == 0) { if (nmp) - nmp->nm_bufqiods--; + nmp->nm_bioqiods--; nfs_iodwant[myiod] = td; nfs_iodmount[myiod] = NULL; error = tsleep((caddr_t)&nfs_iodwant[myiod], @@ -953,31 +953,34 @@ nfssvc_iod(struct thread *td) if (error) { nfs_asyncdaemon[myiod] = 0; if (nmp) - nmp->nm_bufqiods--; + nmp->nm_bioqiods--; nfs_iodwant[myiod] = NULL; nfs_iodmount[myiod] = NULL; nfs_numasync--; return (error); } - while ((bp = TAILQ_FIRST(&nmp->nm_bufq)) != NULL) { - /* Take one off the front of the list */ - TAILQ_REMOVE(&nmp->nm_bufq, bp, b_freelist); - nmp->nm_bufqlen--; - if (nmp->nm_bufqwant && nmp->nm_bufqlen <= nfs_numasync) { - nmp->nm_bufqwant = FALSE; - wakeup(&nmp->nm_bufq); + while ((bio = TAILQ_FIRST(&nmp->nm_bioq)) != NULL) { + /* + * Take one off the front of the list. The BIO's + * block number is normalized for DEV_BSIZE. + */ + TAILQ_REMOVE(&nmp->nm_bioq, bio, bio_act); + nmp->nm_bioqlen--; + if (nmp->nm_bioqwant && nmp->nm_bioqlen <= nfs_numasync) { + nmp->nm_bioqwant = FALSE; + wakeup(&nmp->nm_bioq); } - (void) nfs_doio(bp, NULL); + nfs_doio((struct vnode *)bio->bio_driver_info, bio, NULL); /* * If there are more than one iod on this mount, then defect * so that the iods can be shared out fairly between the mounts */ - if (nfs_defect && nmp->nm_bufqiods > 1) { + if (nfs_defect && nmp->nm_bioqiods > 1) { NFS_DPF(ASYNCIO, ("nfssvc_iod: iod %d defecting from mount %p\n", myiod, nmp)); nfs_iodmount[myiod] = NULL; - nmp->nm_bufqiods--; + nmp->nm_bioqiods--; break; } } diff --git a/sys/vfs/nfs/nfs_vfsops.c b/sys/vfs/nfs/nfs_vfsops.c index 874c0dc714..4a2fae690b 100644 --- a/sys/vfs/nfs/nfs_vfsops.c +++ b/sys/vfs/nfs/nfs_vfsops.c @@ -35,7 +35,7 @@ * * @(#)nfs_vfsops.c 8.12 (Berkeley) 5/20/95 * $FreeBSD: src/sys/nfs/nfs_vfsops.c,v 1.91.2.7 2003/01/27 20:04:08 dillon Exp $ - * $DragonFly: src/sys/vfs/nfs/nfs_vfsops.c,v 1.34 2006/01/31 19:05:45 dillon Exp $ + * $DragonFly: src/sys/vfs/nfs/nfs_vfsops.c,v 1.35 2006/02/17 19:18:07 dillon Exp $ */ #include "opt_bootp.h" @@ -911,7 +911,7 @@ mountnfs(struct nfs_args *argp, struct mount *mp, struct sockaddr *nam, nmp = zalloc(nfsmount_zone); bzero((caddr_t)nmp, sizeof (struct nfsmount)); TAILQ_INIT(&nmp->nm_uidlruhead); - TAILQ_INIT(&nmp->nm_bufq); + TAILQ_INIT(&nmp->nm_bioq); mp->mnt_data = (qaddr_t)nmp; } vfs_getnewfsid(mp); diff --git a/sys/vfs/nfs/nfs_vnops.c b/sys/vfs/nfs/nfs_vnops.c index cea5ec24ff..c3a67956ab 100644 --- a/sys/vfs/nfs/nfs_vnops.c +++ b/sys/vfs/nfs/nfs_vnops.c @@ -35,7 +35,7 @@ * * @(#)nfs_vnops.c 8.16 (Berkeley) 5/27/95 * $FreeBSD: src/sys/nfs/nfs_vnops.c,v 1.150.2.5 2001/12/20 19:56:28 dillon Exp $ - * $DragonFly: src/sys/vfs/nfs/nfs_vnops.c,v 1.44 2005/12/05 17:01:53 dillon Exp $ + * $DragonFly: src/sys/vfs/nfs/nfs_vnops.c,v 1.45 2006/02/17 19:18:07 dillon Exp $ */ @@ -2858,19 +2858,27 @@ nfs_bmap(struct vop_bmap_args *ap) /* * Strategy routine. + * * For async requests when nfsiod(s) are running, queue the request by * calling nfs_asyncio(), otherwise just all nfs_doio() to do the * request. + * + * bio_blkno is NFS block-sized, which depends whether the vnode is a + * regular file or a directory. */ static int nfs_strategy(struct vop_strategy_args *ap) { - struct buf *bp = ap->a_bp; + struct bio *bio = ap->a_bio; + struct bio *nbio; + struct buf *bp = bio->bio_buf; struct thread *td; int error = 0; - KASSERT(!(bp->b_flags & B_DONE), ("nfs_strategy: buffer %p unexpectedly marked B_DONE", bp)); - KASSERT(BUF_REFCNT(bp) > 0, ("nfs_strategy: buffer %p not locked", bp)); + KASSERT(!(bp->b_flags & B_DONE), + ("nfs_strategy: buffer %p unexpectedly marked B_DONE", bp)); + KASSERT(BUF_REFCNT(bp) > 0, + ("nfs_strategy: buffer %p not locked", bp)); if (bp->b_flags & B_PHYS) panic("nfs physio"); @@ -2880,14 +2888,30 @@ nfs_strategy(struct vop_strategy_args *ap) else td = curthread; /* XXX */ + /* + * Convert to DEV_BSIZE'd blocks for nfs_doio/nfs_asyncio + */ + nbio = push_bio(bio); + + if (bp->b_vp->v_type == VREG) { + int biosize; + + biosize = bp->b_vp->v_mount->mnt_stat.f_iosize; + nbio->bio_blkno = ((off_t)bio->bio_blkno * biosize) >> + DEV_BSHIFT; + } else { + nbio->bio_blkno = ((off_t)bio->bio_blkno * NFS_DIRBLKSIZ) >> + DEV_BSHIFT; + } + + /* * If the op is asynchronous and an i/o daemon is waiting * queue the request, wake it up and wait for completion * otherwise just do it ourselves. */ - if ((bp->b_flags & B_ASYNC) == 0 || - nfs_asyncio(bp, td)) - error = nfs_doio(bp, td); + if ((bp->b_flags & B_ASYNC) == 0 || nfs_asyncio(ap->a_vp, nbio, td)) + error = nfs_doio(ap->a_vp, nbio, td); return (error); } @@ -3001,9 +3025,9 @@ nfs_flush(struct vnode *vp, int waitfor, struct thread *td, int commit) * Wait for pending I/O to complete before checking whether * any further dirty buffers exist. */ - while (waitfor == MNT_WAIT && vp->v_numoutput) { - vp->v_flag |= VBWAIT; - error = tsleep((caddr_t)&vp->v_numoutput, + while (waitfor == MNT_WAIT && vp->v_track_write.bk_active) { + vp->v_track_write.bk_waitflag = 1; + error = tsleep(&vp->v_track_write, info.slpflag, "nfsfsync", info.slptimeo); if (error) { /* @@ -3123,7 +3147,7 @@ nfs_flush_bp(struct buf *bp, void *data) vfs_busy_pages(bp, 1); info->bvary[info->bvsize] = bp; - toff = ((u_quad_t)bp->b_blkno) * DEV_BSIZE + + toff = ((u_quad_t)bp->b_bio2.bio_blkno) * DEV_BSIZE + bp->b_dirtyoff; if (info->bvsize == 0 || toff < info->beg_off) info->beg_off = toff; @@ -3191,15 +3215,18 @@ nfs_flush_docommit(struct nfs_flush_info *info, int error) * b_dirtyoff/b_dirtyend seem to be NFS * specific. We should probably move that * into bundirty(). XXX + * + * We are faking an I/O write, we have to + * start the transaction in order to + * immediately biodone() it. */ crit_enter(); - vp->v_numoutput++; bp->b_flags |= B_ASYNC; bundirty(bp); bp->b_flags &= ~(B_READ|B_DONE|B_ERROR); bp->b_dirtyoff = bp->b_dirtyend = 0; crit_exit(); - biodone(bp); + biodone(&bp->b_bio1); } } info->bvsize = 0; @@ -3289,8 +3316,6 @@ nfs_writebp(struct buf *bp, int force, struct thread *td) crit_enter(); bundirty(bp); bp->b_flags &= ~(B_READ|B_DONE|B_ERROR); - - bp->b_vp->v_numoutput++; crit_exit(); /* @@ -3300,9 +3325,9 @@ nfs_writebp(struct buf *bp, int force, struct thread *td) vfs_busy_pages(bp, 1); BUF_KERNPROC(bp); - VOP_STRATEGY(bp->b_vp, bp); + vn_strategy(bp->b_vp, &bp->b_bio1); - if( (oldflags & B_ASYNC) == 0) { + if((oldflags & B_ASYNC) == 0) { int rtval = biowait(bp); if (oldflags & B_DELWRI) { diff --git a/sys/vfs/nfs/nfsmount.h b/sys/vfs/nfs/nfsmount.h index 242a3dfcec..a882e1816c 100644 --- a/sys/vfs/nfs/nfsmount.h +++ b/sys/vfs/nfs/nfsmount.h @@ -35,7 +35,7 @@ * * @(#)nfsmount.h 8.3 (Berkeley) 3/30/95 * $FreeBSD: src/sys/nfs/nfsmount.h,v 1.17 1999/12/29 04:54:54 peter Exp $ - * $DragonFly: src/sys/vfs/nfs/nfsmount.h,v 1.5 2004/04/07 05:15:48 dillon Exp $ + * $DragonFly: src/sys/vfs/nfs/nfsmount.h,v 1.6 2006/02/17 19:18:07 dillon Exp $ */ @@ -89,10 +89,10 @@ struct nfsmount { int nm_numuids; /* Number of nfsuid mappings */ TAILQ_HEAD(, nfsuid) nm_uidlruhead; /* Lists of nfsuid mappings */ LIST_HEAD(, nfsuid) nm_uidhashtbl[NFS_MUIDHASHSIZ]; - TAILQ_HEAD(, buf) nm_bufq; /* async io buffer queue */ - short nm_bufqlen; /* number of buffers in queue */ - short nm_bufqwant; /* process wants to add to the queue */ - int nm_bufqiods; /* number of iods processing queue */ + TAILQ_HEAD(, bio) nm_bioq; /* async io buffer queue */ + short nm_bioqlen; /* number of buffers in queue */ + short nm_bioqwant; /* process wants to add to the queue */ + int nm_bioqiods; /* number of iods processing queue */ u_int64_t nm_maxfilesize; /* maximum file size */ struct ucred *nm_cred; /* 'root' credential */ struct thread *nm_rcvlock_td; /* debugging */ diff --git a/sys/vfs/ntfs/ntfs_vnops.c b/sys/vfs/ntfs/ntfs_vnops.c index e42c2aa049..7a1d9fb883 100644 --- a/sys/vfs/ntfs/ntfs_vnops.c +++ b/sys/vfs/ntfs/ntfs_vnops.c @@ -36,7 +36,7 @@ * SUCH DAMAGE. * * $FreeBSD: src/sys/ntfs/ntfs_vnops.c,v 1.9.2.4 2002/08/06 19:35:18 semenu Exp $ - * $DragonFly: src/sys/vfs/ntfs/ntfs_vnops.c,v 1.24 2005/09/14 01:13:40 dillon Exp $ + * $DragonFly: src/sys/vfs/ntfs/ntfs_vnops.c,v 1.25 2006/02/17 19:18:07 dillon Exp $ * */ @@ -319,13 +319,14 @@ ntfs_print(struct vop_print_args *ap) * Calculate the logical to physical mapping if not done already, * then call the device strategy routine. * - * ntfs_strategy(struct buf *a_bp) + * ntfs_strategy(struct vnode *a_vp, struct bio *a_bio) */ int ntfs_strategy(struct vop_strategy_args *ap) { - struct buf *bp = ap->a_bp; - struct vnode *vp = bp->b_vp; + struct bio *bio = ap->a_bio; + struct buf *bp = bio->bio_buf; + struct vnode *vp = ap->a_vp; struct fnode *fp = VTOF(vp); struct ntnode *ip = FTONT(fp); struct ntfsmount *ntmp = ip->i_mp; @@ -333,11 +334,11 @@ ntfs_strategy(struct vop_strategy_args *ap) #ifdef __DragonFly__ dprintf(("ntfs_strategy: offset: %d, blkno: %d, lblkno: %d\n", - (u_int32_t)bp->b_offset,(u_int32_t)bp->b_blkno, + (u_int32_t)bp->b_loffset,(u_int32_t)bio->bio_blkno, (u_int32_t)bp->b_lblkno)); #else dprintf(("ntfs_strategy: blkno: %d, lblkno: %d\n", - (u_int32_t)bp->b_blkno, + (u_int32_t)bio->bio_blkno, (u_int32_t)bp->b_lblkno)); #endif @@ -347,17 +348,17 @@ ntfs_strategy(struct vop_strategy_args *ap) if (bp->b_flags & B_READ) { u_int32_t toread; - if (ntfs_cntob(bp->b_blkno) >= fp->f_size) { + if (ntfs_cntob(bio->bio_blkno) >= fp->f_size) { clrbuf(bp); error = 0; } else { toread = min(bp->b_bcount, - fp->f_size-ntfs_cntob(bp->b_blkno)); + fp->f_size-ntfs_cntob(bio->bio_blkno)); dprintf(("ntfs_strategy: toread: %d, fsize: %d\n", toread,(u_int32_t)fp->f_size)); error = ntfs_readattr(ntmp, ip, fp->f_attrtype, - fp->f_attrname, ntfs_cntob(bp->b_blkno), + fp->f_attrname, ntfs_cntob(bio->bio_blkno), toread, bp->b_data, NULL); if (error) { @@ -372,18 +373,18 @@ ntfs_strategy(struct vop_strategy_args *ap) size_t tmp; u_int32_t towrite; - if (ntfs_cntob(bp->b_blkno) + bp->b_bcount >= fp->f_size) { + if (ntfs_cntob(bio->bio_blkno) + bp->b_bcount >= fp->f_size) { printf("ntfs_strategy: CAN'T EXTEND FILE\n"); bp->b_error = error = EFBIG; bp->b_flags |= B_ERROR; } else { towrite = min(bp->b_bcount, - fp->f_size-ntfs_cntob(bp->b_blkno)); + fp->f_size-ntfs_cntob(bio->bio_blkno)); dprintf(("ntfs_strategy: towrite: %d, fsize: %d\n", towrite,(u_int32_t)fp->f_size)); error = ntfs_writeattr_plain(ntmp, ip, fp->f_attrtype, - fp->f_attrname, ntfs_cntob(bp->b_blkno),towrite, + fp->f_attrname, ntfs_cntob(bio->bio_blkno),towrite, bp->b_data, &tmp, NULL); if (error) { @@ -393,7 +394,7 @@ ntfs_strategy(struct vop_strategy_args *ap) } } } - biodone(bp); + biodone(bio); return (error); } diff --git a/sys/vfs/nwfs/nwfs.h b/sys/vfs/nwfs/nwfs.h index 5770dee468..72beebb366 100644 --- a/sys/vfs/nwfs/nwfs.h +++ b/sys/vfs/nwfs/nwfs.h @@ -30,7 +30,7 @@ * SUCH DAMAGE. * * $FreeBSD: src/sys/nwfs/nwfs.h,v 1.3 1999/12/29 04:54:56 peter Exp $ - * $DragonFly: src/sys/vfs/nwfs/nwfs.h,v 1.6 2003/08/07 21:54:35 dillon Exp $ + * $DragonFly: src/sys/vfs/nwfs/nwfs.h,v 1.7 2006/02/17 19:18:07 dillon Exp $ */ #ifndef _NWFS_H_ @@ -76,7 +76,7 @@ struct nwmount { int ncp_conn_logged_in(struct nwmount *); int nwfs_ioctl(struct vop_ioctl_args *ap); -int nwfs_doio(struct buf *bp, struct ucred *cr, struct thread *td); +int nwfs_doio(struct vnode *vp, struct bio *bio, struct ucred *cr, struct thread *td); int nwfs_vinvalbuf(struct vnode *vp, int flags, struct thread *td, int intrflg); #endif /* _KERNEL */ diff --git a/sys/vfs/nwfs/nwfs_io.c b/sys/vfs/nwfs/nwfs_io.c index ad189e0069..d95c3bceac 100644 --- a/sys/vfs/nwfs/nwfs_io.c +++ b/sys/vfs/nwfs/nwfs_io.c @@ -30,7 +30,7 @@ * SUCH DAMAGE. * * $FreeBSD: src/sys/nwfs/nwfs_io.c,v 1.6.2.1 2000/10/25 02:11:10 bp Exp $ - * $DragonFly: src/sys/vfs/nwfs/nwfs_io.c,v 1.17 2005/08/16 19:16:39 joerg Exp $ + * $DragonFly: src/sys/vfs/nwfs/nwfs_io.c,v 1.18 2006/02/17 19:18:07 dillon Exp $ * */ #include @@ -259,17 +259,16 @@ nwfs_writevnode(struct vnode *vp, struct uio *uiop, struct ucred *cred, * Do an I/O operation to/from a cache block. */ int -nwfs_doio(struct buf *bp, struct ucred *cr, struct thread *td) +nwfs_doio(struct vnode *vp, struct bio *bio, struct ucred *cr, struct thread *td) { + struct buf *bp = bio->bio_buf; struct uio *uiop; - struct vnode *vp; struct nwnode *np; struct nwmount *nmp; int error = 0; struct uio uio; struct iovec io; - vp = bp->b_vp; np = VTONW(vp); nmp = VFSTONWFS(vp->v_mount); uiop = &uio; @@ -283,7 +282,7 @@ nwfs_doio(struct buf *bp, struct ucred *cr, struct thread *td) uiop->uio_rw = UIO_READ; switch (vp->v_type) { case VREG: - uiop->uio_offset = ((off_t)bp->b_blkno) * DEV_BSIZE; + uiop->uio_offset = ((off_t)bio->bio_blkno) * DEV_BSIZE; error = ncp_read(NWFSTOCONN(nmp), &np->n_fh, uiop, cr); if (error) break; @@ -296,7 +295,7 @@ nwfs_doio(struct buf *bp, struct ucred *cr, struct thread *td) break; /* case VDIR: nfsstats.readdir_bios++; - uiop->uio_offset = ((u_quad_t)bp->b_lblkno) * NFS_DIRBLKSIZ; + uiop->uio_offset = ((u_quad_t)bio->bio_blkno) * NFS_DIRBLKSIZ; if (nmp->nm_flag & NFSMNT_RDIRPLUS) { error = nfs_readdirplusrpc(vp, uiop, cr); if (error == NFSERR_NOTSUPP) @@ -317,12 +316,12 @@ nwfs_doio(struct buf *bp, struct ucred *cr, struct thread *td) bp->b_error = error; } } else { /* write */ - if (((bp->b_blkno * DEV_BSIZE) + bp->b_dirtyend) > np->n_size) - bp->b_dirtyend = np->n_size - (bp->b_blkno * DEV_BSIZE); + if (((bio->bio_blkno * DEV_BSIZE) + bp->b_dirtyend) > np->n_size) + bp->b_dirtyend = np->n_size - (bio->bio_blkno * DEV_BSIZE); if (bp->b_dirtyend > bp->b_dirtyoff) { io.iov_len = uiop->uio_resid = bp->b_dirtyend - bp->b_dirtyoff; - uiop->uio_offset = ((off_t)bp->b_blkno) * DEV_BSIZE + bp->b_dirtyoff; + uiop->uio_offset = ((off_t)bio->bio_blkno) * DEV_BSIZE + bp->b_dirtyoff; io.iov_base = (char *)bp->b_data + bp->b_dirtyoff; uiop->uio_rw = UIO_WRITE; error = ncp_write(NWFSTOCONN(nmp), &np->n_fh, uiop, cr); @@ -364,12 +363,12 @@ nwfs_doio(struct buf *bp, struct ucred *cr, struct thread *td) } } else { bp->b_resid = 0; - biodone(bp); + biodone(bio); return (0); } } bp->b_resid = uiop->uio_resid; - biodone(bp); + biodone(bio); return (error); } diff --git a/sys/vfs/nwfs/nwfs_vnops.c b/sys/vfs/nwfs/nwfs_vnops.c index d48f609677..1fb6d71ad9 100644 --- a/sys/vfs/nwfs/nwfs_vnops.c +++ b/sys/vfs/nwfs/nwfs_vnops.c @@ -30,7 +30,7 @@ * SUCH DAMAGE. * * $FreeBSD: src/sys/nwfs/nwfs_vnops.c,v 1.6.2.3 2001/03/14 11:26:59 bp Exp $ - * $DragonFly: src/sys/vfs/nwfs/nwfs_vnops.c,v 1.23 2005/09/14 01:13:42 dillon Exp $ + * $DragonFly: src/sys/vfs/nwfs/nwfs_vnops.c,v 1.24 2006/02/17 19:18:07 dillon Exp $ */ #include #include @@ -731,12 +731,13 @@ nwfs_pathconf(struct vop_pathconf_args *ap) } /* - * nwfs_strategy(struct buf *a_bp) + * nwfs_strategy(struct vnode *a_vp, struct bio *a_bio) */ static int nwfs_strategy(struct vop_strategy_args *ap) { - struct buf *bp=ap->a_bp; + struct bio *bio = ap->a_bio; + struct buf *bp = bio->bio_buf; int error = 0; struct thread *td = NULL; @@ -751,7 +752,7 @@ nwfs_strategy(struct vop_strategy_args *ap) * otherwise just do it ourselves. */ if ((bp->b_flags & B_ASYNC) == 0 ) - error = nwfs_doio(bp, proc0.p_ucred, td); + error = nwfs_doio(ap->a_vp, bio, proc0.p_ucred, td); return (error); } diff --git a/sys/vfs/smbfs/smbfs.h b/sys/vfs/smbfs/smbfs.h index a555cdccba..df15e1634d 100644 --- a/sys/vfs/smbfs/smbfs.h +++ b/sys/vfs/smbfs/smbfs.h @@ -30,7 +30,7 @@ * SUCH DAMAGE. * * $FreeBSD: src/sys/fs/smbfs/smbfs.h,v 1.2.2.2 2003/01/17 08:20:26 tjr Exp $ - * $DragonFly: src/sys/vfs/smbfs/smbfs.h,v 1.5 2003/07/06 21:23:48 dillon Exp $ + * $DragonFly: src/sys/vfs/smbfs/smbfs.h,v 1.6 2006/02/17 19:18:07 dillon Exp $ */ #ifndef _SMBFS_SMBFS_H_ #define _SMBFS_SMBFS_H_ @@ -101,7 +101,7 @@ struct smbmount { #define VTOSMBFS(vp) (VFSTOSMBFS(VTOVFS(vp))) int smbfs_ioctl(struct vop_ioctl_args *ap); -int smbfs_doio(struct buf *bp, struct ucred *cr, struct thread *td); +int smbfs_doio(struct vnode *vp, struct bio *bio, struct ucred *cr, struct thread *td); int smbfs_vinvalbuf(struct vnode *vp, int flags, struct thread *td, int intrflg); #endif /* KERNEL */ diff --git a/sys/vfs/smbfs/smbfs_io.c b/sys/vfs/smbfs/smbfs_io.c index 06c00c943d..5500eac5ea 100644 --- a/sys/vfs/smbfs/smbfs_io.c +++ b/sys/vfs/smbfs/smbfs_io.c @@ -30,7 +30,7 @@ * SUCH DAMAGE. * * $FreeBSD: src/sys/fs/smbfs/smbfs_io.c,v 1.3.2.3 2003/01/17 08:20:26 tjr Exp $ - * $DragonFly: src/sys/vfs/smbfs/smbfs_io.c,v 1.20 2005/12/08 20:37:20 dillon Exp $ + * $DragonFly: src/sys/vfs/smbfs/smbfs_io.c,v 1.21 2006/02/17 19:18:07 dillon Exp $ * */ #include @@ -299,9 +299,9 @@ smbfs_writevnode(struct vnode *vp, struct uio *uiop, * Do an I/O operation to/from a cache block. */ int -smbfs_doio(struct buf *bp, struct ucred *cr, struct thread *td) +smbfs_doio(struct vnode *vp, struct bio *bio, struct ucred *cr, struct thread *td) { - struct vnode *vp = bp->b_vp; + struct buf *bp = bio->bio_buf; struct smbmount *smp = VFSTOSMBFS(vp->v_mount); struct smbnode *np = VTOSMB(vp); struct uio uio, *uiop = &uio; @@ -322,7 +322,7 @@ smbfs_doio(struct buf *bp, struct ucred *cr, struct thread *td) uiop->uio_rw = UIO_READ; switch (vp->v_type) { case VREG: - uiop->uio_offset = ((off_t)bp->b_blkno) * DEV_BSIZE; + uiop->uio_offset = ((off_t)bio->bio_blkno) * DEV_BSIZE; error = smb_read(smp->sm_share, np->n_fid, uiop, &scred); if (error) break; @@ -342,12 +342,12 @@ smbfs_doio(struct buf *bp, struct ucred *cr, struct thread *td) bp->b_flags |= B_ERROR; } } else { /* write */ - if (((bp->b_blkno * DEV_BSIZE) + bp->b_dirtyend) > np->n_size) - bp->b_dirtyend = np->n_size - (bp->b_blkno * DEV_BSIZE); + if ((((off_t)bio->bio_blkno * DEV_BSIZE) + bp->b_dirtyend) > np->n_size) + bp->b_dirtyend = np->n_size - ((off_t)bio->bio_blkno * DEV_BSIZE); if (bp->b_dirtyend > bp->b_dirtyoff) { io.iov_len = uiop->uio_resid = bp->b_dirtyend - bp->b_dirtyoff; - uiop->uio_offset = ((off_t)bp->b_blkno) * DEV_BSIZE + bp->b_dirtyoff; + uiop->uio_offset = ((off_t)bio->bio_blkno) * DEV_BSIZE + bp->b_dirtyoff; io.iov_base = (char *)bp->b_data + bp->b_dirtyoff; uiop->uio_rw = UIO_WRITE; error = smb_write(smp->sm_share, np->n_fid, uiop, &scred); @@ -388,12 +388,12 @@ smbfs_doio(struct buf *bp, struct ucred *cr, struct thread *td) } } else { bp->b_resid = 0; - biodone(bp); + biodone(bio); return 0; } } bp->b_resid = uiop->uio_resid; - biodone(bp); + biodone(bio); return error; } diff --git a/sys/vfs/smbfs/smbfs_vnops.c b/sys/vfs/smbfs/smbfs_vnops.c index 9d15ee804b..ea7cd01b9e 100644 --- a/sys/vfs/smbfs/smbfs_vnops.c +++ b/sys/vfs/smbfs/smbfs_vnops.c @@ -30,7 +30,7 @@ * SUCH DAMAGE. * * $FreeBSD: src/sys/fs/smbfs/smbfs_vnops.c,v 1.2.2.8 2003/04/04 08:57:23 tjr Exp $ - * $DragonFly: src/sys/vfs/smbfs/smbfs_vnops.c,v 1.24 2005/09/14 01:13:45 dillon Exp $ + * $DragonFly: src/sys/vfs/smbfs/smbfs_vnops.c,v 1.25 2006/02/17 19:18:07 dillon Exp $ */ #include #include @@ -792,12 +792,13 @@ smbfs_pathconf(struct vop_pathconf_args *ap) } /* - * smbfs_strategy(struct buf *a_bp) + * smbfs_strategy(struct vnode *a_vp, struct bio *a_bio) */ static int smbfs_strategy(struct vop_strategy_args *ap) { - struct buf *bp=ap->a_bp; + struct bio *bio = ap->a_bio; + struct buf *bp = bio->bio_buf; struct thread *td = NULL; int error = 0; @@ -808,7 +809,7 @@ smbfs_strategy(struct vop_strategy_args *ap) td = curthread; /* XXX */ if ((bp->b_flags & B_ASYNC) == 0 ) - error = smbfs_doio(bp, proc0.p_ucred, td); + error = smbfs_doio(ap->a_vp, bio, proc0.p_ucred, td); return error; } diff --git a/sys/vfs/specfs/spec_vnops.c b/sys/vfs/specfs/spec_vnops.c index dbdd1312fb..dccbc9ce35 100644 --- a/sys/vfs/specfs/spec_vnops.c +++ b/sys/vfs/specfs/spec_vnops.c @@ -32,7 +32,7 @@ * * @(#)spec_vnops.c 8.14 (Berkeley) 5/21/95 * $FreeBSD: src/sys/miscfs/specfs/spec_vnops.c,v 1.131.2.4 2001/02/26 04:23:20 jlemon Exp $ - * $DragonFly: src/sys/vfs/specfs/spec_vnops.c,v 1.29 2005/09/17 07:43:12 dillon Exp $ + * $DragonFly: src/sys/vfs/specfs/spec_vnops.c,v 1.30 2006/02/17 19:18:07 dillon Exp $ */ #include @@ -125,7 +125,7 @@ spec_vnoperate(struct vop_generic_args *ap) return (VOCALL(spec_vnode_vops, ap)); } -static void spec_getpages_iodone (struct buf *bp); +static void spec_getpages_iodone (struct bio *bio); /* * Open a special file. @@ -435,16 +435,16 @@ spec_inactive(struct vop_inactive_args *ap) /* * Just call the device strategy routine * - * spec_strategy(struct vnode *a_vp, struct buf *a_bp) + * spec_strategy(struct vnode *a_vp, struct bio *a_bio) */ static int spec_strategy(struct vop_strategy_args *ap) { - struct buf *bp; + struct bio *bio = ap->a_bio; + struct buf *bp = bio->bio_buf; struct vnode *vp; struct mount *mp; - bp = ap->a_bp; if (((bp->b_flags & B_READ) == 0) && (LIST_FIRST(&bp->b_dep)) != NULL && bioops.io_start) (*bioops.io_start)(bp); @@ -468,8 +468,7 @@ spec_strategy(struct vop_strategy_args *ap) mp->mnt_stat.f_syncreads++; } } - bp->b_dev = vp->v_rdev; - BUF_STRATEGY(bp, 0); + dev_dstrategy_chain(vp->v_rdev, bio); return (0); } @@ -490,11 +489,10 @@ spec_freeblks(struct vop_freeblks_args *ap) return (0); bp = geteblk(ap->a_length); bp->b_flags |= B_FREEBUF; - bp->b_dev = ap->a_vp->v_rdev; - bp->b_blkno = ap->a_addr; - bp->b_offset = dbtob(ap->a_addr); + bp->b_bio1.bio_blkno = ap->a_addr; + bp->b_bio1.bio_offset = dbtob(ap->a_addr); bp->b_bcount = ap->a_length; - BUF_STRATEGY(bp, 0); + dev_dstrategy(ap->a_vp->v_rdev, &bp->b_bio1); return (0); } @@ -633,10 +631,10 @@ spec_advlock(struct vop_advlock_args *ap) } static void -spec_getpages_iodone(struct buf *bp) +spec_getpages_iodone(struct bio *bio) { - bp->b_flags |= B_DONE; - wakeup(bp); + bio->bio_buf->b_flags |= B_DONE; + wakeup(bio->bio_buf); } static int @@ -659,9 +657,9 @@ spec_getpages(struct vop_getpages_args *ap) /* * Calculate the offset of the transfer and do sanity check. - * FreeBSD currently only supports an 8 TB range due to b_blkno + * FreeBSD currently only supports an 8 TB range due to bio_blkno * being in DEV_BSIZE ( usually 512 ) byte chunks on call to - * VOP_STRATEGY. XXX + * vn_strategy(). XXX */ offset = IDX_TO_OFF(ap->a_m[0]->pindex) + ap->a_offset; @@ -705,11 +703,8 @@ spec_getpages(struct vop_getpages_args *ap) /* Build a minimal buffer header. */ bp->b_flags = B_READ; - bp->b_iodone = spec_getpages_iodone; /* B_PHYS is not set, but it is nice to fill this in. */ - bp->b_blkno = blkno; - bp->b_lblkno = blkno; pbgetvp(ap->a_vp, bp); bp->b_bcount = size; bp->b_bufsize = size; @@ -717,11 +712,14 @@ spec_getpages(struct vop_getpages_args *ap) bp->b_runningbufspace = bp->b_bufsize; runningbufspace += bp->b_runningbufspace; + bp->b_bio1.bio_blkno = blkno; + bp->b_bio1.bio_done = spec_getpages_iodone; + mycpu->gd_cnt.v_vnodein++; mycpu->gd_cnt.v_vnodepgsin += pcount; /* Do the input. */ - VOP_STRATEGY(bp->b_vp, bp); + vn_strategy(ap->a_vp, &bp->b_bio1); crit_enter(); @@ -803,7 +801,7 @@ spec_getpages(struct vop_getpages_args *ap) m = ap->a_m[ap->a_reqpage]; printf( "spec_getpages:(%s) I/O read failure: (error=%d) bp %p vp %p\n", - devtoname(bp->b_dev), error, bp, bp->b_vp); + devtoname(vp->v_rdev), error, bp, bp->b_vp); printf( " size: %d, resid: %ld, a_count: %d, valid: 0x%x\n", size, bp->b_resid, ap->a_count, m->valid); diff --git a/sys/vfs/udf/udf_vnops.c b/sys/vfs/udf/udf_vnops.c index 6d59932f9f..ab77a7d28e 100644 --- a/sys/vfs/udf/udf_vnops.c +++ b/sys/vfs/udf/udf_vnops.c @@ -24,7 +24,7 @@ * SUCH DAMAGE. * * $FreeBSD: src/sys/fs/udf/udf_vnops.c,v 1.33 2003/12/07 05:04:49 scottl Exp $ - * $DragonFly: src/sys/vfs/udf/udf_vnops.c,v 1.17 2005/09/14 01:13:47 dillon Exp $ + * $DragonFly: src/sys/vfs/udf/udf_vnops.c,v 1.18 2006/02/17 19:18:08 dillon Exp $ */ /* udf_vnops.c */ @@ -837,39 +837,40 @@ udf_readlink(struct vop_readlink_args *ap) } static int -udf_strategy(struct vop_strategy_args *a) +udf_strategy(struct vop_strategy_args *ap) { + struct bio *bio; + struct bio *nbio; struct buf *bp; struct vnode *vp; struct udf_node *node; int maxsize; - bp = a->a_bp; - vp = bp->b_vp; + bio = ap->a_bio; + bp = bio->bio_buf; + vp = ap->a_vp; node = VTON(vp); - KASSERT(a->a_vp == a->a_bp->b_vp, ("%s(%p != %p)", - __func__, a->a_vp, a->a_bp->b_vp)); - /* cd9660 has this test reversed, but it seems more logical this way */ - if (bp->b_blkno != bp->b_lblkno) { + nbio = push_bio(bio); + if (nbio->bio_blkno == (daddr_t)-1) { /* * Files that are embedded in the fentry don't translate well * to a block number. Reject. */ - if (udf_bmap_internal(node, bp->b_lblkno * node->udfmp->bsize, - &bp->b_lblkno, &maxsize)) { + if (udf_bmap_internal(node, + bio->bio_blkno * node->udfmp->bsize, + &nbio->bio_blkno, &maxsize)) { clrbuf(bp); - bp->b_blkno = -1; + nbio->bio_blkno = -1; } } - if ((long)bp->b_blkno == -1) { - biodone(bp); + if (nbio->bio_blkno == (daddr_t)-1) { + /* I/O was never started on nbio, must biodone(bio) */ + biodone(bio); return(0); } - vp = node->i_devvp; - bp->b_dev = vp->v_rdev; - bp->b_offset = dbtob(bp->b_blkno); - VOP_STRATEGY(vp, bp); + nbio->bio_offset = dbtob(nbio->bio_blkno); + vn_strategy(node->i_devvp, nbio); return(0); } diff --git a/sys/vfs/ufs/ffs_alloc.c b/sys/vfs/ufs/ffs_alloc.c index 1647feebc4..24ffb4f8f0 100644 --- a/sys/vfs/ufs/ffs_alloc.c +++ b/sys/vfs/ufs/ffs_alloc.c @@ -32,7 +32,7 @@ * * @(#)ffs_alloc.c 8.18 (Berkeley) 5/26/95 * $FreeBSD: src/sys/ufs/ffs/ffs_alloc.c,v 1.64.2.2 2001/09/21 19:15:21 dillon Exp $ - * $DragonFly: src/sys/vfs/ufs/ffs_alloc.c,v 1.16 2005/10/26 17:15:03 dillon Exp $ + * $DragonFly: src/sys/vfs/ufs/ffs_alloc.c,v 1.17 2006/02/17 19:18:08 dillon Exp $ */ #include "opt_quota.h" @@ -207,10 +207,10 @@ ffs_realloccg(struct inode *ip, ufs_daddr_t lbprev, ufs_daddr_t bpref, return (error); } - if( bp->b_blkno == bp->b_lblkno) { + if(bp->b_bio2.bio_blkno == (daddr_t)-1) { if( lbprev >= NDADDR) panic("ffs_realloccg: lbprev out of range"); - bp->b_blkno = fsbtodb(fs, bprev); + bp->b_bio2.bio_blkno = fsbtodb(fs, bprev); } #ifdef QUOTA @@ -226,7 +226,7 @@ ffs_realloccg(struct inode *ip, ufs_daddr_t lbprev, ufs_daddr_t bpref, cg = dtog(fs, bprev); bno = ffs_fragextend(ip, cg, (long)bprev, osize, nsize); if (bno) { - if (bp->b_blkno != fsbtodb(fs, bno)) + if (bp->b_bio2.bio_blkno != fsbtodb(fs, bno)) panic("ffs_realloccg: bad blockno"); ip->i_blocks += btodb(nsize - osize); ip->i_flag |= IN_CHANGE | IN_UPDATE; @@ -287,7 +287,7 @@ ffs_realloccg(struct inode *ip, ufs_daddr_t lbprev, ufs_daddr_t bpref, bno = (ufs_daddr_t)ffs_hashalloc(ip, cg, (long)bpref, request, ffs_alloccg); if (bno > 0) { - bp->b_blkno = fsbtodb(fs, bno); + bp->b_bio2.bio_blkno = fsbtodb(fs, bno); if (!DOINGSOFTDEP(ITOV(ip))) ffs_blkfree(ip, bprev, (long)osize); if (nsize < request) @@ -373,15 +373,15 @@ ffs_reallocblks(struct vop_reallocblks_args *ap) #ifdef DIAGNOSTIC for (i = 0; i < len; i++) if (!ffs_checkblk(ip, - dbtofsb(fs, buflist->bs_children[i]->b_blkno), fs->fs_bsize)) + dbtofsb(fs, buflist->bs_children[i]->b_bio2.bio_blkno), fs->fs_bsize)) panic("ffs_reallocblks: unallocated block 1"); for (i = 1; i < len; i++) if (buflist->bs_children[i]->b_lblkno != start_lbn + i) panic("ffs_reallocblks: non-logical cluster"); - blkno = buflist->bs_children[0]->b_blkno; + blkno = buflist->bs_children[0]->b_bio2.bio_blkno; ssize = fsbtodb(fs, fs->fs_frag); for (i = 1; i < len - 1; i++) - if (buflist->bs_children[i]->b_blkno != blkno + (i * ssize)) + if (buflist->bs_children[i]->b_bio2.bio_blkno != blkno + (i * ssize)) panic("ffs_reallocblks: non-physical cluster %d", i); #endif /* @@ -389,8 +389,8 @@ ffs_reallocblks(struct vop_reallocblks_args *ap) * the filesystem has decided to move and do not force it back to * the previous cylinder group. */ - if (dtog(fs, dbtofsb(fs, buflist->bs_children[0]->b_blkno)) != - dtog(fs, dbtofsb(fs, buflist->bs_children[len - 1]->b_blkno))) + if (dtog(fs, dbtofsb(fs, buflist->bs_children[0]->b_bio2.bio_blkno)) != + dtog(fs, dbtofsb(fs, buflist->bs_children[len - 1]->b_bio2.bio_blkno))) return (ENOSPC); if (ufs_getlbns(vp, start_lbn, start_ap, &start_lvl) || ufs_getlbns(vp, end_lbn, end_ap, &end_lvl)) @@ -470,9 +470,9 @@ ffs_reallocblks(struct vop_reallocblks_args *ap) } #ifdef DIAGNOSTIC if (!ffs_checkblk(ip, - dbtofsb(fs, buflist->bs_children[i]->b_blkno), fs->fs_bsize)) + dbtofsb(fs, buflist->bs_children[i]->b_bio2.bio_blkno), fs->fs_bsize)) panic("ffs_reallocblks: unallocated block 2"); - if (dbtofsb(fs, buflist->bs_children[i]->b_blkno) != *bap) + if (dbtofsb(fs, buflist->bs_children[i]->b_bio2.bio_blkno) != *bap) panic("ffs_reallocblks: alloc mismatch"); #endif #ifdef DEBUG @@ -531,12 +531,12 @@ ffs_reallocblks(struct vop_reallocblks_args *ap) for (blkno = newblk, i = 0; i < len; i++, blkno += fs->fs_frag) { if (!DOINGSOFTDEP(vp)) ffs_blkfree(ip, - dbtofsb(fs, buflist->bs_children[i]->b_blkno), + dbtofsb(fs, buflist->bs_children[i]->b_bio2.bio_blkno), fs->fs_bsize); - buflist->bs_children[i]->b_blkno = fsbtodb(fs, blkno); + buflist->bs_children[i]->b_bio2.bio_blkno = fsbtodb(fs, blkno); #ifdef DIAGNOSTIC if (!ffs_checkblk(ip, - dbtofsb(fs, buflist->bs_children[i]->b_blkno), fs->fs_bsize)) + dbtofsb(fs, buflist->bs_children[i]->b_bio2.bio_blkno), fs->fs_bsize)) panic("ffs_reallocblks: unallocated block 3"); #endif #ifdef DEBUG diff --git a/sys/vfs/ufs/ffs_balloc.c b/sys/vfs/ufs/ffs_balloc.c index 93d79af759..31864f33d1 100644 --- a/sys/vfs/ufs/ffs_balloc.c +++ b/sys/vfs/ufs/ffs_balloc.c @@ -32,7 +32,7 @@ * * @(#)ffs_balloc.c 8.8 (Berkeley) 6/16/95 * $FreeBSD: src/sys/ufs/ffs/ffs_balloc.c,v 1.26.2.1 2002/10/10 19:48:20 dillon Exp $ - * $DragonFly: src/sys/vfs/ufs/ffs_balloc.c,v 1.13 2005/10/26 17:13:40 dillon Exp $ + * $DragonFly: src/sys/vfs/ufs/ffs_balloc.c,v 1.14 2006/02/17 19:18:08 dillon Exp $ */ #include @@ -129,11 +129,11 @@ ffs_balloc(struct vop_balloc_args *ap) return (error); if (DOINGSOFTDEP(vp)) softdep_setup_allocdirect(ip, nb, - dbtofsb(fs, bp->b_blkno), ip->i_db[nb], - fs->fs_bsize, osize, bp); + dbtofsb(fs, bp->b_bio2.bio_blkno), + ip->i_db[nb], fs->fs_bsize, osize, bp); /* adjust the inode size, we just grew */ ip->i_size = smalllblktosize(fs, nb + 1); - ip->i_db[nb] = dbtofsb(fs, bp->b_blkno); + ip->i_db[nb] = dbtofsb(fs, bp->b_bio2.bio_blkno); ip->i_flag |= IN_CHANGE | IN_UPDATE; if (flags & B_SYNC) bwrite(bp); @@ -153,7 +153,7 @@ ffs_balloc(struct vop_balloc_args *ap) brelse(bp); return (error); } - bp->b_blkno = fsbtodb(fs, nb); + bp->b_bio2.bio_blkno = fsbtodb(fs, nb); *ap->a_bpp = bp; return (0); } @@ -169,7 +169,7 @@ ffs_balloc(struct vop_balloc_args *ap) brelse(bp); return (error); } - bp->b_blkno = fsbtodb(fs, nb); + bp->b_bio2.bio_blkno = fsbtodb(fs, nb); } else { error = ffs_realloccg(ip, lbn, ffs_blkpref(ip, lbn, (int)lbn, @@ -178,8 +178,8 @@ ffs_balloc(struct vop_balloc_args *ap) return (error); if (DOINGSOFTDEP(vp)) softdep_setup_allocdirect(ip, lbn, - dbtofsb(fs, bp->b_blkno), nb, - nsize, osize, bp); + dbtofsb(fs, bp->b_bio2.bio_blkno), + nb, nsize, osize, bp); } } else { if (ip->i_size < smalllblktosize(fs, lbn + 1)) @@ -192,14 +192,14 @@ ffs_balloc(struct vop_balloc_args *ap) if (error) return (error); bp = getblk(vp, lbn, nsize, 0, 0); - bp->b_blkno = fsbtodb(fs, newb); + bp->b_bio2.bio_blkno = fsbtodb(fs, newb); if (flags & B_CLRBUF) vfs_bio_clrbuf(bp); if (DOINGSOFTDEP(vp)) softdep_setup_allocdirect(ip, lbn, newb, 0, nsize, 0, bp); } - ip->i_db[lbn] = dbtofsb(fs, bp->b_blkno); + ip->i_db[lbn] = dbtofsb(fs, bp->b_bio2.bio_blkno); ip->i_flag |= IN_CHANGE | IN_UPDATE; *ap->a_bpp = bp; return (0); @@ -250,7 +250,7 @@ ffs_balloc(struct vop_balloc_args *ap) nb = newb; *allocblk++ = nb; bp = getblk(vp, indirs[1].in_lbn, fs->fs_bsize, 0, 0); - bp->b_blkno = fsbtodb(fs, nb); + bp->b_bio2.bio_blkno = fsbtodb(fs, nb); vfs_bio_clrbuf(bp); if (DOINGSOFTDEP(vp)) { softdep_setup_allocdirect(ip, NDADDR + indirs[0].in_off, @@ -299,7 +299,7 @@ ffs_balloc(struct vop_balloc_args *ap) nb = newb; *allocblk++ = nb; nbp = getblk(vp, indirs[i].in_lbn, fs->fs_bsize, 0, 0); - nbp->b_blkno = fsbtodb(fs, nb); + nbp->b_bio2.bio_blkno = fsbtodb(fs, nb); vfs_bio_clrbuf(nbp); if (DOINGSOFTDEP(vp)) { softdep_setup_allocindir_meta(nbp, ip, bp, @@ -353,7 +353,7 @@ ffs_balloc(struct vop_balloc_args *ap) } nb = newb; *allocblk++ = nb; - dbp->b_blkno = fsbtodb(fs, nb); + dbp->b_bio2.bio_blkno = fsbtodb(fs, nb); if (flags & B_CLRBUF) vfs_bio_clrbuf(dbp); if (DOINGSOFTDEP(vp)) @@ -387,7 +387,7 @@ ffs_balloc(struct vop_balloc_args *ap) /* * If B_CLRBUF is set we must validate the invalid portions * of the buffer. This typically requires a read-before- - * write. The strategy call will fill in b_blkno in that + * write. The strategy call will fill in bio_blkno in that * case. * * If we hit this case we do a cluster read if possible @@ -408,15 +408,15 @@ ffs_balloc(struct vop_balloc_args *ap) if (error) goto fail; } else { - dbp->b_blkno = fsbtodb(fs, nb); + dbp->b_bio2.bio_blkno = fsbtodb(fs, nb); } } else { /* * If B_CLRBUF is not set the caller intends to overwrite * the entire contents of the buffer. We can simply set - * b_blkno and we are done. + * bio_blkno and we are done. */ - dbp->b_blkno = fsbtodb(fs, nb); + dbp->b_bio2.bio_blkno = fsbtodb(fs, nb); } *ap->a_bpp = dbp; return (0); diff --git a/sys/vfs/ufs/ffs_inode.c b/sys/vfs/ufs/ffs_inode.c index 53243735ca..3417324000 100644 --- a/sys/vfs/ufs/ffs_inode.c +++ b/sys/vfs/ufs/ffs_inode.c @@ -32,7 +32,7 @@ * * @(#)ffs_inode.c 8.13 (Berkeley) 4/21/95 * $FreeBSD: src/sys/ufs/ffs/ffs_inode.c,v 1.56.2.5 2002/02/05 18:35:03 dillon Exp $ - * $DragonFly: src/sys/vfs/ufs/ffs_inode.c,v 1.14 2005/04/15 19:08:32 dillon Exp $ + * $DragonFly: src/sys/vfs/ufs/ffs_inode.c,v 1.15 2006/02/17 19:18:08 dillon Exp $ */ #include "opt_quota.h" @@ -450,7 +450,7 @@ ffs_indirtrunc(struct inode *ip, ufs_daddr_t lbn, ufs_daddr_t dbn, * to blocks to be free'd, and update on disk copy first. Since * double(triple) indirect before single(double) indirect, calls * to bmap on these blocks will fail. However, we already have - * the on disk address, so we have to set the b_blkno field + * the on disk address, so we have to set the bio_blkno field * explicitly instead of letting bread do everything for us. */ vp = ITOV(ip); @@ -460,9 +460,19 @@ ffs_indirtrunc(struct inode *ip, ufs_daddr_t lbn, ufs_daddr_t dbn, bp->b_flags &= ~(B_ERROR|B_INVAL); if (bp->b_bcount > bp->b_bufsize) panic("ffs_indirtrunc: bad buffer size"); - bp->b_blkno = dbn; + bp->b_bio2.bio_blkno = dbn; vfs_busy_pages(bp, 0); - VOP_STRATEGY(bp->b_vp, bp); + /* + * Access the block device layer using the device vnode + * and the translated block number (bio2) instead of the + * file vnode (vp) and logical block number (bio1). + * + * Even though we are bypassing the vnode layer, we still + * want the vnode state to indicate that an I/O on its behalf + * is in progress. + */ + bio_start_transaction(&bp->b_bio1, &vp->v_track_read); + vn_strategy(ip->i_devvp, &bp->b_bio2); error = biowait(bp); } if (error) { diff --git a/sys/vfs/ufs/ffs_rawread.c b/sys/vfs/ufs/ffs_rawread.c index 0fc20dd6cf..d6a56ad3a5 100644 --- a/sys/vfs/ufs/ffs_rawread.c +++ b/sys/vfs/ufs/ffs_rawread.c @@ -24,7 +24,7 @@ * SUCH DAMAGE. * * $FreeBSD: src/sys/ufs/ffs/ffs_rawread.c,v 1.3.2.2 2003/05/29 06:15:35 alc Exp $ - * $DragonFly: src/sys/vfs/ufs/ffs_rawread.c,v 1.13 2005/11/19 17:58:30 dillon Exp $ + * $DragonFly: src/sys/vfs/ufs/ffs_rawread.c,v 1.14 2006/02/17 19:18:08 dillon Exp $ */ #include @@ -63,7 +63,7 @@ int ffs_rawread(struct vnode *vp, struct uio *uio, int *workdone); void ffs_rawread_setup(void); -static void ffs_rawreadwakeup(struct buf *bp); +static void ffs_rawreadwakeup(struct bio *bio); SYSCTL_DECL(_vfs_ffs); @@ -96,7 +96,7 @@ ffs_rawread_sync(struct vnode *vp, struct thread *td) /* Check for dirty mmap, pending writes and dirty buffers */ crit_enter(); - if (vp->v_numoutput > 0 || + if (vp->v_track_write.bk_active > 0 || !RB_EMPTY(&vp->v_rbdirty_tree) || (vp->v_flag & VOBJDIRTY) != 0) { crit_exit(); @@ -117,10 +117,9 @@ ffs_rawread_sync(struct vnode *vp, struct thread *td) /* Wait for pending writes to complete */ crit_enter(); - while (vp->v_numoutput) { - vp->v_flag |= VBWAIT; - error = tsleep((caddr_t)&vp->v_numoutput, 0, - "rawrdfls", 0); + while (vp->v_track_write.bk_active) { + vp->v_track_write.bk_waitflag = 1; + error = tsleep(&vp->v_track_write, 0, "rawrdfls", 0); if (error != 0) { crit_exit(); if (upgraded != 0) @@ -137,7 +136,7 @@ ffs_rawread_sync(struct vnode *vp, struct thread *td) return (error); } crit_enter(); - if (vp->v_numoutput > 0 || + if (vp->v_track_write.bk_active > 0 || !RB_EMPTY(&vp->v_rbdirty_tree)) panic("ffs_rawread_sync: dirty bufs"); } @@ -152,7 +151,7 @@ ffs_rawread_sync(struct vnode *vp, struct thread *td) static int -ffs_rawread_readahead(struct vnode *vp, caddr_t udata, off_t offset, +ffs_rawread_readahead(struct vnode *vp, caddr_t udata, off_t loffset, size_t len, struct thread *td, struct buf *bp, caddr_t sa, int *baseticks) { @@ -174,27 +173,28 @@ ffs_rawread_readahead(struct vnode *vp, caddr_t udata, off_t offset, bp->b_bcount -= PAGE_SIZE; } bp->b_flags = B_PHYS | B_READ; - bp->b_iodone = ffs_rawreadwakeup; bp->b_data = udata; bp->b_saveaddr = sa; - bp->b_offset = offset; - blockno = bp->b_offset / bsize; - blockoff = (bp->b_offset % bsize) / DEV_BSIZE; - if ((daddr_t) blockno != blockno) { + bp->b_loffset = loffset; + blockno = loffset / bsize; + blockoff = (loffset % bsize) / DEV_BSIZE; + if ((daddr_t)blockno != blockno) { return EINVAL; /* blockno overflow */ } - - bp->b_lblkno = bp->b_blkno = blockno; - - error = VOP_BMAP(vp, bp->b_lblkno, &dp, &bp->b_blkno, &bforwards, - NULL); + bp->b_lblkno = blockno; + bp->b_bio2.bio_offset = NOOFFSET; + bp->b_bio2.bio_blkno = (daddr_t)-1; + bp->b_bio2.bio_done = ffs_rawreadwakeup; + + error = VOP_BMAP(vp, bp->b_lblkno, &dp, &bp->b_bio2.bio_blkno, + &bforwards, NULL); if (error != 0) { return error; } - if (bp->b_blkno == -1) { - - /* Fill holes with NULs to preserve semantics */ - + if (bp->b_bio2.bio_blkno == (daddr_t)-1) { + /* + * Fill holes with NULs to preserve semantics + */ if (bp->b_bcount + blockoff * DEV_BSIZE > bsize) bp->b_bcount = bsize - blockoff * DEV_BSIZE; bp->b_bufsize = bp->b_bcount; @@ -218,13 +218,22 @@ ffs_rawread_readahead(struct vnode *vp, caddr_t udata, off_t offset, if (bp->b_bcount + blockoff * DEV_BSIZE > bsize * (1 + bforwards)) bp->b_bcount = bsize * (1 + bforwards) - blockoff * DEV_BSIZE; bp->b_bufsize = bp->b_bcount; - bp->b_blkno += blockoff; - bp->b_dev = dp->v_rdev; + bp->b_bio2.bio_blkno += blockoff; if (vmapbuf(bp) < 0) return EFAULT; - (void) VOP_STRATEGY(dp, bp); + /* + * Access the block device layer using the device vnode (dp) and + * the translated block number (bio2) instead of the logical block + * number (bio1). + * + * Even though we are bypassing the vnode layer, we still + * want the vnode state to indicate that an I/O on its behalf + * is in progress. + */ + bio_start_transaction(&bp->b_bio1, &vp->v_track_read); + vn_strategy(dp, &bp->b_bio2); return 0; } @@ -294,7 +303,7 @@ ffs_rawread_main(struct vnode *vp, struct uio *uio) crit_enter(); while ((bp->b_flags & B_DONE) == 0) { - tsleep((caddr_t)bp, 0, "rawrd", 0); + tsleep((caddr_t)&bp->b_bio2, 0, "rawrd", 0); } crit_exit(); @@ -310,6 +319,7 @@ ffs_rawread_main(struct vnode *vp, struct uio *uio) error = bp->b_error; break; } + clearbiocache(&bp->b_bio2); resid -= iolen; udata += iolen; offset += iolen; @@ -330,6 +340,8 @@ ffs_rawread_main(struct vnode *vp, struct uio *uio) tsa = sa; sa = nsa; nsa = tsa; + + clearbiocache(&nbp->b_bio2); if (resid <= bp->b_bufsize) { /* No more readaheads */ relpbuf(nbp, &ffsrawbufcnt); @@ -361,7 +373,7 @@ ffs_rawread_main(struct vnode *vp, struct uio *uio) if (nbp != NULL) { /* Run down readahead buffer */ crit_enter(); while ((nbp->b_flags & B_DONE) == 0) { - tsleep((caddr_t)nbp, 0, "rawrd", 0); + tsleep(&nbp->b_bio2, 0, "rawrd", 0); } crit_exit(); vunmapbuf(nbp); @@ -442,7 +454,7 @@ ffs_rawread(struct vnode *vp, static void -ffs_rawreadwakeup(struct buf *bp) +ffs_rawreadwakeup(struct bio *bio) { - wakeup((caddr_t) bp); + wakeup(bio); } diff --git a/sys/vfs/ufs/ffs_softdep.c b/sys/vfs/ufs/ffs_softdep.c index 5971ea00fb..5f582b50d4 100644 --- a/sys/vfs/ufs/ffs_softdep.c +++ b/sys/vfs/ufs/ffs_softdep.c @@ -37,7 +37,7 @@ * * from: @(#)ffs_softdep.c 9.59 (McKusick) 6/21/00 * $FreeBSD: src/sys/ufs/ffs/ffs_softdep.c,v 1.57.2.11 2002/02/05 18:46:53 dillon Exp $ - * $DragonFly: src/sys/vfs/ufs/ffs_softdep.c,v 1.33 2006/01/11 02:46:38 corecode Exp $ + * $DragonFly: src/sys/vfs/ufs/ffs_softdep.c,v 1.34 2006/02/17 19:18:08 dillon Exp $ */ /* @@ -1696,12 +1696,15 @@ setup_allocindir_phase2(bp, ip, aip) newindirdep->ir_state = ATTACHED; LIST_INIT(&newindirdep->ir_deplisthd); LIST_INIT(&newindirdep->ir_donehd); - if (bp->b_blkno == bp->b_lblkno) { - VOP_BMAP(bp->b_vp, bp->b_lblkno, NULL, &bp->b_blkno, + if (bp->b_bio2.bio_blkno == (daddr_t)-1) { + VOP_BMAP(bp->b_vp, bp->b_bio1.bio_blkno, + NULL, &bp->b_bio2.bio_blkno, NULL, NULL); } + KKASSERT(bp->b_bio2.bio_blkno != (daddr_t)-1); newindirdep->ir_savebp = - getblk(ip->i_devvp, bp->b_blkno, bp->b_bcount, 0, 0); + getblk(ip->i_devvp, bp->b_bio2.bio_blkno, bp->b_bcount, + 0, 0); BUF_KERNPROC(newindirdep->ir_savebp); bcopy(bp->b_data, newindirdep->ir_savebp->b_data, bp->b_bcount); } @@ -1931,6 +1934,9 @@ deallocate_dependencies(bp, inodedep) * purpose. Hence we swap the safe copy with the real * copy, allowing the safe copy to be freed and holding * on to the real copy for later use in indir_trunc. + * + * NOTE: ir_savebp is relative to the block device + * so b_bio1 contains the device block number. */ if (indirdep->ir_state & GOINGAWAY) { FREE_LOCK(&lk); @@ -1939,8 +1945,8 @@ deallocate_dependencies(bp, inodedep) indirdep->ir_state |= GOINGAWAY; while ((aip = LIST_FIRST(&indirdep->ir_deplisthd)) != 0) free_allocindir(aip, inodedep); - if (bp->b_lblkno >= 0 || - bp->b_blkno != indirdep->ir_savebp->b_lblkno) { + if (bp->b_bio1.bio_blkno >= 0 || + bp->b_bio2.bio_blkno != indirdep->ir_savebp->b_bio1.bio_blkno) { FREE_LOCK(&lk); panic("deallocate_dependencies: not indir"); } @@ -5059,10 +5065,10 @@ drain_output(vp, islocked) if (!islocked) ACQUIRE_LOCK(&lk); - while (vp->v_numoutput) { - vp->v_flag |= VBWAIT; - interlocked_sleep(&lk, SLEEP, (caddr_t)&vp->v_numoutput, - 0, "drainvp", 0); + while (vp->v_track_write.bk_active) { + vp->v_track_write.bk_waitflag = 1; + interlocked_sleep(&lk, SLEEP, &vp->v_track_write, + 0, "drainvp", 0); } if (!islocked) FREE_LOCK(&lk); diff --git a/sys/vfs/ufs/ffs_subr.c b/sys/vfs/ufs/ffs_subr.c index ca98acf99e..931a0d851b 100644 --- a/sys/vfs/ufs/ffs_subr.c +++ b/sys/vfs/ufs/ffs_subr.c @@ -32,7 +32,7 @@ * * @(#)ffs_subr.c 8.5 (Berkeley) 3/21/95 * $FreeBSD: src/sys/ufs/ffs/ffs_subr.c,v 1.25 1999/12/29 04:55:04 peter Exp $ - * $DragonFly: src/sys/vfs/ufs/ffs_subr.c,v 1.8 2005/10/16 18:48:36 dillon Exp $ + * $DragonFly: src/sys/vfs/ufs/ffs_subr.c,v 1.9 2006/02/17 19:18:08 dillon Exp $ */ #include @@ -155,7 +155,7 @@ ffs_checkoverlap(struct buf *bp, struct inode *ip) struct vnode *vp; ebp = &buf[nbuf]; - start = bp->b_blkno; + start = bp->b_bio2.bio_blkno; last = start + btodb(bp->b_bcount) - 1; for (ep = buf; ep < ebp; ep++) { if (ep == bp || (ep->b_flags & B_INVAL) || @@ -167,13 +167,15 @@ ffs_checkoverlap(struct buf *bp, struct inode *ip) if (vp != ip->i_devvp) continue; /* look for overlap */ - if (ep->b_bcount == 0 || ep->b_blkno > last || - ep->b_blkno + btodb(ep->b_bcount) <= start) + if (ep->b_bcount == 0 || ep->b_bio2.bio_blkno == (daddr_t)-1 || + ep->b_bio2.bio_blkno > last || + ep->b_bio2.bio_blkno + btodb(ep->b_bcount) <= start) continue; vprint("Disk overlap", vp); (void)printf("\tstart %lu, end %lu overlap start %lu, end %lu\n", - (u_long)start, (u_long)last, (u_long)ep->b_blkno, - (u_long)(ep->b_blkno + btodb(ep->b_bcount) - 1)); + (u_long)start, (u_long)last, + (u_long)ep->b_bio2.bio_blkno, + (u_long)(ep->b_bio2.bio_blkno + btodb(ep->b_bcount) - 1)); panic("ffs_checkoverlap: Disk buffer overlap"); } } diff --git a/sys/vfs/ufs/ffs_vfsops.c b/sys/vfs/ufs/ffs_vfsops.c index 7d3057ce3d..05721a73e1 100644 --- a/sys/vfs/ufs/ffs_vfsops.c +++ b/sys/vfs/ufs/ffs_vfsops.c @@ -32,7 +32,7 @@ * * @(#)ffs_vfsops.c 8.31 (Berkeley) 5/20/95 * $FreeBSD: src/sys/ufs/ffs/ffs_vfsops.c,v 1.117.2.10 2002/06/23 22:34:52 iedowse Exp $ - * $DragonFly: src/sys/vfs/ufs/ffs_vfsops.c,v 1.34 2005/09/17 07:43:12 dillon Exp $ + * $DragonFly: src/sys/vfs/ufs/ffs_vfsops.c,v 1.35 2006/02/17 19:18:08 dillon Exp $ */ #include "opt_quota.h" @@ -1244,6 +1244,9 @@ ffs_sbupdate(struct ufsmount *mp, int waitfor) /* * First write back the summary information. + * + * NOTE: the getblk is relative to the device vnode so bio1 + * contains the device block number. */ blks = howmany(fs->fs_cssize, fs->fs_fsize); space = fs->fs_csp; @@ -1252,7 +1255,7 @@ ffs_sbupdate(struct ufsmount *mp, int waitfor) if (i + fs->fs_frag > blks) size = (blks - i) * fs->fs_fsize; bp = getblk(mp->um_devvp, fsbtodb(fs, fs->fs_csaddr + i), - size, 0, 0); + size, 0, 0); bcopy(space, bp->b_data, (uint)size); space = (char *)space + size; if (waitfor != MNT_WAIT) diff --git a/sys/vfs/ufs/ufs_bmap.c b/sys/vfs/ufs/ufs_bmap.c index f9529d1520..730ce1f44b 100644 --- a/sys/vfs/ufs/ufs_bmap.c +++ b/sys/vfs/ufs/ufs_bmap.c @@ -37,7 +37,7 @@ * * @(#)ufs_bmap.c 8.7 (Berkeley) 3/21/95 * $FreeBSD: src/sys/ufs/ufs/ufs_bmap.c,v 1.34.2.1 2000/03/17 10:12:14 ps Exp $ - * $DragonFly: src/sys/vfs/ufs/ufs_bmap.c,v 1.6 2004/05/18 00:16:46 cpressey Exp $ + * $DragonFly: src/sys/vfs/ufs/ufs_bmap.c,v 1.7 2006/02/17 19:18:08 dillon Exp $ */ #include @@ -181,11 +181,11 @@ ufs_bmaparray(struct vnode *vp, ufs_daddr_t bn, ufs_daddr_t *bnp, if (!daddr) panic("ufs_bmaparray: indirect block not in cache"); #endif - bp->b_blkno = blkptrtodb(ump, daddr); + bp->b_bio2.bio_blkno = blkptrtodb(ump, daddr); bp->b_flags |= B_READ; bp->b_flags &= ~(B_INVAL|B_ERROR); vfs_busy_pages(bp, 0); - VOP_STRATEGY(bp->b_vp, bp); + vn_strategy(bp->b_vp, &bp->b_bio1); error = biowait(bp); if (error) { brelse(bp); diff --git a/sys/vfs/ufs/ufs_vnops.c b/sys/vfs/ufs/ufs_vnops.c index edcbd76e20..ce13fc4da9 100644 --- a/sys/vfs/ufs/ufs_vnops.c +++ b/sys/vfs/ufs/ufs_vnops.c @@ -37,7 +37,7 @@ * * @(#)ufs_vnops.c 8.27 (Berkeley) 5/27/95 * $FreeBSD: src/sys/ufs/ufs/ufs_vnops.c,v 1.131.2.8 2003/01/02 17:26:19 bde Exp $ - * $DragonFly: src/sys/vfs/ufs/ufs_vnops.c,v 1.32 2005/09/17 07:43:12 dillon Exp $ + * $DragonFly: src/sys/vfs/ufs/ufs_vnops.c,v 1.33 2006/02/17 19:18:08 dillon Exp $ */ #include "opt_quota.h" @@ -1443,7 +1443,7 @@ ufs_mkdir(struct vop_old_mkdir_args *ap) } if ((error = UFS_UPDATE(tvp, !(DOINGSOFTDEP(tvp) | DOINGASYNC(tvp)))) != 0) { - (void)VOP_BWRITE(bp->b_vp, bp); + VOP_BWRITE(bp->b_vp, bp); goto bad; } /* @@ -1757,13 +1757,15 @@ ufs_readlink(struct vop_readlink_args *ap) * In order to be able to swap to a file, the VOP_BMAP operation may not * deadlock on memory. See ufs_bmap() for details. * - * ufs_strategy(struct vnode *a_vp, struct buf *a_bp) + * ufs_strategy(struct vnode *a_vp, struct bio *a_bio) */ static int ufs_strategy(struct vop_strategy_args *ap) { - struct buf *bp = ap->a_bp; + struct bio *bio = ap->a_bio; + struct bio *nbio; + struct buf *bp = bio->bio_buf; struct vnode *vp = ap->a_vp; struct inode *ip; int error; @@ -1771,24 +1773,26 @@ ufs_strategy(struct vop_strategy_args *ap) ip = VTOI(vp); if (vp->v_type == VBLK || vp->v_type == VCHR) panic("ufs_strategy: spec"); - if (bp->b_blkno == bp->b_lblkno) { - error = VOP_BMAP(vp, bp->b_lblkno, NULL, &bp->b_blkno, NULL, NULL); + nbio = push_bio(bio); + if (nbio->bio_blkno == (daddr_t)-1) { + error = VOP_BMAP(vp, bio->bio_blkno, NULL, &nbio->bio_blkno, + NULL, NULL); if (error) { bp->b_error = error; bp->b_flags |= B_ERROR; - biodone(bp); + /* I/O was never started on nbio, must biodone(bio) */ + biodone(bio); return (error); } - if (bp->b_blkno == (daddr_t)-1) + if (nbio->bio_blkno == (daddr_t)-1) vfs_bio_clrbuf(bp); } - if (bp->b_blkno == (daddr_t)-1) { - biodone(bp); + if (nbio->bio_blkno == (daddr_t)-1) { + /* I/O was never started on nbio, must biodone(bio) */ + biodone(bio); return (0); } - vp = ip->i_devvp; - bp->b_dev = vp->v_rdev; - VOP_STRATEGY(vp, bp); + vn_strategy(ip->i_devvp, nbio); return (0); } diff --git a/sys/vfs/union/union_vnops.c b/sys/vfs/union/union_vnops.c index b92078a886..71efd75dfc 100644 --- a/sys/vfs/union/union_vnops.c +++ b/sys/vfs/union/union_vnops.c @@ -36,7 +36,7 @@ * * @(#)union_vnops.c 8.32 (Berkeley) 6/23/95 * $FreeBSD: src/sys/miscfs/union/union_vnops.c,v 1.72 1999/12/15 23:02:14 eivind Exp $ - * $DragonFly: src/sys/vfs/union/union_vnops.c,v 1.21 2005/09/14 01:13:50 dillon Exp $ + * $DragonFly: src/sys/vfs/union/union_vnops.c,v 1.22 2006/02/17 19:18:08 dillon Exp $ */ #include @@ -1838,22 +1838,22 @@ union_advlock(struct vop_advlock_args *ap) * vnode in its arguments. * This goes away with a merged VM/buffer cache. * - * union_strategy(struct vnode *a_vp, struct buf *a_bp) + * union_strategy(struct vnode *a_vp, struct bio *a_bio) */ static int union_strategy(struct vop_strategy_args *ap) { - struct buf *bp = ap->a_bp; - struct vnode *othervp = OTHERVP(bp->b_vp); + struct bio *bio = ap->a_bio; + struct buf *bp = bio->bio_buf; + struct vnode *othervp = OTHERVP(ap->a_vp); #ifdef DIAGNOSTIC if (othervp == NULLVP) panic("union_strategy: nil vp"); - if (((bp->b_flags & B_READ) == 0) && - (othervp == LOWERVP(bp->b_vp))) + if (((bp->b_flags & B_READ) == 0) && (othervp == LOWERVP(ap->a_vp))) panic("union_strategy: writing to lowervp"); #endif - return (VOP_STRATEGY(othervp, bp)); + return (vn_strategy(othervp, bio)); } /* diff --git a/sys/vm/swap_pager.c b/sys/vm/swap_pager.c index 28dce060a9..e9d6eeee12 100644 --- a/sys/vm/swap_pager.c +++ b/sys/vm/swap_pager.c @@ -96,7 +96,7 @@ * @(#)swap_pager.c 8.9 (Berkeley) 3/21/94 * * $FreeBSD: src/sys/vm/swap_pager.c,v 1.130.2.12 2002/08/31 21:15:55 dillon Exp $ - * $DragonFly: src/sys/vm/swap_pager.c,v 1.17 2005/08/03 16:36:33 hmp Exp $ + * $DragonFly: src/sys/vm/swap_pager.c,v 1.18 2006/02/17 19:18:08 dillon Exp $ */ #include @@ -188,7 +188,8 @@ static void swap_pager_dealloc (vm_object_t object); static int swap_pager_getpages (vm_object_t, vm_page_t *, int, int); static void swap_pager_init (void); static void swap_pager_unswapped (vm_page_t); -static void swap_pager_strategy (vm_object_t, struct buf *); +static void swap_pager_strategy (vm_object_t, struct bio *); +static void swap_chain_iodone(struct bio *biox); struct pagerops swappagerops = { swap_pager_init, /* early system initialization of pager */ @@ -215,8 +216,8 @@ int nswap_lowat = 128; /* in pages, swap_pager_almost_full warn */ int nswap_hiwat = 512; /* in pages, swap_pager_almost_full warn */ static __inline void swp_sizecheck (void); -static void swp_pager_sync_iodone (struct buf *bp); -static void swp_pager_async_iodone (struct buf *bp); +static void swp_pager_sync_iodone (struct bio *bio); +static void swp_pager_async_iodone (struct bio *bio); /* * Swap bitmap functions @@ -839,7 +840,7 @@ swap_pager_unswapped(vm_page_t m) * Therefore we do not maintain any resident pages. All I/O goes * directly to and from the swap device. * - * Note that b_blkno is scaled for PAGE_SIZE + * Note that bio_blkno is scaled for PAGE_SIZE * * We currently attempt to run I/O synchronously or asynchronously as * the caller requests. This isn't perfect because we loose error @@ -848,30 +849,41 @@ swap_pager_unswapped(vm_page_t m) */ static void -swap_pager_strategy(vm_object_t object, struct buf *bp) +swap_pager_strategy(vm_object_t object, struct bio *bio) { + struct buf *bp = bio->bio_buf; + struct bio *nbio; vm_pindex_t start; int count; char *data; - struct buf *nbp = NULL; + struct bio *biox = NULL; + struct buf *bufx = NULL; + struct bio_track *track; + + /* + * tracking for swapdev vnode I/Os + */ + if (bp->b_flags & B_READ) + track = &swapdev_vp->v_track_read; + else + track = &swapdev_vp->v_track_write; if (bp->b_bcount & PAGE_MASK) { bp->b_error = EINVAL; bp->b_flags |= B_ERROR | B_INVAL; - biodone(bp); - printf("swap_pager_strategy: bp %p b_vp %p blk %d size %d, not page bounded\n", bp, bp->b_vp, (int)bp->b_pblkno, (int)bp->b_bcount); + biodone(bio); + printf("swap_pager_strategy: bp %p b_vp %p blk %d size %d, not page bounded\n", bp, bp->b_vp, (int)bio->bio_blkno, (int)bp->b_bcount); return; } /* * Clear error indication, initialize page index, count, data pointer. */ - bp->b_error = 0; bp->b_flags &= ~B_ERROR; bp->b_resid = bp->b_bcount; - start = bp->b_pblkno; + start = bio->bio_blkno; count = howmany(bp->b_bcount, PAGE_SIZE); data = bp->b_data; @@ -880,7 +892,6 @@ swap_pager_strategy(vm_object_t object, struct buf *bp) /* * Deal with B_FREEBUF */ - if (bp->b_flags & B_FREEBUF) { /* * FREE PAGE(s) - destroy underlying swap that is no longer @@ -889,10 +900,23 @@ swap_pager_strategy(vm_object_t object, struct buf *bp) swp_pager_meta_free(object, start, count); crit_exit(); bp->b_resid = 0; - biodone(bp); + biodone(bio); return; } + /* + * We need to be able to create a new cluster of I/O's. We cannot + * use the caller fields of the passed bio so push a new one. + * + * Because nbio is just a placeholder for the cluster links, + * we can biodone() the original bio instead of nbio to make + * things a bit more efficient. + */ + nbio = push_bio(bio); + nbio->bio_blkno = bio->bio_blkno; + nbio->bio_caller_info1.cluster_head = NULL; + nbio->bio_caller_info2.cluster_tail = NULL; + /* * Execute read or write */ @@ -926,29 +950,41 @@ swap_pager_strategy(vm_object_t object, struct buf *bp) */ if ( - nbp && (nbp->b_blkno + btoc(nbp->b_bcount) != blk || - ((nbp->b_blkno ^ blk) & dmmax_mask) + biox && (biox->bio_blkno + btoc(bufx->b_bcount) != blk || + ((biox->bio_blkno ^ blk) & dmmax_mask) ) ) { crit_exit(); if (bp->b_flags & B_READ) { ++mycpu->gd_cnt.v_swapin; - mycpu->gd_cnt.v_swappgsin += btoc(nbp->b_bcount); + mycpu->gd_cnt.v_swappgsin += btoc(bufx->b_bcount); } else { ++mycpu->gd_cnt.v_swapout; - mycpu->gd_cnt.v_swappgsout += btoc(nbp->b_bcount); - nbp->b_dirtyend = nbp->b_bcount; + mycpu->gd_cnt.v_swappgsout += btoc(bufx->b_bcount); + bufx->b_dirtyend = bufx->b_bcount; + } + + /* + * Flush the biox to the swap device. + */ + if (bufx->b_bcount) { + bufx->b_bufsize = bufx->b_bcount; + if ((bufx->b_flags & B_READ) == 0) + bufx->b_dirtyend = bufx->b_bcount; + BUF_KERNPROC(bufx); + vn_strategy(bufx->b_vp, biox); + } else { + biodone(biox); } - flushchainbuf(nbp); crit_enter(); - nbp = NULL; + biox = NULL; + bufx = NULL; } /* - * Add new swapblk to nbp, instantiating nbp if necessary. + * Add new swapblk to biox, instantiating biox if necessary. * Zero-fill reads are able to take a shortcut. */ - if (blk == SWAPBLK_NONE) { /* * We can only get here if we are reading. Since @@ -958,13 +994,23 @@ swap_pager_strategy(vm_object_t object, struct buf *bp) bzero(data, PAGE_SIZE); bp->b_resid -= PAGE_SIZE; } else { - if (nbp == NULL) { - nbp = getchainbuf(bp, swapdev_vp, (bp->b_flags & B_READ) | B_ASYNC); - nbp->b_blkno = blk; - nbp->b_bcount = 0; - nbp->b_data = data; + if (biox == NULL) { + /* XXX chain count > 4, wait to <= 4 */ + + bufx = getpbuf(NULL); + biox = &bufx->b_bio1; + cluster_append(nbio, bufx); + bufx->b_flags = (bufx->b_flags & B_ORDERED) | + (bp->b_flags & B_READ) | + B_ASYNC; + pbgetvp(swapdev_vp, bufx); + biox->bio_done = swap_chain_iodone; + biox->bio_blkno = blk; + biox->bio_caller_info1.cluster_parent = nbio; + bufx->b_bcount = 0; + bufx->b_data = data; } - nbp->b_bcount += PAGE_SIZE; + bufx->b_bcount += PAGE_SIZE; } --count; ++start; @@ -974,35 +1020,120 @@ swap_pager_strategy(vm_object_t object, struct buf *bp) /* * Flush out last buffer */ - crit_exit(); - if (nbp) { + if (biox) { if ((bp->b_flags & B_ASYNC) == 0) - nbp->b_flags &= ~B_ASYNC; - if (nbp->b_flags & B_READ) { + bufx->b_flags &= ~B_ASYNC; + if (bufx->b_flags & B_READ) { ++mycpu->gd_cnt.v_swapin; - mycpu->gd_cnt.v_swappgsin += btoc(nbp->b_bcount); + mycpu->gd_cnt.v_swappgsin += btoc(bufx->b_bcount); } else { ++mycpu->gd_cnt.v_swapout; - mycpu->gd_cnt.v_swappgsout += btoc(nbp->b_bcount); - nbp->b_dirtyend = nbp->b_bcount; + mycpu->gd_cnt.v_swappgsout += btoc(bufx->b_bcount); + bufx->b_dirtyend = bufx->b_bcount; + } + if (bufx->b_bcount) { + bufx->b_bufsize = bufx->b_bcount; + if ((bufx->b_flags & B_READ) == 0) + bufx->b_dirtyend = bufx->b_bcount; + BUF_KERNPROC(bufx); + vn_strategy(bufx->b_vp, biox); + } else { + biodone(biox); } - flushchainbuf(nbp); - /* nbp = NULL; */ + /* biox, bufx = NULL */ } /* * Wait for completion. */ - if (bp->b_flags & B_ASYNC) { - autochaindone(bp); + crit_enter(); + if (nbio->bio_caller_info1.cluster_head == NULL) { + biodone(bio); + } else { + bp->b_xflags |= BX_AUTOCHAINDONE; + } + crit_exit(); } else { - waitchainbuf(bp, 0, 1); + crit_enter(); + while (nbio->bio_caller_info1.cluster_head != NULL) { + bp->b_flags |= B_WANT; + tsleep(bp, 0, "bpchain", 0); + } + if (bp->b_resid != 0 && !(bp->b_flags & B_ERROR)) { + bp->b_flags |= B_ERROR; + bp->b_error = EINVAL; + } + biodone(bio); + crit_exit(); } } +static void +swap_chain_iodone(struct bio *biox) +{ + struct buf **nextp; + struct buf *bufx; /* chained sub-buffer */ + struct bio *nbio; /* parent nbio with chain glue */ + struct buf *bp; /* original bp associated with nbio */ + + bufx = biox->bio_buf; + nbio = biox->bio_caller_info1.cluster_parent; + bp = nbio->bio_buf; + + /* + * Update the original buffer + */ + KKASSERT(bp != NULL); + if (bufx->b_flags & B_ERROR) { + bp->b_flags |= B_ERROR; + bp->b_error = bufx->b_error; + } else if (bufx->b_resid != 0) { + bp->b_flags |= B_ERROR; + bp->b_error = EINVAL; + } else { + bp->b_resid -= bufx->b_bcount; + } + + /* + * Remove us from the chain. It is sufficient to clean up + * cluster_head. We do not have to clean up cluster_tail. + */ + nextp = &nbio->bio_caller_info1.cluster_head; + while (*nextp != bufx) { + KKASSERT(*nextp != NULL); + nextp = &(*nextp)->b_cluster_next; + } + *nextp = bufx->b_cluster_next; + if (bp->b_flags & B_WANT) { + bp->b_flags &= ~B_WANT; + wakeup(bp); + } + + /* + * Clean up bufx. If this was the last buffer in the chain + * and BX_AUTOCHAINDONE was set, finish off the original I/O + * as well. + * + * nbio was just a fake BIO layer to hold the cluster links, + * we can issue the biodone() on the layer above it. + */ + if (nbio->bio_caller_info1.cluster_head == NULL && + (bp->b_xflags & BX_AUTOCHAINDONE)) { + bp->b_xflags &= ~BX_AUTOCHAINDONE; + if (bp->b_resid != 0 && !(bp->b_flags & B_ERROR)) { + bp->b_flags |= B_ERROR; + bp->b_error = EINVAL; + } + biodone(nbio->bio_prev); + } + bufx->b_flags |= B_DONE; + bufx->b_flags &= ~B_ASYNC; + relpbuf(bufx, NULL); +} + /* * SWAP_PAGER_GETPAGES() - bring pages in from swap * @@ -1027,6 +1158,7 @@ static int swap_pager_getpages(vm_object_t object, vm_page_t *m, int count, int reqpage) { struct buf *bp; + struct bio *bio; vm_page_t mreq; int i; int j; @@ -1106,6 +1238,7 @@ swap_pager_getpages(vm_object_t object, vm_page_t *m, int count, int reqpage) */ bp = getpbuf(&nsw_rcount); + bio = &bp->b_bio1; kva = (vm_offset_t) bp->b_data; /* @@ -1117,12 +1250,12 @@ swap_pager_getpages(vm_object_t object, vm_page_t *m, int count, int reqpage) pmap_qenter(kva, m + i, j - i); bp->b_flags = B_READ; - bp->b_iodone = swp_pager_async_iodone; bp->b_data = (caddr_t) kva; - bp->b_blkno = blk - (reqpage - i); bp->b_bcount = PAGE_SIZE * (j - i); bp->b_bufsize = PAGE_SIZE * (j - i); - bp->b_pager.pg_reqpage = reqpage - i; + bio->bio_done = swp_pager_async_iodone; + bio->bio_blkno = blk - (reqpage - i); + bio->bio_driver_info = (void *)(reqpage - i); { int k; @@ -1156,11 +1289,12 @@ swap_pager_getpages(vm_object_t object, vm_page_t *m, int count, int reqpage) * The other pages in our m[] array are also released on completion, * so we cannot assume they are valid anymore either. * - * NOTE: b_blkno is destroyed by the call to VOP_STRATEGY + * NOTE: bio_blkno may be destroyed by the call to vn_strategy() + * XXX should not be, any more. */ BUF_KERNPROC(bp); - VOP_STRATEGY(bp->b_vp, bp); + vn_strategy(swapdev_vp, bio); /* * wait for the page we want to complete. PG_SWAPINPROG is always @@ -1175,10 +1309,9 @@ swap_pager_getpages(vm_object_t object, vm_page_t *m, int count, int reqpage) mycpu->gd_cnt.v_intrans++; if (tsleep(mreq, 0, "swread", hz*20)) { printf( - "swap_pager: indefinite wait buffer: device:" - " %s, blkno: %ld, size: %ld\n", - devtoname(bp->b_dev), (long)bp->b_blkno, - bp->b_bcount + "swap_pager: indefinite wait buffer: " + " blkno: %ld, size: %ld\n", + (long)bio->bio_blkno, bp->b_bcount ); } } @@ -1213,7 +1346,7 @@ swap_pager_getpages(vm_object_t object, vm_page_t *m, int count, int reqpage) * We support both OBJT_DEFAULT and OBJT_SWAP objects. DEFAULT objects * are automatically converted to SWAP objects. * - * In a low memory situation we may block in VOP_STRATEGY(), but the new + * In a low memory situation we may block in vn_strategy(), but the new * vm_page reservation system coupled with properly written VFS devices * should ensure that no low-memory deadlock occurs. This is an area * which needs work. @@ -1298,9 +1431,10 @@ swap_pager_putpages(vm_object_t object, vm_page_t *m, int count, boolean_t sync, */ for (i = 0; i < count; i += n) { - int j; struct buf *bp; + struct bio *bio; daddr_t blk; + int j; /* * Maximum I/O size is limited by a number of factors. @@ -1354,13 +1488,13 @@ swap_pager_putpages(vm_object_t object, vm_page_t *m, int count, boolean_t sync, bp = getpbuf(&nsw_wcount_async); bp->b_flags = B_ASYNC; } - bp->b_spc = NULL; /* not used, but NULL-out anyway */ + bio = &bp->b_bio1; pmap_qenter((vm_offset_t)bp->b_data, &m[i], n); bp->b_bcount = PAGE_SIZE * n; bp->b_bufsize = PAGE_SIZE * n; - bp->b_blkno = blk; + bio->bio_blkno = blk; pbgetvp(swapdev_vp, bp); @@ -1387,20 +1521,20 @@ swap_pager_putpages(vm_object_t object, vm_page_t *m, int count, boolean_t sync, mycpu->gd_cnt.v_swapout++; mycpu->gd_cnt.v_swappgsout += bp->b_xio.xio_npages; - swapdev_vp->v_numoutput++; crit_exit(); /* * asynchronous * - * NOTE: b_blkno is destroyed by the call to VOP_STRATEGY + * NOTE: bio_blkno is destroyed by the call to vn_strategy() + * XXX it should not be destroyed any more */ if (sync == FALSE) { - bp->b_iodone = swp_pager_async_iodone; + bio->bio_done = swp_pager_async_iodone; BUF_KERNPROC(bp); - VOP_STRATEGY(bp->b_vp, bp); + vn_strategy(swapdev_vp, bio); for (j = 0; j < n; ++j) rtvals[i+j] = VM_PAGER_PEND; @@ -1410,11 +1544,12 @@ swap_pager_putpages(vm_object_t object, vm_page_t *m, int count, boolean_t sync, /* * synchronous * - * NOTE: b_blkno is destroyed by the call to VOP_STRATEGY + * NOTE: bio_blkno is destroyed by the call to vn_strategy() + * XXX it should not be destroyed any more */ - bp->b_iodone = swp_pager_sync_iodone; - VOP_STRATEGY(bp->b_vp, bp); + bio->bio_done = swp_pager_sync_iodone; + vn_strategy(swapdev_vp, bio); /* * Wait for the sync I/O to complete, then update rtvals. @@ -1436,7 +1571,7 @@ swap_pager_putpages(vm_object_t object, vm_page_t *m, int count, boolean_t sync, * normal async completion, which frees everything up. */ - swp_pager_async_iodone(bp); + swp_pager_async_iodone(bio); crit_exit(); } @@ -1452,8 +1587,10 @@ swap_pager_putpages(vm_object_t object, vm_page_t *m, int count, boolean_t sync, */ static void -swp_pager_sync_iodone(struct buf *bp) +swp_pager_sync_iodone(struct bio *bio) { + struct buf *bp = bio->bio_buf; + bp->b_flags |= B_DONE; bp->b_flags &= ~B_ASYNC; wakeup(bp); @@ -1472,17 +1609,14 @@ swp_pager_sync_iodone(struct buf *bp) * because we marked them all VM_PAGER_PEND on return from putpages ). * * This routine may not block. - * This routine is called at splbio() or better - * - * We up ourselves to splvm() as required for various vm_page related - * calls. */ static void -swp_pager_async_iodone(struct buf *bp) +swp_pager_async_iodone(struct bio *bio) { - int i; + struct buf *bp = bio->bio_buf; vm_object_t object = NULL; + int i; bp->b_flags |= B_DONE; @@ -1495,7 +1629,7 @@ swp_pager_async_iodone(struct buf *bp) "swap_pager: I/O error - %s failed; blkno %ld," "size %ld, error %d\n", ((bp->b_flags & B_READ) ? "pagein" : "pageout"), - (long)bp->b_blkno, + (long)bio->bio_blkno, (long)bp->b_bcount, bp->b_error ); @@ -1563,7 +1697,11 @@ swp_pager_async_iodone(struct buf *bp) m->valid = 0; vm_page_flag_clear(m, PG_ZERO); - if (i != bp->b_pager.pg_reqpage) + /* + * bio_driver_info holds the requested page + * index. + */ + if (i != (int)bio->bio_driver_info) vm_page_free(m); else vm_page_flash(m); @@ -1618,8 +1756,10 @@ swp_pager_async_iodone(struct buf *bp) * be sure to not unbusy getpages specifically * requested page - getpages expects it to be * left busy. + * + * bio_driver_info holds the requested page */ - if (i != bp->b_pager.pg_reqpage) { + if (i != (int)bio->bio_driver_info) { vm_page_deactivate(m); vm_page_wakeup(m); } else { diff --git a/sys/vm/vm_pager.c b/sys/vm/vm_pager.c index 97407785ce..20d23eae82 100644 --- a/sys/vm/vm_pager.c +++ b/sys/vm/vm_pager.c @@ -62,7 +62,7 @@ * rights to redistribute these changes. * * $FreeBSD: src/sys/vm/vm_pager.c,v 1.54.2.2 2001/11/18 07:11:00 dillon Exp $ - * $DragonFly: src/sys/vm/vm_pager.c,v 1.15 2005/08/08 16:53:12 hmp Exp $ + * $DragonFly: src/sys/vm/vm_pager.c,v 1.16 2006/02/17 19:18:08 dillon Exp $ */ /* @@ -256,14 +256,17 @@ vm_pager_deallocate(vm_object_t object) */ void -vm_pager_strategy(vm_object_t object, struct buf *bp) +vm_pager_strategy(vm_object_t object, struct bio *bio) { + struct buf *bp; + if (pagertab[object->type]->pgo_strategy) { - (*pagertab[object->type]->pgo_strategy)(object, bp); + (*pagertab[object->type]->pgo_strategy)(object, bio); } else { + bp = bio->bio_buf; bp->b_flags |= B_ERROR; bp->b_error = ENXIO; - biodone(bp); + biodone(bio); } } @@ -320,6 +323,7 @@ initpbuf(struct buf *bp) bp->b_xflags = 0; bp->b_flags = 0; bp->b_error = 0; + initbufbio(bp); xio_init(&bp->b_xio); BUF_LOCK(bp, LK_EXCLUSIVE); } @@ -426,128 +430,3 @@ relpbuf(struct buf *bp, int *pfreecnt) crit_exit(); } -/******************************************************** - * CHAINING FUNCTIONS * - ******************************************************** - * - * These functions support recursion of I/O operations - * on bp's, typically by chaining one or more 'child' bp's - * to the parent. Synchronous, asynchronous, and semi-synchronous - * chaining is possible. - */ - -/* - * vm_pager_chain_iodone: - * - * io completion routine for child bp. Currently we fudge a bit - * on dealing with b_resid. Since users of these routines may issue - * multiple children simultaniously, sequencing of the error can be lost. - */ - -static void -vm_pager_chain_iodone(struct buf *nbp) -{ - struct buf *bp; - - if ((bp = nbp->b_chain.parent) != NULL) { - if (nbp->b_flags & B_ERROR) { - bp->b_flags |= B_ERROR; - bp->b_error = nbp->b_error; - } else if (nbp->b_resid != 0) { - bp->b_flags |= B_ERROR; - bp->b_error = EINVAL; - } else { - bp->b_resid -= nbp->b_bcount; - } - nbp->b_chain.parent = NULL; - --bp->b_chain.count; - if (bp->b_flags & B_WANT) { - bp->b_flags &= ~B_WANT; - wakeup(bp); - } - if (!bp->b_chain.count && (bp->b_xflags & BX_AUTOCHAINDONE)) { - bp->b_xflags &= ~BX_AUTOCHAINDONE; - if (bp->b_resid != 0 && !(bp->b_flags & B_ERROR)) { - bp->b_flags |= B_ERROR; - bp->b_error = EINVAL; - } - biodone(bp); - } - } - nbp->b_flags |= B_DONE; - nbp->b_flags &= ~B_ASYNC; - relpbuf(nbp, NULL); -} - -/* - * getchainbuf: - * - * Obtain a physical buffer and chain it to its parent buffer. When - * I/O completes, the parent buffer will be B_SIGNAL'd. Errors are - * automatically propogated to the parent - * - * Since these are brand new buffers, we do not have to clear B_INVAL - * and B_ERROR because they are already clear. - */ - -struct buf * -getchainbuf(struct buf *bp, struct vnode *vp, int flags) -{ - struct buf *nbp = getpbuf(NULL); - - nbp->b_chain.parent = bp; - ++bp->b_chain.count; - - if (bp->b_chain.count > 4) - waitchainbuf(bp, 4, 0); - - nbp->b_flags = (bp->b_flags & B_ORDERED) | flags; - nbp->b_iodone = vm_pager_chain_iodone; - - if (vp) - pbgetvp(vp, nbp); - return(nbp); -} - -void -flushchainbuf(struct buf *nbp) -{ - if (nbp->b_bcount) { - nbp->b_bufsize = nbp->b_bcount; - if ((nbp->b_flags & B_READ) == 0) - nbp->b_dirtyend = nbp->b_bcount; - BUF_KERNPROC(nbp); - VOP_STRATEGY(nbp->b_vp, nbp); - } else { - biodone(nbp); - } -} - -void -waitchainbuf(struct buf *bp, int count, int done) -{ - crit_enter(); - while (bp->b_chain.count > count) { - bp->b_flags |= B_WANT; - tsleep(bp, 0, "bpchain", 0); - } - if (done) { - if (bp->b_resid != 0 && !(bp->b_flags & B_ERROR)) { - bp->b_flags |= B_ERROR; - bp->b_error = EINVAL; - } - biodone(bp); - } - crit_exit(); -} - -void -autochaindone(struct buf *bp) -{ - crit_enter(); - if (bp->b_chain.count == 0) - biodone(bp); - else - bp->b_xflags |= BX_AUTOCHAINDONE; - crit_exit(); -} diff --git a/sys/vm/vm_pager.h b/sys/vm/vm_pager.h index 800f57bb2e..12e1e2c50f 100644 --- a/sys/vm/vm_pager.h +++ b/sys/vm/vm_pager.h @@ -37,7 +37,7 @@ * * @(#)vm_pager.h 8.4 (Berkeley) 1/12/94 * $FreeBSD: src/sys/vm/vm_pager.h,v 1.24.2.2 2002/12/31 09:34:51 dillon Exp $ - * $DragonFly: src/sys/vm/vm_pager.h,v 1.5 2005/01/23 13:24:20 joerg Exp $ + * $DragonFly: src/sys/vm/vm_pager.h,v 1.6 2006/02/17 19:18:08 dillon Exp $ */ /* @@ -52,6 +52,7 @@ TAILQ_HEAD(pagerlst, vm_object); struct buf; +struct bio; struct pagerops { void (*pgo_init) (void); /* Initialize pager. */ @@ -61,7 +62,7 @@ struct pagerops { void (*pgo_putpages) (vm_object_t, vm_page_t *, int, int, int *); /* Put (write) page. */ boolean_t (*pgo_haspage) (vm_object_t, vm_pindex_t, int *, int *); /* Does pager have page? */ void (*pgo_pageunswapped) (vm_page_t); - void (*pgo_strategy) (vm_object_t, struct buf *); + void (*pgo_strategy) (vm_object_t, struct bio *); }; /* @@ -105,7 +106,7 @@ static __inline boolean_t vm_pager_has_page (vm_object_t, vm_pindex_t, int *, in void vm_pager_init (void); vm_object_t vm_pager_object_lookup (struct pagerlst *, void *); void vm_pager_sync (void); -void vm_pager_strategy (vm_object_t object, struct buf *bp); +void vm_pager_strategy (vm_object_t object, struct bio *bio); struct buf *getchainbuf(struct buf *bp, struct vnode *vp, int flags); void flushchainbuf(struct buf *nbp); void waitchainbuf(struct buf *bp, int count, int done); diff --git a/sys/vm/vm_swap.c b/sys/vm/vm_swap.c index 544ffd333f..2486b390aa 100644 --- a/sys/vm/vm_swap.c +++ b/sys/vm/vm_swap.c @@ -32,7 +32,7 @@ * * @(#)vm_swap.c 8.5 (Berkeley) 2/17/94 * $FreeBSD: src/sys/vm/vm_swap.c,v 1.96.2.2 2001/10/14 18:46:47 iedowse Exp $ - * $DragonFly: src/sys/vm/vm_swap.c,v 1.20 2006/01/13 20:45:30 swildner Exp $ + * $DragonFly: src/sys/vm/vm_swap.c,v 1.21 2006/02/17 19:18:08 dillon Exp $ */ #include "opt_swap.h" @@ -76,24 +76,25 @@ struct vnode *swapdev_vp; /* * swapdev_strategy: * - * VOP_STRATEGY() for swapdev_vp. + * vn_strategy() for swapdev_vp. * Perform swap strategy interleave device selection. * * The bp is expected to be locked and *not* B_DONE on call. + * + * (struct vnode *a_vp, struct bio *b_bio) */ static int -swapdev_strategy(struct vop_strategy_args /* { - struct vnode *a_vp; - struct buf *a_bp; - } */ *ap) +swapdev_strategy(struct vop_strategy_args *ap) { + struct bio *bio = ap->a_bio; + struct bio *nbio; + struct buf *bp = bio->bio_buf; int sz, off, seg, index; struct swdevt *sp; struct vnode *vp; - struct buf *bp; - bp = ap->a_bp; + vp = ap->a_vp; sz = howmany(bp->b_bcount, PAGE_SIZE); /* @@ -101,63 +102,56 @@ swapdev_strategy(struct vop_strategy_args /* { * the block size is left in PAGE_SIZE'd chunks (for the newswap) * here. */ + nbio = push_bio(bio); if (nswdev > 1) { - off = bp->b_blkno % dmmax; + off = bio->bio_blkno % dmmax; if (off + sz > dmmax) { bp->b_error = EINVAL; bp->b_flags |= B_ERROR; - biodone(bp); + biodone(bio); return 0; } - seg = bp->b_blkno / dmmax; + seg = bio->bio_blkno / dmmax; index = seg % nswdev; seg /= nswdev; - bp->b_blkno = seg * dmmax + off; + nbio->bio_blkno = seg * dmmax + off; } else { index = 0; + nbio->bio_blkno = bio->bio_blkno; } sp = &swdevt[index]; - if (bp->b_blkno + sz > sp->sw_nblks) { + if (nbio->bio_blkno + sz > sp->sw_nblks) { bp->b_error = EINVAL; bp->b_flags |= B_ERROR; - biodone(bp); + /* I/O was never started on nbio, must biodone(bio) */ + biodone(bio); return 0; } - bp->b_dev = sp->sw_device; if (sp->sw_vp == NULL) { bp->b_error = ENODEV; bp->b_flags |= B_ERROR; - biodone(bp); + /* I/O was never started on nbio, must biodone(bio) */ + biodone(bio); return 0; } /* - * Convert from PAGE_SIZE'd to DEV_BSIZE'd chunks for the actual I/O + * Convert from PAGE_SIZE'd to DEV_BSIZE'd chunks for the actual I/O. + * Issue a strategy call on the appropriate swap vnode. Note that + * bp->b_vp is not modified. Strategy code is always supposed to + * use the passed vp. + * + * XXX do a dev_dstrategy() call on sp->sw_device instead of on + * sp->sw_vp ? */ - bp->b_blkno = ctodb(bp->b_blkno); - - vhold(sp->sw_vp); - crit_enter(); - if ((bp->b_flags & B_READ) == 0) { - vp = bp->b_vp; - if (vp) { - vp->v_numoutput--; - if ((vp->v_flag & VBWAIT) && vp->v_numoutput <= 0) { - vp->v_flag &= ~VBWAIT; - wakeup(&vp->v_numoutput); - } - } - sp->sw_vp->v_numoutput++; - } - pbreassignbuf(bp, sp->sw_vp); - crit_exit(); - VOP_STRATEGY(bp->b_vp, bp); + nbio->bio_blkno = ctodb(nbio->bio_blkno); + vn_strategy(sp->sw_vp, nbio); return 0; } /* * Create a special vnode op vector for swapdev_vp - we only use - * VOP_STRATEGY(), everything else returns an error. + * vn_strategy(), everything else returns an error. */ struct vop_ops *swapdev_vnode_vops; static struct vnodeopv_entry_desc swapdev_vnodeop_entries[] = { diff --git a/sys/vm/vnode_pager.c b/sys/vm/vnode_pager.c index 9f2da08576..939788ce21 100644 --- a/sys/vm/vnode_pager.c +++ b/sys/vm/vnode_pager.c @@ -39,7 +39,7 @@ * * from: @(#)vnode_pager.c 7.5 (Berkeley) 4/20/91 * $FreeBSD: src/sys/vm/vnode_pager.c,v 1.116.2.7 2002/12/31 09:34:51 dillon Exp $ - * $DragonFly: src/sys/vm/vnode_pager.c,v 1.20 2005/08/03 16:36:33 hmp Exp $ + * $DragonFly: src/sys/vm/vnode_pager.c,v 1.21 2006/02/17 19:18:08 dillon Exp $ */ /* @@ -74,7 +74,7 @@ static vm_offset_t vnode_pager_addr (struct vnode *vp, vm_ooffset_t address, int *run); -static void vnode_pager_iodone (struct buf *bp); +static void vnode_pager_iodone (struct bio *bio); static int vnode_pager_input_smlfs (vm_object_t object, vm_page_t m); static int vnode_pager_input_old (vm_object_t object, vm_page_t m); static void vnode_pager_dealloc (vm_object_t); @@ -401,8 +401,10 @@ vnode_pager_addr(struct vnode *vp, vm_ooffset_t address, int *run) * interrupt routine for I/O completion */ static void -vnode_pager_iodone(struct buf *bp) +vnode_pager_iodone(struct bio *bio) { + struct buf *bp = bio->bio_buf; + bp->b_flags |= B_DONE; wakeup(bp); } @@ -451,9 +453,9 @@ vnode_pager_input_smlfs(vm_object_t object, vm_page_t m) /* build a minimal buffer header */ bp->b_flags = B_READ; - bp->b_iodone = vnode_pager_iodone; bp->b_data = (caddr_t) kva + i * bsize; - bp->b_blkno = fileaddr; + bp->b_bio1.bio_done = vnode_pager_iodone; + bp->b_bio1.bio_blkno = fileaddr; pbgetvp(dp, bp); bp->b_bcount = bsize; bp->b_bufsize = bsize; @@ -461,7 +463,7 @@ vnode_pager_input_smlfs(vm_object_t object, vm_page_t m) runningbufspace += bp->b_runningbufspace; /* do the input */ - VOP_STRATEGY(bp->b_vp, bp); + vn_strategy(dp, &bp->b_bio1); /* we definitely need to be at splvm here */ @@ -765,9 +767,8 @@ vnode_pager_generic_getpages(struct vnode *vp, vm_page_t *m, int bytecount, /* build a minimal buffer header */ bp->b_flags = B_READ; - bp->b_iodone = vnode_pager_iodone; - /* B_PHYS is not set, but it is nice to fill this in */ - bp->b_blkno = firstaddr; + bp->b_bio1.bio_done = vnode_pager_iodone; + bp->b_bio1.bio_blkno = firstaddr; pbgetvp(dp, bp); bp->b_bcount = size; bp->b_bufsize = size; @@ -778,7 +779,7 @@ vnode_pager_generic_getpages(struct vnode *vp, vm_page_t *m, int bytecount, mycpu->gd_cnt.v_vnodepgsin += count; /* do the input */ - VOP_STRATEGY(bp->b_vp, bp); + vn_strategy(dp, &bp->b_bio1); crit_enter(); /* we definitely need to be at splvm here */ -- 2.41.0