aboutsummaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
Diffstat (limited to 'sys')
-rw-r--r--sys/kern/vfs_export.c44
-rw-r--r--sys/kern/vfs_subr.c44
-rw-r--r--sys/sys/vnode.h3
-rw-r--r--sys/ufs/ufs/ufs_vnops.c29
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,
+ &timestamp_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,
+ &timestamp_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);