diff options
Diffstat (limited to 'usr/src/uts/common/fs/vnode.c')
| -rw-r--r-- | usr/src/uts/common/fs/vnode.c | 125 | 
1 files changed, 117 insertions, 8 deletions
| diff --git a/usr/src/uts/common/fs/vnode.c b/usr/src/uts/common/fs/vnode.c index 6e8f65cacb..6d6c4af5ca 100644 --- a/usr/src/uts/common/fs/vnode.c +++ b/usr/src/uts/common/fs/vnode.c @@ -207,6 +207,11 @@ static void		(**vsd_destructor)(void *);  		cr = crgetmapped(cr);					\  	} +#define	VOP_LATENCY_10MS	10000000 +#define	VOP_LATENCY_100MS	100000000 +#define	VOP_LATENCY_1S		1000000000 +#define	VOP_LATENCY_10S		10000000000 +  /*   * Convert stat(2) formats to vnode types and vice versa.  (Knows about   * numerical order of S_IFMT and vnode types.) @@ -2543,6 +2548,7 @@ vnevent_rename_src(vnode_t *vp, vnode_t *dvp, char *name, caller_context_t *ct)  	if (vp == NULL || vp->v_femhead == NULL) {  		return;  	} +	(void) VOP_VNEVENT(dvp, VE_RENAME_SRC_DIR, vp, name, ct);  	(void) VOP_VNEVENT(vp, VE_RENAME_SRC, dvp, name, ct);  } @@ -2557,12 +2563,13 @@ vnevent_rename_dest(vnode_t *vp, vnode_t *dvp, char *name,  }  void -vnevent_rename_dest_dir(vnode_t *vp, caller_context_t *ct) +vnevent_rename_dest_dir(vnode_t *vp, vnode_t *nvp, char *name, +    caller_context_t *ct)  {  	if (vp == NULL || vp->v_femhead == NULL) {  		return;  	} -	(void) VOP_VNEVENT(vp, VE_RENAME_DEST_DIR, NULL, NULL, ct); +	(void) VOP_VNEVENT(vp, VE_RENAME_DEST_DIR, nvp, name, ct);  }  void @@ -2649,6 +2656,15 @@ vnevent_truncate(vnode_t *vp, caller_context_t *ct)  	(void) VOP_VNEVENT(vp, VE_TRUNCATE, NULL, NULL, ct);  } +void +vnevent_resize(vnode_t *vp, caller_context_t *ct) +{ +	if (vp == NULL || vp->v_femhead == NULL) { +		return; +	} +	(void) VOP_VNEVENT(vp, VE_RESIZE, NULL, NULL, ct); +} +  /*   * Vnode accessors.   */ @@ -3424,14 +3440,58 @@ fop_read(  	cred_t *cr,  	caller_context_t *ct)  { -	int	err;  	ssize_t	resid_start = uiop->uio_resid; +	zone_t	*zonep = curzone; +	zone_vfs_kstat_t *zvp = zonep->zone_vfs_stats; + +	hrtime_t start = 0, lat; +	ssize_t len; +	int err; + +	if ((vp->v_type == VREG || vp->v_type == VDIR || vp->v_type == VBLK) && +	    vp->v_vfsp != NULL && (vp->v_vfsp->vfs_flag & VFS_STATS)) { +		start = gethrtime(); + +		mutex_enter(&zonep->zone_vfs_lock); +		kstat_runq_enter(&zonep->zone_vfs_rwstats); +		mutex_exit(&zonep->zone_vfs_lock); +	}  	VOPXID_MAP_CR(vp, cr);  	err = (*(vp)->v_op->vop_read)(vp, uiop, ioflag, cr, ct); -	VOPSTATS_UPDATE_IO(vp, read, -	    read_bytes, (resid_start - uiop->uio_resid)); +	len = resid_start - uiop->uio_resid; + +	VOPSTATS_UPDATE_IO(vp, read, read_bytes, len); + +	if (start != 0) { +		mutex_enter(&zonep->zone_vfs_lock); +		zonep->zone_vfs_rwstats.reads++; +		zonep->zone_vfs_rwstats.nread += len; +		kstat_runq_exit(&zonep->zone_vfs_rwstats); +		mutex_exit(&zonep->zone_vfs_lock); + +		lat = gethrtime() - start; + +		if (lat >= VOP_LATENCY_10MS) { +			if (lat < VOP_LATENCY_100MS) +				atomic_inc_64(&zvp->zv_10ms_ops.value.ui64); +			else if (lat < VOP_LATENCY_1S) { +				atomic_inc_64(&zvp->zv_10ms_ops.value.ui64); +				atomic_inc_64(&zvp->zv_100ms_ops.value.ui64); +			} else if (lat < VOP_LATENCY_10S) { +				atomic_inc_64(&zvp->zv_10ms_ops.value.ui64); +				atomic_inc_64(&zvp->zv_100ms_ops.value.ui64); +				atomic_inc_64(&zvp->zv_1s_ops.value.ui64); +			} else { +				atomic_inc_64(&zvp->zv_10ms_ops.value.ui64); +				atomic_inc_64(&zvp->zv_100ms_ops.value.ui64); +				atomic_inc_64(&zvp->zv_1s_ops.value.ui64); +				atomic_inc_64(&zvp->zv_10s_ops.value.ui64); +			} +		} +	} +  	return (err);  } @@ -3443,14 +3503,63 @@ fop_write(  	cred_t *cr,  	caller_context_t *ct)  { -	int	err;  	ssize_t	resid_start = uiop->uio_resid; +	zone_t	*zonep = curzone; +	zone_vfs_kstat_t *zvp = zonep->zone_vfs_stats; + +	hrtime_t start = 0, lat; +	ssize_t len; +	int	err; + +	/* +	 * For the purposes of VFS kstat consumers, the "waitq" calculation is +	 * repurposed as the active queue for VFS write operations.  There's no +	 * actual wait queue for VFS operations. +	 */ +	if ((vp->v_type == VREG || vp->v_type == VDIR || vp->v_type == VBLK) && +	    vp->v_vfsp != NULL && (vp->v_vfsp->vfs_flag & VFS_STATS)) { +		start = gethrtime(); + +		mutex_enter(&zonep->zone_vfs_lock); +		kstat_waitq_enter(&zonep->zone_vfs_rwstats); +		mutex_exit(&zonep->zone_vfs_lock); +	}  	VOPXID_MAP_CR(vp, cr);  	err = (*(vp)->v_op->vop_write)(vp, uiop, ioflag, cr, ct); -	VOPSTATS_UPDATE_IO(vp, write, -	    write_bytes, (resid_start - uiop->uio_resid)); +	len = resid_start - uiop->uio_resid; + +	VOPSTATS_UPDATE_IO(vp, write, write_bytes, len); + +	if (start != 0) { +		mutex_enter(&zonep->zone_vfs_lock); +		zonep->zone_vfs_rwstats.writes++; +		zonep->zone_vfs_rwstats.nwritten += len; +		kstat_waitq_exit(&zonep->zone_vfs_rwstats); +		mutex_exit(&zonep->zone_vfs_lock); + +		lat = gethrtime() - start; + +		if (lat >= VOP_LATENCY_10MS) { +			if (lat < VOP_LATENCY_100MS) +				atomic_inc_64(&zvp->zv_10ms_ops.value.ui64); +			else if (lat < VOP_LATENCY_1S) { +				atomic_inc_64(&zvp->zv_10ms_ops.value.ui64); +				atomic_inc_64(&zvp->zv_100ms_ops.value.ui64); +			} else if (lat < VOP_LATENCY_10S) { +				atomic_inc_64(&zvp->zv_10ms_ops.value.ui64); +				atomic_inc_64(&zvp->zv_100ms_ops.value.ui64); +				atomic_inc_64(&zvp->zv_1s_ops.value.ui64); +			} else { +				atomic_inc_64(&zvp->zv_10ms_ops.value.ui64); +				atomic_inc_64(&zvp->zv_100ms_ops.value.ui64); +				atomic_inc_64(&zvp->zv_1s_ops.value.ui64); +				atomic_inc_64(&zvp->zv_10s_ops.value.ui64); +			} +		} +	} +  	return (err);  } | 
