diff options
Diffstat (limited to 'sys')
-rw-r--r-- | sys/kern/vfs_export.c | 44 | ||||
-rw-r--r-- | sys/kern/vfs_subr.c | 44 | ||||
-rw-r--r-- | sys/sys/vnode.h | 3 | ||||
-rw-r--r-- | sys/ufs/ufs/ufs_vnops.c | 29 |
4 files changed, 107 insertions, 13 deletions
diff --git a/sys/kern/vfs_export.c b/sys/kern/vfs_export.c index 21bb57bddbdc..043a5bf78d51 100644 --- a/sys/kern/vfs_export.c +++ b/sys/kern/vfs_export.c @@ -36,7 +36,7 @@ * SUCH DAMAGE. * * @(#)vfs_subr.c 8.31 (Berkeley) 5/26/95 - * $Id: vfs_subr.c,v 1.216 1999/08/13 10:10:01 phk Exp $ + * $Id: vfs_subr.c,v 1.217 1999/08/13 10:29:21 phk Exp $ */ /* @@ -361,6 +361,48 @@ vfs_getnewfsid(mp) } /* + * Knob to control the precision of file timestamps: + * + * 0 = seconds only; nanoseconds zeroed. + * 1 = seconds and nanoseconds, accurate within 1/HZ. + * 2 = seconds and nanoseconds, truncated to microseconds. + * >=3 = seconds and nanoseconds, maximum precision. + */ +enum { TSP_SEC, TSP_HZ, TSP_USEC, TSP_NSEC }; + +static int timestamp_precision = TSP_SEC; +SYSCTL_INT(_vfs, OID_AUTO, timestamp_precision, CTLFLAG_RW, + ×tamp_precision, 0, ""); + +/* + * Get a current timestamp. + */ +void +vfs_timestamp(tsp) + struct timespec *tsp; +{ + struct timeval tv; + + switch (timestamp_precision) { + case TSP_SEC: + tsp->tv_sec = time_second; + tsp->tv_nsec = 0; + break; + case TSP_HZ: + getnanotime(tsp); + break; + case TSP_USEC: + microtime(&tv); + TIMEVAL_TO_TIMESPEC(&tv, tsp); + break; + case TSP_NSEC: + default: + nanotime(tsp); + break; + } +} + +/* * Set vnode attributes to VNOVAL */ void diff --git a/sys/kern/vfs_subr.c b/sys/kern/vfs_subr.c index 21bb57bddbdc..043a5bf78d51 100644 --- a/sys/kern/vfs_subr.c +++ b/sys/kern/vfs_subr.c @@ -36,7 +36,7 @@ * SUCH DAMAGE. * * @(#)vfs_subr.c 8.31 (Berkeley) 5/26/95 - * $Id: vfs_subr.c,v 1.216 1999/08/13 10:10:01 phk Exp $ + * $Id: vfs_subr.c,v 1.217 1999/08/13 10:29:21 phk Exp $ */ /* @@ -361,6 +361,48 @@ vfs_getnewfsid(mp) } /* + * Knob to control the precision of file timestamps: + * + * 0 = seconds only; nanoseconds zeroed. + * 1 = seconds and nanoseconds, accurate within 1/HZ. + * 2 = seconds and nanoseconds, truncated to microseconds. + * >=3 = seconds and nanoseconds, maximum precision. + */ +enum { TSP_SEC, TSP_HZ, TSP_USEC, TSP_NSEC }; + +static int timestamp_precision = TSP_SEC; +SYSCTL_INT(_vfs, OID_AUTO, timestamp_precision, CTLFLAG_RW, + ×tamp_precision, 0, ""); + +/* + * Get a current timestamp. + */ +void +vfs_timestamp(tsp) + struct timespec *tsp; +{ + struct timeval tv; + + switch (timestamp_precision) { + case TSP_SEC: + tsp->tv_sec = time_second; + tsp->tv_nsec = 0; + break; + case TSP_HZ: + getnanotime(tsp); + break; + case TSP_USEC: + microtime(&tv); + TIMEVAL_TO_TIMESPEC(&tv, tsp); + break; + case TSP_NSEC: + default: + nanotime(tsp); + break; + } +} + +/* * Set vnode attributes to VNOVAL */ void diff --git a/sys/sys/vnode.h b/sys/sys/vnode.h index fc9dbe9df49c..aa02ac47e727 100644 --- a/sys/sys/vnode.h +++ b/sys/sys/vnode.h @@ -31,7 +31,7 @@ * SUCH DAMAGE. * * @(#)vnode.h 8.7 (Berkeley) 2/4/94 - * $Id: vnode.h,v 1.93 1999/08/08 18:43:00 phk Exp $ + * $Id: vnode.h,v 1.94 1999/08/13 10:10:11 phk Exp $ */ #ifndef _SYS_VNODE_H_ @@ -544,6 +544,7 @@ dev_t vn_todev __P((struct vnode *vp)); int vfs_cache_lookup __P((struct vop_lookup_args *ap)); int vfs_object_create __P((struct vnode *vp, struct proc *p, struct ucred *cred)); +void vfs_timestamp __P((struct timespec *)); int vn_writechk __P((struct vnode *vp)); int vop_stdbwrite __P((struct vop_bwrite_args *ap)); int vop_stdislocked __P((struct vop_islocked_args *)); diff --git a/sys/ufs/ufs/ufs_vnops.c b/sys/ufs/ufs/ufs_vnops.c index e65f22b48160..f68e6dae180f 100644 --- a/sys/ufs/ufs/ufs_vnops.c +++ b/sys/ufs/ufs/ufs_vnops.c @@ -36,7 +36,7 @@ * SUCH DAMAGE. * * @(#)ufs_vnops.c 8.27 (Berkeley) 5/27/95 - * $Id: ufs_vnops.c,v 1.118 1999/08/13 10:10:12 phk Exp $ + * $Id: ufs_vnops.c,v 1.119 1999/08/13 10:56:02 phk Exp $ */ #include "opt_quota.h" @@ -138,26 +138,31 @@ ufs_itimes(vp) struct vnode *vp; { struct inode *ip; - time_t tv_sec; + struct timespec ts; ip = VTOI(vp); if ((ip->i_flag & (IN_ACCESS | IN_CHANGE | IN_UPDATE)) == 0) return; if ((vp->v_mount->mnt_flag & MNT_RDONLY) == 0) { - tv_sec = time_second; + vfs_timestamp(&ts); if ((vp->v_type == VBLK || vp->v_type == VCHR) && !DOINGSOFTDEP(vp)) ip->i_flag |= IN_LAZYMOD; else ip->i_flag |= IN_MODIFIED; - if (ip->i_flag & IN_ACCESS) - ip->i_atime = tv_sec; + if (ip->i_flag & IN_ACCESS) { + ip->i_atime = ts.tv_sec; + ip->i_atimensec = ts.tv_nsec; + } if (ip->i_flag & IN_UPDATE) { - ip->i_mtime = tv_sec; + ip->i_mtime = ts.tv_sec; + ip->i_mtimensec = ts.tv_nsec; ip->i_modrev++; } - if (ip->i_flag & IN_CHANGE) - ip->i_ctime = tv_sec; + if (ip->i_flag & IN_CHANGE) { + ip->i_ctime = ts.tv_sec; + ip->i_ctimensec = ts.tv_nsec; + } } ip->i_flag &= ~(IN_ACCESS | IN_CHANGE | IN_UPDATE); } @@ -500,10 +505,14 @@ ufs_setattr(ap) if (vap->va_mtime.tv_sec != VNOVAL) ip->i_flag |= IN_CHANGE | IN_UPDATE; ufs_itimes(vp); - if (vap->va_atime.tv_sec != VNOVAL) + if (vap->va_atime.tv_sec != VNOVAL) { ip->i_atime = vap->va_atime.tv_sec; - if (vap->va_mtime.tv_sec != VNOVAL) + ip->i_atimensec = vap->va_atime.tv_nsec; + } + if (vap->va_mtime.tv_sec != VNOVAL) { ip->i_mtime = vap->va_mtime.tv_sec; + ip->i_mtimensec = vap->va_mtime.tv_nsec; + } error = UFS_UPDATE(vp, 0); if (error) return (error); |