diff options
-rw-r--r-- | libexec/rpc.rstatd/rstat_proc.c | 6 | ||||
-rw-r--r-- | sys/arch/sparc/dev/fd.c | 7 | ||||
-rw-r--r-- | sys/arch/sparc/dev/xd.c | 8 | ||||
-rw-r--r-- | sys/arch/sparc/dev/xy.c | 8 | ||||
-rw-r--r-- | sys/arch/vax/mba/hp.c | 5 | ||||
-rw-r--r-- | sys/arch/vax/mscp/mscp_disk.c | 12 | ||||
-rw-r--r-- | sys/dev/ata/wd.c | 5 | ||||
-rw-r--r-- | sys/dev/ccd.c | 5 | ||||
-rw-r--r-- | sys/dev/isa/fd.c | 7 | ||||
-rw-r--r-- | sys/dev/isa/mcd.c | 4 | ||||
-rw-r--r-- | sys/dev/ofw/ofdisk.c | 5 | ||||
-rw-r--r-- | sys/dev/raidframe/rf_openbsdkintf.c | 5 | ||||
-rw-r--r-- | sys/dev/vnd.c | 22 | ||||
-rw-r--r-- | sys/kern/kern_sysctl.c | 18 | ||||
-rw-r--r-- | sys/kern/subr_disk.c | 24 | ||||
-rw-r--r-- | sys/scsi/cd.c | 7 | ||||
-rw-r--r-- | sys/scsi/sd.c | 7 | ||||
-rw-r--r-- | sys/sys/disk.h | 19 | ||||
-rw-r--r-- | usr.bin/systat/iostat.c | 12 | ||||
-rw-r--r-- | usr.bin/systat/vmstat.c | 10 | ||||
-rw-r--r-- | usr.bin/vmstat/dkstats.c | 117 | ||||
-rw-r--r-- | usr.bin/vmstat/dkstats.h | 8 | ||||
-rw-r--r-- | usr.bin/vmstat/vmstat.c | 7 | ||||
-rw-r--r-- | usr.sbin/iostat/iostat.c | 19 |
24 files changed, 217 insertions, 130 deletions
diff --git a/libexec/rpc.rstatd/rstat_proc.c b/libexec/rpc.rstatd/rstat_proc.c index 7cb62534b70..5a085f9250a 100644 --- a/libexec/rpc.rstatd/rstat_proc.c +++ b/libexec/rpc.rstatd/rstat_proc.c @@ -1,4 +1,4 @@ -/* $OpenBSD: rstat_proc.c,v 1.24 2003/07/29 18:39:23 deraadt Exp $ */ +/* $OpenBSD: rstat_proc.c,v 1.25 2004/02/15 02:45:47 tedu Exp $ */ /* * Sun RPC is a product of Sun Microsystems, Inc. and is provided for @@ -31,7 +31,7 @@ #ifndef lint /*static char sccsid[] = "from: @(#)rpc.rstatd.c 1.1 86/09/25 Copyr 1984 Sun Micro";*/ /*static char sccsid[] = "from: @(#)rstat_proc.c 2.2 88/08/01 4.0 RPCSRC";*/ -static char rcsid[] = "$OpenBSD: rstat_proc.c,v 1.24 2003/07/29 18:39:23 deraadt Exp $"; +static char rcsid[] = "$OpenBSD: rstat_proc.c,v 1.25 2004/02/15 02:45:47 tedu Exp $"; #endif /* @@ -202,7 +202,7 @@ updatestat(void) dkreadstats(); memset(stats_all.s1.dk_xfer, '\0', sizeof(stats_all.s1.dk_xfer)); for (i = 0; i < dk_ndrive && i < DK_NDRIVE; i++) - stats_all.s1.dk_xfer[i] = cur.dk_xfer[i]; + stats_all.s1.dk_xfer[i] = cur.dk_rxfer[i] + cur.dk_wxfer[i]; for (i = 0; i < CPUSTATES; i++) stats_all.s1.cp_time[i] = cp_time[cp_xlat[i]]; diff --git a/sys/arch/sparc/dev/fd.c b/sys/arch/sparc/dev/fd.c index 99de2dfe043..64b520ad889 100644 --- a/sys/arch/sparc/dev/fd.c +++ b/sys/arch/sparc/dev/fd.c @@ -1,4 +1,4 @@ -/* $OpenBSD: fd.c,v 1.34 2004/01/12 11:35:08 jmc Exp $ */ +/* $OpenBSD: fd.c,v 1.35 2004/02/15 02:45:46 tedu Exp $ */ /* $NetBSD: fd.c,v 1.51 1997/05/24 20:16:19 pk Exp $ */ /*- @@ -1363,7 +1363,7 @@ loop: } /*FALLTHROUGH*/ case SEEKCOMPLETE: - disk_unbusy(&fd->sc_dk, 0); /* no data on seek */ + disk_unbusy(&fd->sc_dk, 0, 0); /* no data on seek */ /* Make sure seek really happened. */ if (fdc->sc_nstat != 2 || (st0 & 0xf8) != 0x20 || @@ -1391,7 +1391,8 @@ loop: case IOCOMPLETE: /* IO DONE, post-analyze */ timeout_del(&fdc->fdctimeout_to); - disk_unbusy(&fd->sc_dk, (bp->b_bcount - bp->b_resid)); + disk_unbusy(&fd->sc_dk, (bp->b_bcount - bp->b_resid), + (bp->b_flags & B_READ)); if (fdc->sc_nstat != 7 || st1 != 0 || ((st0 & 0xf8) != 0 && diff --git a/sys/arch/sparc/dev/xd.c b/sys/arch/sparc/dev/xd.c index 447a4dae08b..cf175036bd7 100644 --- a/sys/arch/sparc/dev/xd.c +++ b/sys/arch/sparc/dev/xd.c @@ -1,4 +1,4 @@ -/* $OpenBSD: xd.c,v 1.27 2004/01/12 11:35:08 jmc Exp $ */ +/* $OpenBSD: xd.c,v 1.28 2004/02/15 02:45:46 tedu Exp $ */ /* $NetBSD: xd.c,v 1.37 1997/07/29 09:58:16 fair Exp $ */ /* @@ -1738,7 +1738,8 @@ xdc_reset(xdcsc, quiet, blastmode, error, xdsc) iorq->buf->b_bcount); disk_unbusy(&xdcsc->reqs[lcv].xd->sc_dk, (xdcsc->reqs[lcv].buf->b_bcount - - xdcsc->reqs[lcv].buf->b_resid)); + xdcsc->reqs[lcv].buf->b_resid), + (xdcsc->reqs[lcv].buf->b_flags & B_READ)); biodone(iorq->buf); XDC_FREE(xdcsc, lcv); /* add to free list */ break; @@ -1943,7 +1944,8 @@ xdc_remove_iorq(xdcsc) (vaddr_t) bp->b_un.b_addr, bp->b_bcount); disk_unbusy(&iorq->xd->sc_dk, - (bp->b_bcount - bp->b_resid)); + (bp->b_bcount - bp->b_resid), + (bp->b_flags & B_READ)); XDC_FREE(xdcsc, rqno); biodone(bp); break; diff --git a/sys/arch/sparc/dev/xy.c b/sys/arch/sparc/dev/xy.c index 29411e8da2d..f651417287a 100644 --- a/sys/arch/sparc/dev/xy.c +++ b/sys/arch/sparc/dev/xy.c @@ -1,4 +1,4 @@ -/* $OpenBSD: xy.c,v 1.23 2003/09/29 09:08:19 miod Exp $ */ +/* $OpenBSD: xy.c,v 1.24 2004/02/15 02:45:46 tedu Exp $ */ /* $NetBSD: xy.c,v 1.26 1997/07/19 21:43:56 pk Exp $ */ /* @@ -1644,7 +1644,8 @@ xyc_reset(xycsc, quiet, blastmode, error, xysc) iorq->xy->xyq.b_actf = iorq->buf->b_actf; disk_unbusy(&xycsc->reqs[lcv].xy->sc_dk, (xycsc->reqs[lcv].buf->b_bcount - - xycsc->reqs[lcv].buf->b_resid)); + xycsc->reqs[lcv].buf->b_resid), + (xycsc->reqs[lcv].buf->b_flags & B_READ)); biodone(iorq->buf); iorq->mode = XY_SUB_FREE; break; @@ -1821,7 +1822,8 @@ xyc_remove_iorq(xycsc) bp->b_bcount); iorq->xy->xyq.b_actf = bp->b_actf; disk_unbusy(&iorq->xy->sc_dk, - (bp->b_bcount - bp->b_resid)); + (bp->b_bcount - bp->b_resid), + (bp->b_flags & B_READ)); iorq->mode = XY_SUB_FREE; biodone(bp); break; diff --git a/sys/arch/vax/mba/hp.c b/sys/arch/vax/mba/hp.c index d156a49a41e..e0f8a55521d 100644 --- a/sys/arch/vax/mba/hp.c +++ b/sys/arch/vax/mba/hp.c @@ -1,4 +1,4 @@ -/* $OpenBSD: hp.c,v 1.14 2003/04/06 22:01:41 miod Exp $ */ +/* $OpenBSD: hp.c,v 1.15 2004/02/15 02:45:46 tedu Exp $ */ /* $NetBSD: hp.c,v 1.22 2000/02/12 16:09:33 ragge Exp $ */ /* * Copyright (c) 1996 Ludd, University of Lule}, Sweden. @@ -416,7 +416,8 @@ hper2: sc->sc_dev.dv_xname, mbasr); BUFQ_FIRST(&md->md_q)->b_resid = 0; - disk_unbusy(&sc->sc_disk, BUFQ_FIRST(&md->md_q)->b_bcount); + disk_unbusy(&sc->sc_disk, BUFQ_FIRST(&md->md_q)->b_bcount, + (BUFQ_FIRST(&md->md_q)->b_flags & B_READ)); return XFER_FINISH; } diff --git a/sys/arch/vax/mscp/mscp_disk.c b/sys/arch/vax/mscp/mscp_disk.c index 5e54596af1f..8b059ea14fd 100644 --- a/sys/arch/vax/mscp/mscp_disk.c +++ b/sys/arch/vax/mscp/mscp_disk.c @@ -1,4 +1,4 @@ -/* $OpenBSD: mscp_disk.c,v 1.13 2003/06/02 23:27:57 millert Exp $ */ +/* $OpenBSD: mscp_disk.c,v 1.14 2004/02/15 02:45:46 tedu Exp $ */ /* $NetBSD: mscp_disk.c,v 1.30 2001/11/13 07:38:28 lukem Exp $ */ /* * Copyright (c) 1996 Ludd, University of Lule}, Sweden. @@ -324,8 +324,9 @@ rastrategy(bp) goto done; /* Make some statistics... /bqt */ - ra->ra_disk.dk_xfer++; - ra->ra_disk.dk_bytes += bp->b_bcount; + s = splbio(); + disk_busy(&ra->ra_disk); + splx(s); mscp_strategy(bp, ra->ra_dev.dv_parent); return; @@ -707,8 +708,9 @@ rxstrategy(bp) } /* Make some statistics... /bqt */ - rx->ra_disk.dk_xfer++; - rx->ra_disk.dk_bytes += bp->b_bcount; + s = splbio(); + disk_busy(&rx->ra_disk); + splx(s); mscp_strategy(bp, rx->ra_dev.dv_parent); return; diff --git a/sys/dev/ata/wd.c b/sys/dev/ata/wd.c index bb65c803715..79b39710eb8 100644 --- a/sys/dev/ata/wd.c +++ b/sys/dev/ata/wd.c @@ -1,4 +1,4 @@ -/* $OpenBSD: wd.c,v 1.38 2004/02/02 21:29:38 tedu Exp $ */ +/* $OpenBSD: wd.c,v 1.39 2004/02/15 02:45:47 tedu Exp $ */ /* $NetBSD: wd.c,v 1.193 1999/02/28 17:15:27 explorer Exp $ */ /* @@ -648,7 +648,8 @@ noerror: if ((wd->sc_wdc_bio.flags & ATA_CORR) || wd->retries > 0) printf("%s: soft error (corrected)\n", wd->sc_dev.dv_xname); } - disk_unbusy(&wd->sc_dk, (bp->b_bcount - bp->b_resid)); + disk_unbusy(&wd->sc_dk, (bp->b_bcount - bp->b_resid), + (bp->b_flags & B_READ)); #if NRND > 0 rnd_add_uint32(&wd->rnd_source, bp->b_blkno); #endif diff --git a/sys/dev/ccd.c b/sys/dev/ccd.c index eaac7b55473..9d1740c3657 100644 --- a/sys/dev/ccd.c +++ b/sys/dev/ccd.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ccd.c,v 1.54 2004/01/09 21:32:23 brad Exp $ */ +/* $OpenBSD: ccd.c,v 1.55 2004/02/15 02:45:46 tedu Exp $ */ /* $NetBSD: ccd.c,v 1.33 1996/05/05 04:21:14 thorpej Exp $ */ /*- @@ -1013,7 +1013,8 @@ ccdintr(cs, bp) */ if (bp->b_flags & B_ERROR) bp->b_resid = bp->b_bcount; - disk_unbusy(&cs->sc_dkdev, (bp->b_bcount - bp->b_resid)); + disk_unbusy(&cs->sc_dkdev, (bp->b_bcount - bp->b_resid), + (bp->b_flags & B_READ)); biodone(bp); } diff --git a/sys/dev/isa/fd.c b/sys/dev/isa/fd.c index e2bf5977b2c..1f0d6ce9572 100644 --- a/sys/dev/isa/fd.c +++ b/sys/dev/isa/fd.c @@ -1,4 +1,4 @@ -/* $OpenBSD: fd.c,v 1.47 2003/06/02 23:28:02 millert Exp $ */ +/* $OpenBSD: fd.c,v 1.48 2004/02/15 02:45:47 tedu Exp $ */ /* $NetBSD: fd.c,v 1.90 1996/05/12 23:12:03 mycroft Exp $ */ /*- @@ -771,7 +771,7 @@ loop: return 1; case SEEKCOMPLETE: - disk_unbusy(&fd->sc_dk, 0); /* no data on seek */ + disk_unbusy(&fd->sc_dk, 0, 0); /* no data on seek */ /* Make sure seek really happened. */ out_fdc(iot, ioh, NE7CMD_SENSEI); @@ -797,7 +797,8 @@ loop: case IOCOMPLETE: /* IO DONE, post-analyze */ timeout_del(&fd->fdtimeout_to); - disk_unbusy(&fd->sc_dk, (bp->b_bcount - bp->b_resid)); + disk_unbusy(&fd->sc_dk, (bp->b_bcount - bp->b_resid), + (bp->b_flags & B_READ)); if (fdcresult(fdc) != 7 || (st0 & 0xf8) != 0) { isadma_abort(fdc->sc_drq); diff --git a/sys/dev/isa/mcd.c b/sys/dev/isa/mcd.c index e8f3a57205a..bc66a2839ba 100644 --- a/sys/dev/isa/mcd.c +++ b/sys/dev/isa/mcd.c @@ -1,4 +1,4 @@ -/* $OpenBSD: mcd.c,v 1.32 2003/04/06 15:28:25 krw Exp $ */ +/* $OpenBSD: mcd.c,v 1.33 2004/02/15 02:45:47 tedu Exp $ */ /* $NetBSD: mcd.c,v 1.60 1998/01/14 12:14:41 drochner Exp $ */ /* @@ -1241,7 +1241,7 @@ mcdintr(arg) /* Return buffer. */ bp->b_resid = 0; - disk_unbusy(&sc->sc_dk, bp->b_bcount); + disk_unbusy(&sc->sc_dk, bp->b_bcount, (bp->b_flags & B_READ)); biodone(bp); mcdstart(sc); diff --git a/sys/dev/ofw/ofdisk.c b/sys/dev/ofw/ofdisk.c index 489766c9dbe..7eb875e3ddc 100644 --- a/sys/dev/ofw/ofdisk.c +++ b/sys/dev/ofw/ofdisk.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ofdisk.c,v 1.7 2003/04/06 18:54:20 ho Exp $ */ +/* $OpenBSD: ofdisk.c,v 1.8 2004/02/15 02:45:47 tedu Exp $ */ /* $NetBSD: ofdisk.c,v 1.3 1996/10/13 01:38:13 christos Exp $ */ /* @@ -270,7 +270,8 @@ ofdstrategy(bp) } else bp->b_resid = bp->b_bcount - read; - disk_unbusy(&of->sc_dk, bp->b_bcount - bp->b_resid); + disk_unbusy(&of->sc_dk, bp->b_bcount - bp->b_resid, + (bp->b_flags & B_READ)); done: s = splbio(); diff --git a/sys/dev/raidframe/rf_openbsdkintf.c b/sys/dev/raidframe/rf_openbsdkintf.c index 24f5d0c3eef..059e87de4dd 100644 --- a/sys/dev/raidframe/rf_openbsdkintf.c +++ b/sys/dev/raidframe/rf_openbsdkintf.c @@ -1,4 +1,4 @@ -/* $OpenBSD: rf_openbsdkintf.c,v 1.25 2004/01/14 20:50:49 miod Exp $ */ +/* $OpenBSD: rf_openbsdkintf.c,v 1.26 2004/02/15 02:45:47 tedu Exp $ */ /* $NetBSD: rf_netbsdkintf.c,v 1.109 2001/07/27 03:30:07 oster Exp $ */ /*- @@ -3563,5 +3563,6 @@ rf_disk_unbusy(RF_RaidAccessDesc_t *desc) bp = (struct buf *)desc->bp; disk_unbusy(&raid_softc[desc->raidPtr->raidid].sc_dkdev, - (bp->b_bcount - bp->b_resid)); + (bp->b_bcount - bp->b_resid), + (bp->b_flags & B_READ)); } diff --git a/sys/dev/vnd.c b/sys/dev/vnd.c index b9db2b4c385..3258fb7fc80 100644 --- a/sys/dev/vnd.c +++ b/sys/dev/vnd.c @@ -1,4 +1,4 @@ -/* $OpenBSD: vnd.c,v 1.41 2003/10/17 23:05:39 tedu Exp $ */ +/* $OpenBSD: vnd.c,v 1.42 2004/02/15 02:45:46 tedu Exp $ */ /* $NetBSD: vnd.c,v 1.26 1996/03/30 23:06:11 christos Exp $ */ /* @@ -651,7 +651,6 @@ vndiodone(bp) struct vndbuf *vbp = (struct vndbuf *) bp; struct buf *pbp = vbp->vb_obp; struct vnd_softc *vnd = &vnd_softc[vndunit(pbp->b_dev)]; - long count; splassert(IPL_BIO); @@ -673,21 +672,22 @@ vndiodone(bp) } pbp->b_resid -= vbp->vb_buf.b_bcount; putvndbuf(vbp); - count = pbp->b_bcount - pbp->b_resid; - if (pbp->b_resid == 0) { -#ifdef DEBUG - if (vnddebug & VDB_IO) - printf("vndiodone: pbp %p iodone\n", pbp); -#endif - biodone(pbp); - } if (vnd->sc_tab.b_active) { - disk_unbusy(&vnd->sc_dk, count); + disk_unbusy(&vnd->sc_dk, (pbp->b_bcount - pbp->b_resid), + (pbp->b_flags & B_READ)); if (vnd->sc_tab.b_actf) vndstart(vnd); else vnd->sc_tab.b_active--; } + if (pbp->b_resid == 0) { +#ifdef DEBUG + if (vnddebug & VDB_IO) + printf("vndiodone: pbp %p iodone\n", pbp); +#endif + biodone(pbp); + } + } /* ARGSUSED */ diff --git a/sys/kern/kern_sysctl.c b/sys/kern/kern_sysctl.c index 68685933775..a3cbe801bb6 100644 --- a/sys/kern/kern_sysctl.c +++ b/sys/kern/kern_sysctl.c @@ -1,4 +1,4 @@ -/* $OpenBSD: kern_sysctl.c,v 1.99 2004/02/14 15:09:22 grange Exp $ */ +/* $OpenBSD: kern_sysctl.c,v 1.100 2004/02/15 02:45:46 tedu Exp $ */ /* $NetBSD: kern_sysctl.c,v 1.17 1996/05/20 17:49:05 mrg Exp $ */ /*- @@ -1528,10 +1528,14 @@ sysctl_diskinit(update, p) dk->dk_name ? dk->dk_name : ""); l += strlen(disknames + l); sdk = diskstats + i; + strlcpy(sdk->ds_name, dk->dk_name, + sizeof(sdk->ds_name)); sdk->ds_busy = dk->dk_busy; - sdk->ds_xfer = dk->dk_xfer; + sdk->ds_rxfer = dk->dk_rxfer; + sdk->ds_wxfer = dk->dk_wxfer; sdk->ds_seek = dk->dk_seek; - sdk->ds_bytes = dk->dk_bytes; + sdk->ds_rbytes = dk->dk_rbytes; + sdk->ds_wbytes = dk->dk_wbytes; sdk->ds_attachtime = dk->dk_attachtime; sdk->ds_timestamp = dk->dk_timestamp; sdk->ds_time = dk->dk_time; @@ -1546,10 +1550,14 @@ sysctl_diskinit(update, p) for (dk = TAILQ_FIRST(&disklist), i = 0; dk; dk = TAILQ_NEXT(dk, dk_link), i++) { sdk = diskstats + i; + strlcpy(sdk->ds_name, dk->dk_name, + sizeof(sdk->ds_name)); sdk->ds_busy = dk->dk_busy; - sdk->ds_xfer = dk->dk_xfer; + sdk->ds_rxfer = dk->dk_rxfer; + sdk->ds_wxfer = dk->dk_wxfer; sdk->ds_seek = dk->dk_seek; - sdk->ds_bytes = dk->dk_bytes; + sdk->ds_rbytes = dk->dk_rbytes; + sdk->ds_wbytes = dk->dk_wbytes; sdk->ds_attachtime = dk->dk_attachtime; sdk->ds_timestamp = dk->dk_timestamp; sdk->ds_time = dk->dk_time; diff --git a/sys/kern/subr_disk.c b/sys/kern/subr_disk.c index 7802ac73801..9ad79738878 100644 --- a/sys/kern/subr_disk.c +++ b/sys/kern/subr_disk.c @@ -1,4 +1,4 @@ -/* $OpenBSD: subr_disk.c,v 1.24 2004/01/21 21:00:14 tedu Exp $ */ +/* $OpenBSD: subr_disk.c,v 1.25 2004/02/15 02:45:46 tedu Exp $ */ /* $NetBSD: subr_disk.c,v 1.17 1996/03/16 23:17:08 christos Exp $ */ /* @@ -371,9 +371,10 @@ disk_busy(diskp) * time, and reset the timestamp. */ void -disk_unbusy(diskp, bcount) +disk_unbusy(diskp, bcount, read) struct disk *diskp; long bcount; + int read; { int s; struct timeval dv_time, diff_time; @@ -390,10 +391,15 @@ disk_unbusy(diskp, bcount) diskp->dk_timestamp = dv_time; if (bcount > 0) { - diskp->dk_bytes += bcount; - diskp->dk_xfer++; - } - diskp->dk_seek++; + if (read) { + diskp->dk_rbytes += bcount; + diskp->dk_rxfer++; + } else { + diskp->dk_wbytes += bcount; + diskp->dk_wxfer++; + } + } else + diskp->dk_seek++; add_disk_randomness(bcount ^ diff_time.tv_usec); } @@ -430,8 +436,10 @@ disk_resetstat(diskp) { int s = splbio(), t; - diskp->dk_xfer = 0; - diskp->dk_bytes = 0; + diskp->dk_rxfer = 0; + diskp->dk_rbytes = 0; + diskp->dk_wxfer = 0; + diskp->dk_wbytes = 0; diskp->dk_seek = 0; t = splclock(); diff --git a/sys/scsi/cd.c b/sys/scsi/cd.c index 6736c67350e..fd441cad760 100644 --- a/sys/scsi/cd.c +++ b/sys/scsi/cd.c @@ -1,4 +1,4 @@ -/* $OpenBSD: cd.c,v 1.73 2003/11/07 10:16:46 jmc Exp $ */ +/* $OpenBSD: cd.c,v 1.74 2004/02/15 02:45:47 tedu Exp $ */ /* $NetBSD: cd.c,v 1.100 1997/04/02 02:29:30 mycroft Exp $ */ /* @@ -705,7 +705,7 @@ cdstart(v) (u_char *) bp->b_data, bp->b_bcount, CDRETRIES, 30000, bp, SCSI_NOSLEEP | ((bp->b_flags & B_READ) ? SCSI_DATA_IN : SCSI_DATA_OUT))) { - disk_unbusy(&cd->sc_dk, 0); + disk_unbusy(&cd->sc_dk, 0, 0); printf("%s: not queued", cd->sc_dev.dv_xname); } } @@ -718,7 +718,8 @@ cddone(xs) struct cd_softc *cd = xs->sc_link->device_softc; if (xs->bp != NULL) - disk_unbusy(&cd->sc_dk, xs->bp->b_bcount - xs->bp->b_resid); + disk_unbusy(&cd->sc_dk, xs->bp->b_bcount - xs->bp->b_resid, + (xs->bp->b_flags & B_READ)); } void diff --git a/sys/scsi/sd.c b/sys/scsi/sd.c index de69457d985..a1ad171164e 100644 --- a/sys/scsi/sd.c +++ b/sys/scsi/sd.c @@ -1,4 +1,4 @@ -/* $OpenBSD: sd.c,v 1.65 2004/01/25 21:51:18 krw Exp $ */ +/* $OpenBSD: sd.c,v 1.66 2004/02/15 02:45:47 tedu Exp $ */ /* $NetBSD: sd.c,v 1.111 1997/04/02 02:29:41 mycroft Exp $ */ /*- @@ -751,7 +751,7 @@ sdstart(v) SDRETRIES, 60000, bp, SCSI_NOSLEEP | ((bp->b_flags & B_READ) ? SCSI_DATA_IN : SCSI_DATA_OUT)); if (error) { - disk_unbusy(&sd->sc_dk, 0); + disk_unbusy(&sd->sc_dk, 0, 0); printf("%s: not queued, error %d\n", sd->sc_dev.dv_xname, error); } @@ -770,7 +770,8 @@ sddone(xs) } if (xs->bp != NULL) - disk_unbusy(&sd->sc_dk, (xs->bp->b_bcount - xs->bp->b_resid)); + disk_unbusy(&sd->sc_dk, (xs->bp->b_bcount - xs->bp->b_resid), + (xs->bp->b_flags & B_READ)); } void diff --git a/sys/sys/disk.h b/sys/sys/disk.h index f3b6394894e..faee1a48995 100644 --- a/sys/sys/disk.h +++ b/sys/sys/disk.h @@ -1,4 +1,4 @@ -/* $OpenBSD: disk.h,v 1.11 2003/06/02 23:28:21 millert Exp $ */ +/* $OpenBSD: disk.h,v 1.12 2004/02/15 02:45:46 tedu Exp $ */ /* $NetBSD: disk.h,v 1.11 1996/04/28 20:22:50 thorpej Exp $ */ /* @@ -56,11 +56,16 @@ struct buf; struct disklabel; struct cpu_disklabel; +#define DS_DISKNAMELEN 16 + struct diskstats { + char ds_name[DS_DISKNAMELEN]; int ds_busy; /* busy counter */ - u_int64_t ds_xfer; /* total number of transfers */ + u_int64_t ds_rxfer; /* total number of read transfers */ + u_int64_t ds_wxfer; /* total number of write transfers */ u_int64_t ds_seek; /* total independent seek operations */ - u_int64_t ds_bytes; /* total bytes transferred */ + u_int64_t ds_rbytes; /* total bytes read */ + u_int64_t ds_wbytes; /* total bytes written */ struct timeval ds_attachtime; /* time disk was attached */ struct timeval ds_timestamp; /* timestamp of last unbusy */ struct timeval ds_time; /* total time spent busy */ @@ -78,9 +83,11 @@ struct disk { * on certain types of disks. */ int dk_busy; /* busy counter */ - u_int64_t dk_xfer; /* total number of transfers */ + u_int64_t dk_rxfer; /* total number of read transfers */ + u_int64_t dk_wxfer; /* total number of write transfers */ u_int64_t dk_seek; /* total independent seek operations */ - u_int64_t dk_bytes; /* total bytes transferred */ + u_int64_t dk_rbytes; /* total bytes read */ + u_int64_t dk_wbytes; /* total bytes written */ struct timeval dk_attachtime; /* time disk was attached */ struct timeval dk_timestamp; /* timestamp of last unbusy */ struct timeval dk_time; /* total time spent busy */ @@ -154,7 +161,7 @@ int disk_construct(struct disk *, char *); void disk_attach(struct disk *); void disk_detach(struct disk *); void disk_busy(struct disk *); -void disk_unbusy(struct disk *, long); +void disk_unbusy(struct disk *, long, int); void disk_resetstat(struct disk *); struct disk *disk_find(char *); diff --git a/usr.bin/systat/iostat.c b/usr.bin/systat/iostat.c index e54871e5386..4d636d10f64 100644 --- a/usr.bin/systat/iostat.c +++ b/usr.bin/systat/iostat.c @@ -1,4 +1,4 @@ -/* $OpenBSD: iostat.c,v 1.21 2003/06/03 02:56:17 millert Exp $ */ +/* $OpenBSD: iostat.c,v 1.22 2004/02/15 02:45:47 tedu Exp $ */ /* $NetBSD: iostat.c,v 1.5 1996/05/10 23:16:35 thorpej Exp $ */ /* @@ -34,7 +34,7 @@ #if 0 static char sccsid[] = "@(#)iostat.c 8.1 (Berkeley) 6/6/93"; #endif -static char rcsid[] = "$OpenBSD: iostat.c,v 1.21 2003/06/03 02:56:17 millert Exp $"; +static char rcsid[] = "$OpenBSD: iostat.c,v 1.22 2004/02/15 02:45:47 tedu Exp $"; #endif /* not lint */ #include <sys/param.h> @@ -252,16 +252,18 @@ stats(int row, int col, int dn) atime = (double)cur.dk_time[dn].tv_sec + ((double)cur.dk_time[dn].tv_usec / (double)1000000); - words = cur.dk_bytes[dn] / 1024.0; /* # of K transferred */ + /* # of K transferred */ + words = (cur.dk_rbytes[dn] + cur.dk_wbytes[dn]) / 1024.0; if (numbers) { mvwprintw(wnd, row, col, "%5.0f%4.0f%5.1f", - words / etime, cur.dk_xfer[dn] / etime, atime / etime); + words / etime, (cur.dk_rxfer[dn] + cur.dk_wxfer[dn]) / + etime, atime / etime); return (row); } wmove(wnd, row++, col); histogram(words / etime, 50, 0.5); wmove(wnd, row++, col); - histogram(cur.dk_xfer[dn] / etime, 50, 0.5); + histogram((cur.dk_rxfer[dn] + cur.dk_wxfer[dn]) / etime, 50, 0.5); if (secs) { wmove(wnd, row++, col); atime *= 1000; /* In milliseconds */ diff --git a/usr.bin/systat/vmstat.c b/usr.bin/systat/vmstat.c index 9efe1d1b7cd..eb7bf0266ac 100644 --- a/usr.bin/systat/vmstat.c +++ b/usr.bin/systat/vmstat.c @@ -1,4 +1,4 @@ -/* $OpenBSD: vmstat.c,v 1.43 2003/10/16 07:09:09 mickey Exp $ */ +/* $OpenBSD: vmstat.c,v 1.44 2004/02/15 02:45:47 tedu Exp $ */ /* $NetBSD: vmstat.c,v 1.5 1996/05/10 23:16:40 thorpej Exp $ */ /*- @@ -34,7 +34,7 @@ #if 0 static char sccsid[] = "@(#)vmstat.c 8.2 (Berkeley) 1/12/94"; #endif -static char rcsid[] = "$OpenBSD: vmstat.c,v 1.43 2003/10/16 07:09:09 mickey Exp $"; +static char rcsid[] = "$OpenBSD: vmstat.c,v 1.44 2004/02/15 02:45:47 tedu Exp $"; #endif /* not lint */ /* @@ -705,10 +705,12 @@ dinfo(int dn, int c) atime = (double)cur.dk_time[dn].tv_sec + ((double)cur.dk_time[dn].tv_usec / (double)1000000); - words = cur.dk_bytes[dn] / 1024.0; /* # of K transferred */ + /* # of K transferred */ + words = (cur.dk_rbytes[dn] + cur.dk_wbytes[dn]) / 1024.0; putint((int)((float)cur.dk_seek[dn]/etime+0.5), DISKROW + 1, c, 5); - putint((int)((float)cur.dk_xfer[dn]/etime+0.5), DISKROW + 2, c, 5); + putint((int)((float)(cur.dk_rxfer[dn] + cur.dk_wxfer[dn])/etime+0.5), + DISKROW + 2, c, 5); putint((int)(words/etime + 0.5), DISKROW + 3, c, 5); putfloat(atime/etime, DISKROW + 4, c, 5, 1, 1); } diff --git a/usr.bin/vmstat/dkstats.c b/usr.bin/vmstat/dkstats.c index 406fa47e4d0..61ccfca56fb 100644 --- a/usr.bin/vmstat/dkstats.c +++ b/usr.bin/vmstat/dkstats.c @@ -1,4 +1,4 @@ -/* $OpenBSD: dkstats.c,v 1.23 2003/06/18 04:13:10 millert Exp $ */ +/* $OpenBSD: dkstats.c,v 1.24 2004/02/15 02:45:47 tedu Exp $ */ /* $NetBSD: dkstats.c,v 1.1 1996/05/10 23:19:27 thorpej Exp $ */ /* @@ -129,9 +129,11 @@ dkswap(void) continue; /* Delta Values. */ - SWAP(dk_xfer[i]); + SWAP(dk_rxfer[i]); + SWAP(dk_wxfer[i]); SWAP(dk_seek[i]); - SWAP(dk_bytes[i]); + SWAP(dk_rbytes[i]); + SWAP(dk_wbytes[i]); /* Delta Time. */ timerclear(&tmp_timer); @@ -205,56 +207,76 @@ dkreadstats(void) if (j >= cur.dk_ndrive) { cur.dk_select[i] = 1; - last.dk_xfer[i] = 0; + last.dk_rxfer[i] = 0; + last.dk_wxfer[i] = 0; last.dk_seek[i] = 0; - last.dk_bytes[i] = 0; + last.dk_rbytes[i] = 0; + last.dk_wbytes[i] = 0; bzero(&last.dk_time[i], sizeof(struct timeval)); continue; } cur.dk_select[i] = cur.dk_select[j]; - last.dk_xfer[i] = last.dk_xfer[j]; + last.dk_rxfer[i] = last.dk_rxfer[j]; + last.dk_wxfer[i] = last.dk_wxfer[j]; last.dk_seek[i] = last.dk_seek[j]; - last.dk_bytes[i] = last.dk_bytes[j]; + last.dk_rbytes[i] = last.dk_rbytes[j]; + last.dk_wbytes[i] = last.dk_wbytes[j]; last.dk_time[i] = last.dk_time[j]; } cur.dk_select = realloc(cur.dk_select, dk_ndrive * sizeof(*cur.dk_select)); - cur.dk_xfer = realloc(cur.dk_xfer, - dk_ndrive * sizeof(*cur.dk_xfer)); + cur.dk_rxfer = realloc(cur.dk_rxfer, + dk_ndrive * sizeof(*cur.dk_rxfer)); + cur.dk_wxfer = realloc(cur.dk_wxfer, + dk_ndrive * sizeof(*cur.dk_wxfer)); cur.dk_seek = realloc(cur.dk_seek, dk_ndrive * sizeof(*cur.dk_seek)); - cur.dk_bytes = realloc(cur.dk_bytes, - dk_ndrive * sizeof(*cur.dk_bytes)); + cur.dk_rbytes = realloc(cur.dk_rbytes, + dk_ndrive * sizeof(*cur.dk_rbytes)); + cur.dk_wbytes = realloc(cur.dk_wbytes, + dk_ndrive * sizeof(*cur.dk_wbytes)); cur.dk_time = realloc(cur.dk_time, dk_ndrive * sizeof(*cur.dk_time)); - last.dk_xfer = realloc(last.dk_xfer, - dk_ndrive * sizeof(*last.dk_xfer)); + last.dk_rxfer = realloc(last.dk_rxfer, + dk_ndrive * sizeof(*last.dk_rxfer)); + last.dk_wxfer = realloc(last.dk_rxfer, + dk_ndrive * sizeof(*last.dk_rxfer)); last.dk_seek = realloc(last.dk_seek, dk_ndrive * sizeof(*last.dk_seek)); - last.dk_bytes = realloc(last.dk_bytes, - dk_ndrive * sizeof(*last.dk_bytes)); + last.dk_rbytes = realloc(last.dk_rbytes, + dk_ndrive * sizeof(*last.dk_rbytes)); + last.dk_wbytes = realloc(last.dk_wbytes, + dk_ndrive * sizeof(*last.dk_wbytes)); last.dk_time = realloc(last.dk_time, dk_ndrive * sizeof(*last.dk_time)); } else { cur.dk_select = realloc(cur.dk_select, dk_ndrive * sizeof(*cur.dk_select)); - cur.dk_xfer = realloc(cur.dk_xfer, - dk_ndrive * sizeof(*cur.dk_xfer)); + cur.dk_rxfer = realloc(cur.dk_rxfer, + dk_ndrive * sizeof(*cur.dk_rxfer)); + cur.dk_wxfer = realloc(cur.dk_wxfer, + dk_ndrive * sizeof(*cur.dk_wxfer)); cur.dk_seek = realloc(cur.dk_seek, dk_ndrive * sizeof(*cur.dk_seek)); - cur.dk_bytes = realloc(cur.dk_bytes, - dk_ndrive * sizeof(*cur.dk_bytes)); + cur.dk_rbytes = realloc(cur.dk_rbytes, + dk_ndrive * sizeof(*cur.dk_rbytes)); + cur.dk_wbytes = realloc(cur.dk_wbytes, + dk_ndrive * sizeof(*cur.dk_wbytes)); cur.dk_time = realloc(cur.dk_time, dk_ndrive * sizeof(*cur.dk_time)); - last.dk_xfer = realloc(last.dk_xfer, - dk_ndrive * sizeof(*last.dk_xfer)); + last.dk_rxfer = realloc(last.dk_rxfer, + dk_ndrive * sizeof(*last.dk_rxfer)); + last.dk_wxfer = realloc(last.dk_wxfer, + dk_ndrive * sizeof(*last.dk_wxfer)); last.dk_seek = realloc(last.dk_seek, dk_ndrive * sizeof(*last.dk_seek)); - last.dk_bytes = realloc(last.dk_bytes, - dk_ndrive * sizeof(*last.dk_bytes)); + last.dk_rbytes = realloc(last.dk_rbytes, + dk_ndrive * sizeof(*last.dk_rbytes)); + last.dk_wbytes = realloc(last.dk_wbytes, + dk_ndrive * sizeof(*last.dk_wbytes)); last.dk_time = realloc(last.dk_time, dk_ndrive * sizeof(*last.dk_time)); @@ -265,9 +287,11 @@ dkreadstats(void) strcmp(cur.dk_name[j], dk_name[i])) { cur.dk_select[i] = 1; - last.dk_xfer[i] = 0; + last.dk_rxfer[i] = 0; + last.dk_wxfer[i] = 0; last.dk_seek[i] = 0; - last.dk_bytes[i] = 0; + last.dk_rbytes[i] = 0; + last.dk_wbytes[i] = 0; bzero(&last.dk_time[i], sizeof(struct timeval)); continue; @@ -276,12 +300,16 @@ dkreadstats(void) if (i > j) { cur.dk_select[i] = cur.dk_select[j]; - last.dk_xfer[i] = - last.dk_xfer[j]; + last.dk_rxfer[i] = + last.dk_rxfer[j]; + last.dk_wxfer[i] = + last.dk_wxfer[j]; last.dk_seek[i] = last.dk_seek[j]; - last.dk_bytes[i] = - last.dk_bytes[j]; + last.dk_rbytes[i] = + last.dk_rbytes[j]; + last.dk_wbytes[i] = + last.dk_wbytes[j]; last.dk_time[i] = last.dk_time[j]; } @@ -310,9 +338,11 @@ dkreadstats(void) } for (i = 0; i < cur.dk_ndrive; i++) { - cur.dk_xfer[i] = q[i].ds_xfer; + cur.dk_rxfer[i] = q[i].ds_rxfer; + cur.dk_wxfer[i] = q[i].ds_wxfer; cur.dk_seek[i] = q[i].ds_seek; - cur.dk_bytes[i] = q[i].ds_bytes; + cur.dk_rbytes[i] = q[i].ds_rbytes; + cur.dk_wbytes[i] = q[i].ds_wbytes; timerset(&(q[i].ds_time), &(cur.dk_time[i])); } free(q); @@ -346,9 +376,11 @@ dkreadstats(void) for (i = 0; i < cur.dk_ndrive; i++) { deref_kptr(p, &cur_disk, sizeof(cur_disk)); - cur.dk_xfer[i] = cur_disk.dk_xfer; + cur.dk_rxfer[i] = cur_disk.dk_rxfer; + cur.dk_wxfer[i] = cur_disk.dk_wxfer; cur.dk_seek[i] = cur_disk.dk_seek; - cur.dk_bytes[i] = cur_disk.dk_bytes; + cur.dk_rbytes[i] = cur_disk.dk_rbytes; + cur.dk_wbytes[i] = cur_disk.dk_wbytes; timerset(&(cur_disk.dk_time), &(cur.dk_time[i])); p = cur_disk.dk_link.tqe_next; } @@ -439,19 +471,24 @@ dkinit(int select) /* allocate space for the statistics */ cur.dk_time = calloc(cur.dk_ndrive, sizeof(struct timeval)); - cur.dk_xfer = calloc(cur.dk_ndrive, sizeof(u_int64_t)); + cur.dk_rxfer = calloc(cur.dk_ndrive, sizeof(u_int64_t)); + cur.dk_wxfer = calloc(cur.dk_ndrive, sizeof(u_int64_t)); cur.dk_seek = calloc(cur.dk_ndrive, sizeof(u_int64_t)); - cur.dk_bytes = calloc(cur.dk_ndrive, sizeof(u_int64_t)); + cur.dk_rbytes = calloc(cur.dk_ndrive, sizeof(u_int64_t)); + cur.dk_wbytes = calloc(cur.dk_ndrive, sizeof(u_int64_t)); last.dk_time = calloc(cur.dk_ndrive, sizeof(struct timeval)); - last.dk_xfer = calloc(cur.dk_ndrive, sizeof(u_int64_t)); + last.dk_rxfer = calloc(cur.dk_ndrive, sizeof(u_int64_t)); + last.dk_wxfer = calloc(cur.dk_ndrive, sizeof(u_int64_t)); last.dk_seek = calloc(cur.dk_ndrive, sizeof(u_int64_t)); - last.dk_bytes = calloc(cur.dk_ndrive, sizeof(u_int64_t)); + last.dk_rbytes = calloc(cur.dk_ndrive, sizeof(u_int64_t)); + last.dk_wbytes = calloc(cur.dk_ndrive, sizeof(u_int64_t)); cur.dk_select = calloc(cur.dk_ndrive, sizeof(int)); cur.dk_name = calloc(cur.dk_ndrive, sizeof(char *)); - if (!cur.dk_time || !cur.dk_xfer || !cur.dk_seek || !cur.dk_bytes || - !last.dk_time || !last.dk_xfer || !last.dk_seek || - !last.dk_bytes || !cur.dk_select || !cur.dk_name) + if (!cur.dk_time || !cur.dk_rxfer || !cur.dk_wxfer || !cur.dk_seek || + !cur.dk_rbytes || !cur.dk_wbytes || !last.dk_time || + !last.dk_rxfer || !last.dk_wxfer || !last.dk_seek || + !cur.dk_select || !cur.dk_name) errx(1, "Memory allocation failure."); /* Set up the compatibility interfaces. */ diff --git a/usr.bin/vmstat/dkstats.h b/usr.bin/vmstat/dkstats.h index 5080d7f5d2f..62bad32d7f8 100644 --- a/usr.bin/vmstat/dkstats.h +++ b/usr.bin/vmstat/dkstats.h @@ -1,4 +1,4 @@ -/* $OpenBSD: dkstats.h,v 1.8 2002/12/16 01:57:04 tdeval Exp $ */ +/* $OpenBSD: dkstats.h,v 1.9 2004/02/15 02:45:47 tedu Exp $ */ /* $NetBSD: dkstats.h,v 1.1 1996/05/10 23:19:28 thorpej Exp $ */ /* @@ -41,9 +41,11 @@ struct _disk { int dk_ndrive; /* # of drives. */ int *dk_select; /* Display stats for selected disks. */ char **dk_name; /* Disk names (sd0, wd1, etc). */ - u_int64_t *dk_xfer; /* # of transfers. */ + u_int64_t *dk_rxfer; /* # of read transfers. */ + u_int64_t *dk_wxfer; /* # of read transfers. */ u_int64_t *dk_seek; /* # of seeks (currently unused). */ - u_int64_t *dk_bytes; /* # of bytes transferred. */ + u_int64_t *dk_rbytes; /* # of bytes read. */ + u_int64_t *dk_wbytes; /* # of bytes written. */ struct timeval *dk_time; /* Time spent in disk i/o. */ int64_t tk_nin; /* TTY Chars in. */ int64_t tk_nout; /* TTY Chars out. */ diff --git a/usr.bin/vmstat/vmstat.c b/usr.bin/vmstat/vmstat.c index 6adaca8d53c..05b47fe6865 100644 --- a/usr.bin/vmstat/vmstat.c +++ b/usr.bin/vmstat/vmstat.c @@ -1,5 +1,5 @@ /* $NetBSD: vmstat.c,v 1.29.4.1 1996/06/05 00:21:05 cgd Exp $ */ -/* $OpenBSD: vmstat.c,v 1.81 2004/01/15 20:39:33 otto Exp $ */ +/* $OpenBSD: vmstat.c,v 1.82 2004/02/15 02:45:47 tedu Exp $ */ /* * Copyright (c) 1980, 1986, 1991, 1993 @@ -40,7 +40,7 @@ static char copyright[] = #if 0 static char sccsid[] = "@(#)vmstat.c 8.1 (Berkeley) 6/6/93"; #else -static const char rcsid[] = "$OpenBSD: vmstat.c,v 1.81 2004/01/15 20:39:33 otto Exp $"; +static const char rcsid[] = "$OpenBSD: vmstat.c,v 1.82 2004/02/15 02:45:47 tedu Exp $"; #endif #endif /* not lint */ @@ -672,7 +672,8 @@ dkstats(void) for (dn = 0; dn < dk_ndrive; ++dn) { if (!dk_select[dn]) continue; - (void)printf("%3.0f ", cur.dk_xfer[dn] / etime); + (void)printf("%3.0f ", + (cur.dk_rxfer[dn] + cur.dk_rxfer[dn]) / etime); } } diff --git a/usr.sbin/iostat/iostat.c b/usr.sbin/iostat/iostat.c index a4fbf839650..9b4086ce499 100644 --- a/usr.sbin/iostat/iostat.c +++ b/usr.sbin/iostat/iostat.c @@ -1,4 +1,4 @@ -/* $OpenBSD: iostat.c,v 1.18 2003/06/26 19:47:09 deraadt Exp $ */ +/* $OpenBSD: iostat.c,v 1.19 2004/02/15 02:45:47 tedu Exp $ */ /* $NetBSD: iostat.c,v 1.10 1996/10/25 18:21:58 scottr Exp $ */ /* @@ -265,14 +265,16 @@ double etime; continue; /* average Kbytes per transfer. */ - if (cur.dk_xfer[dn]) - mbps = (cur.dk_bytes[dn] / (1024.0)) / cur.dk_xfer[dn]; + if (cur.dk_rxfer[dn] + cur.dk_wxfer[dn]) + mbps = ((cur.dk_rxfer[dn] + cur.dk_wxfer[dn]) / + (1024.0)) / (cur.dk_rxfer[dn] + cur.dk_wxfer[dn]); else mbps = 0.0; (void)printf(" %5.2f", mbps); /* average transfers per second. */ - (void)printf(" %3.0f", cur.dk_xfer[dn] / etime); + (void)printf(" %3.0f", + (cur.dk_rxfer[dn] + cur.dk_wxfer[dn]) / etime); /* time busy in disk activity */ atime = (double)cur.dk_time[dn].tv_sec + @@ -280,7 +282,8 @@ double etime; /* Megabytes per second. */ if (atime != 0.0) - mbps = cur.dk_bytes[dn] / (double)(1024 * 1024); + mbps = (cur.dk_rbytes[dn] + cur.dk_wbytes[dn]) / + (double)(1024 * 1024); else mbps = 0; (void)printf(" %4.2f ", mbps / etime); @@ -299,10 +302,12 @@ double etime; continue; /* average kbytes per second. */ - (void)printf(" %4.0f", cur.dk_bytes[dn] / (1024.0) / etime); + (void)printf(" %4.0f", + (cur.dk_rbytes[dn] + cur.dk_wbytes[dn]) / (1024.0) / etime); /* average transfers per second. */ - (void)printf(" %3.0f", cur.dk_xfer[dn] / etime); + (void)printf(" %3.0f", + (cur.dk_rxfer[dn] + cur.dk_wxfer[dn]) / etime); /* average time busy in disk activity. */ atime = (double)cur.dk_time[dn].tv_sec + |