summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authormckusick <mckusick@FreeBSD.org>2012-03-28 20:49:11 +0000
committermckusick <mckusick@FreeBSD.org>2012-03-28 20:49:11 +0000
commit9a7982e5a0267c0421856f3a43a1ae75880058f3 (patch)
treee4296e1e7484307c80036dcfa1043b1869febf17
parent4d38be64d75540ce84d18b307ffc130ac5d5f2f9 (diff)
downloadFreeBSD-src-9a7982e5a0267c0421856f3a43a1ae75880058f3.zip
FreeBSD-src-9a7982e5a0267c0421856f3a43a1ae75880058f3.tar.gz
Keep track of the mount point associated with a special device
to enable the collection of counts of synchronous and asynchronous reads and writes for its associated filesystem. The counts are displayed using `mount -v'. Ensure that buffers used for paging indicate the vnode from which they are operating so that counts of paging I/O operations from the filesystem are collected. This checkin only adds the setting of the mount point for the UFS/FFS filesystem, but it would be trivial to add the setting and clearing of the mount point at filesystem mount/unmount time for other filesystems too. Reviewed by: kib
-rw-r--r--sys/geom/geom_vfs.c31
-rw-r--r--sys/sys/conf.h4
-rw-r--r--sys/ufs/ffs/ffs_vfsops.c6
-rw-r--r--sys/vm/vnode_pager.c4
4 files changed, 42 insertions, 3 deletions
diff --git a/sys/geom/geom_vfs.c b/sys/geom/geom_vfs.c
index 9be0000..499445f 100644
--- a/sys/geom/geom_vfs.c
+++ b/sys/geom/geom_vfs.c
@@ -95,6 +95,36 @@ g_vfs_done(struct bio *bip)
struct g_vfs_softc *sc;
struct buf *bp;
int vfslocked, destroy;
+ struct mount *mp;
+ struct vnode *vp;
+
+ /*
+ * Collect statistics on synchronous and asynchronous read
+ * and write counts for disks that have associated filesystems.
+ * Since this run by the g_up thread it is single threaded and
+ * we do not need to use atomic increments on the counters.
+ */
+ bp = bip->bio_caller2;
+ vp = bp->b_vp;
+ if (vp == NULL)
+ mp = NULL;
+ else if (vn_isdisk(vp, NULL))
+ mp = vp->v_rdev->si_mountpt;
+ else
+ mp = vp->v_mount;
+ if (mp != NULL) {
+ if (bp->b_iocmd == BIO_WRITE) {
+ if (LK_HOLDER(bp->b_lock.lk_lock) == LK_KERNPROC)
+ mp->mnt_stat.f_asyncwrites++;
+ else
+ mp->mnt_stat.f_syncwrites++;
+ } else {
+ if (LK_HOLDER(bp->b_lock.lk_lock) == LK_KERNPROC)
+ mp->mnt_stat.f_asyncreads++;
+ else
+ mp->mnt_stat.f_syncreads++;
+ }
+ }
cp = bip->bio_from;
sc = cp->geom->softc;
@@ -103,7 +133,6 @@ g_vfs_done(struct bio *bip)
g_print_bio(bip);
printf("error = %d\n", bip->bio_error);
}
- bp = bip->bio_caller2;
bp->b_error = bip->bio_error;
bp->b_ioflags = bip->bio_flags;
if (bip->bio_error)
diff --git a/sys/sys/conf.h b/sys/sys/conf.h
index 0a12124..49bb3d4 100644
--- a/sys/sys/conf.h
+++ b/sys/sys/conf.h
@@ -52,7 +52,7 @@ struct cdevsw;
struct file;
struct cdev {
- void *__si_reserved;
+ void *si_spare0;
u_int si_flags;
#define SI_ETERNAL 0x0001 /* never destroyed */
#define SI_ALIAS 0x0002 /* carrier of alias name */
@@ -78,7 +78,7 @@ struct cdev {
LIST_HEAD(, cdev) si_children;
LIST_ENTRY(cdev) si_siblings;
struct cdev *si_parent;
- void *si_spare0;
+ struct mount *si_mountpt;
void *si_drv1, *si_drv2;
struct cdevsw *si_devsw;
int si_iosize_max; /* maximum I/O size (for physio &al) */
diff --git a/sys/ufs/ffs/ffs_vfsops.c b/sys/ufs/ffs/ffs_vfsops.c
index 8871cdf..f38fbcb 100644
--- a/sys/ufs/ffs/ffs_vfsops.c
+++ b/sys/ufs/ffs/ffs_vfsops.c
@@ -407,6 +407,8 @@ ffs_mount(struct mount *mp)
vn_finished_write(mp);
return (error);
}
+ if (devvp->v_type == VCHR && devvp->v_rdev != NULL)
+ devvp->v_rdev->si_mountpt = mp;
if (fs->fs_snapinum[0] != 0)
ffs_snapshot_mount(mp);
vn_finished_write(mp);
@@ -1050,6 +1052,8 @@ ffs_mountfs(devvp, mp, td)
ffs_flushfiles(mp, FORCECLOSE, td);
goto out;
}
+ if (devvp->v_type == VCHR && devvp->v_rdev != NULL)
+ devvp->v_rdev->si_mountpt = mp;
if (fs->fs_snapinum[0] != 0)
ffs_snapshot_mount(mp);
fs->fs_fmod = 1;
@@ -1295,6 +1299,8 @@ ffs_unmount(mp, mntflags)
g_vfs_close(ump->um_cp);
g_topology_unlock();
PICKUP_GIANT();
+ if (ump->um_devvp->v_type == VCHR && ump->um_devvp->v_rdev != NULL)
+ ump->um_devvp->v_rdev->si_mountpt = NULL;
vrele(ump->um_devvp);
dev_rel(ump->um_dev);
mtx_destroy(UFS_MTX(ump));
diff --git a/sys/vm/vnode_pager.c b/sys/vm/vnode_pager.c
index c5b6c17..c8c57e1 100644
--- a/sys/vm/vnode_pager.c
+++ b/sys/vm/vnode_pager.c
@@ -543,6 +543,7 @@ vnode_pager_input_smlfs(object, m)
bp->b_data = (caddr_t)sf_buf_kva(sf) + i * bsize;
bp->b_blkno = fileaddr;
pbgetbo(bo, bp);
+ bp->b_vp = vp;
bp->b_bcount = bsize;
bp->b_bufsize = bsize;
bp->b_runningbufspace = bp->b_bufsize;
@@ -560,6 +561,7 @@ vnode_pager_input_smlfs(object, m)
/*
* free the buffer header back to the swap buffer pool
*/
+ bp->b_vp = NULL;
pbrelbo(bp);
relpbuf(bp, &vnode_pbuf_freecnt);
if (error)
@@ -918,6 +920,7 @@ vnode_pager_generic_getpages(vp, m, bytecount, reqpage)
bp->b_wcred = crhold(curthread->td_ucred);
bp->b_blkno = firstaddr;
pbgetbo(bo, bp);
+ bp->b_vp = vp;
bp->b_bcount = size;
bp->b_bufsize = size;
bp->b_runningbufspace = bp->b_bufsize;
@@ -944,6 +947,7 @@ vnode_pager_generic_getpages(vp, m, bytecount, reqpage)
/*
* free the buffer header back to the swap buffer pool
*/
+ bp->b_vp = NULL;
pbrelbo(bp);
relpbuf(bp, &vnode_pbuf_freecnt);
OpenPOWER on IntegriCloud