diff options
author | mckusick <mckusick@FreeBSD.org> | 2012-04-08 06:20:21 +0000 |
---|---|---|
committer | mckusick <mckusick@FreeBSD.org> | 2012-04-08 06:20:21 +0000 |
commit | 614fd4fe5e7e76da2328df84ca390b36dad17e79 (patch) | |
tree | ac3859e68a88e7aa5a584b0dcbb67868c43ca06f | |
parent | 4bed5dbd8fe59f265092a2c8d3f6109dac7700c1 (diff) | |
download | FreeBSD-src-614fd4fe5e7e76da2328df84ca390b36dad17e79.zip FreeBSD-src-614fd4fe5e7e76da2328df84ca390b36dad17e79.tar.gz |
Expand locking around identification of filesystem mount point when
accounting for I/O counts at completion of I/O operation. Also switch
from using global devmtx to vnode mutex to reduce contention.
Suggested and reviewed by: kib
-rw-r--r-- | sys/geom/geom_vfs.c | 22 |
1 files changed, 17 insertions, 5 deletions
diff --git a/sys/geom/geom_vfs.c b/sys/geom/geom_vfs.c index 499445f..ade1790 100644 --- a/sys/geom/geom_vfs.c +++ b/sys/geom/geom_vfs.c @@ -97,6 +97,7 @@ g_vfs_done(struct bio *bip) int vfslocked, destroy; struct mount *mp; struct vnode *vp; + struct cdev *cdevp; /* * Collect statistics on synchronous and asynchronous read @@ -106,12 +107,23 @@ g_vfs_done(struct bio *bip) */ bp = bip->bio_caller2; vp = bp->b_vp; - if (vp == NULL) + if (vp == NULL) { mp = NULL; - else if (vn_isdisk(vp, NULL)) - mp = vp->v_rdev->si_mountpt; - else - mp = vp->v_mount; + } else { + /* + * If not a disk vnode, use its associated mount point + * otherwise use the mountpoint associated with the disk. + */ + VI_LOCK(vp); + if (vp->v_type != VCHR || + (cdevp = vp->v_rdev) == NULL || + cdevp->si_devsw == NULL || + (cdevp->si_devsw->d_flags & D_DISK) == 0) + mp = vp->v_mount; + else + mp = cdevp->si_mountpt; + VI_UNLOCK(vp); + } if (mp != NULL) { if (bp->b_iocmd == BIO_WRITE) { if (LK_HOLDER(bp->b_lock.lk_lock) == LK_KERNPROC) |