Collect read and write counts for filesystems. This new code

drops the counting in bwrite and puts it all in spec_strategy.
I did some tests and verified that the counts collected for writes
in spec_strategy is identical to the counts that we previously
collected in bwrite. We now also get read counts (async reads
come from requests for read-ahead blocks). Note that you need
to compile a new version of mount to get the read counts printed
out. The old mount binary is completely compatible, the only
reason to install a new mount is to get the read counts printed.

Submitted by:	Craig A Soules <soules+@andrew.cmu.edu>
Reviewed by:	Kirk McKusick <mckusick@mckusick.com>
This commit is contained in:
Kirk McKusick 1999-12-01 02:09:30 +00:00
parent 08c667112d
commit e9cc475851
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=53975
4 changed files with 48 additions and 21 deletions

View file

@ -406,11 +406,32 @@ spec_strategy(ap)
} */ *ap;
{
struct buf *bp;
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);
/*
* Collect statistics on synchronous and asynchronous read
* and write counts for disks that have associated filesystems.
*/
vp = ap->a_vp;
if (vn_isdisk(vp) && (mp = vp->v_specmountpoint) != NULL) {
if ((bp->b_flags & B_READ) == 0) {
if (bp->b_lock.lk_lockholder == LK_KERNPROC)
mp->mnt_stat.f_asyncwrites++;
else
mp->mnt_stat.f_syncwrites++;
} else {
if (bp->b_lock.lk_lockholder == LK_KERNPROC)
mp->mnt_stat.f_asyncreads++;
else
mp->mnt_stat.f_syncreads++;
}
}
KASSERT(devsw(bp->b_dev) != NULL,
("No devsw on dev %s responsible for buffer %p\n",
devtoname(bp->b_dev), bp));

View file

@ -589,8 +589,6 @@ int
bwrite(struct buf * bp)
{
int oldflags, s;
struct vnode *vp;
struct mount *mp;
if (bp->b_flags & B_INVAL) {
brelse(bp);
@ -618,24 +616,6 @@ bwrite(struct buf * bp)
BUF_KERNPROC(bp);
VOP_STRATEGY(bp->b_vp, bp);
/*
* Collect statistics on synchronous and asynchronous writes.
* Writes to block devices are charged to their associated
* filesystem (if any).
*/
if ((vp = bp->b_vp) != NULL) {
if (vn_isdisk(vp))
mp = vp->v_specmountpoint;
else
mp = vp->v_mount;
if (mp != NULL) {
if ((oldflags & B_ASYNC) == 0)
mp->mnt_stat.f_syncwrites++;
else
mp->mnt_stat.f_asyncwrites++;
}
}
if ((oldflags & B_ASYNC) == 0) {
int rtval = biowait(bp);
brelse(bp);

View file

@ -406,11 +406,32 @@ spec_strategy(ap)
} */ *ap;
{
struct buf *bp;
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);
/*
* Collect statistics on synchronous and asynchronous read
* and write counts for disks that have associated filesystems.
*/
vp = ap->a_vp;
if (vn_isdisk(vp) && (mp = vp->v_specmountpoint) != NULL) {
if ((bp->b_flags & B_READ) == 0) {
if (bp->b_lock.lk_lockholder == LK_KERNPROC)
mp->mnt_stat.f_asyncwrites++;
else
mp->mnt_stat.f_syncwrites++;
} else {
if (bp->b_lock.lk_lockholder == LK_KERNPROC)
mp->mnt_stat.f_asyncreads++;
else
mp->mnt_stat.f_syncreads++;
}
}
KASSERT(devsw(bp->b_dev) != NULL,
("No devsw on dev %s responsible for buffer %p\n",
devtoname(bp->b_dev), bp));

View file

@ -67,7 +67,7 @@ struct fid {
*/
#define MFSNAMELEN 16 /* length of fs type name, including null */
#define MNAMELEN 90 /* length of buffer for returned name */
#define MNAMELEN 80 /* length of buffer for returned name */
struct statfs {
long f_spare2; /* placeholder */
@ -86,7 +86,12 @@ struct statfs {
long f_asyncwrites; /* count of async writes since mount */
char f_fstypename[MFSNAMELEN]; /* fs type name */
char f_mntonname[MNAMELEN]; /* directory on which mounted */
long f_syncreads; /* count of sync reads since mount */
long f_asyncreads; /* count of async reads since mount */
short f_spares1; /* unused spare */
char f_mntfromname[MNAMELEN];/* mounted filesystem */
short f_spares2; /* unused spare */
long f_spare[2]; /* unused spare */
};
/*