Get the time with higher resolution from kernel using host_get_time64()
when possible.

---
 libdiskfs/node-times.c | 25 +++++++++++++++++--------
 1 file changed, 17 insertions(+), 8 deletions(-)

diff --git a/libdiskfs/node-times.c b/libdiskfs/node-times.c
index 60eabc0f..203232da 100644
--- a/libdiskfs/node-times.c
+++ b/libdiskfs/node-times.c
@@ -23,6 +23,7 @@
 
 #include "priv.h"
 #include <maptime.h>
+#include <mach/time_value.h>
 
 /* If the disk is not readonly and noatime is not set, then check relatime
    conditions: if either `np->dn_stat.st_mtim.tv_sec' or
@@ -71,12 +72,20 @@ diskfs_set_node_atime (struct node *np)
 void
 diskfs_set_node_times (struct node *np)
 {
-  struct timeval t;
+  struct timeval mt;
+  time_value64_t t;
 
   if (!np->dn_set_mtime && !np->dn_set_atime && !np->dn_set_ctime)
     return;
 
-  maptime_read (diskfs_mtime, &t);
+  /* Get time from kernel.  If host_get_time64 is not supported by the
+     kernel, step back to use maptime_read.  */
+  if (host_get_time64 (mach_host_self (), &t) == MIG_BAD_ID)
+    {
+      maptime_read (diskfs_mtime, &mt);
+      t.seconds = mt.tv_sec;
+      t.nanoseconds = mt.tv_usec * 1000;
+    }
 
   /* We are careful to test and reset each of these individually, so there
      is no race condition where a dn_set_?time flag setting gets lost.  It
@@ -85,22 +94,22 @@ diskfs_set_node_times (struct node *np)
      the update will happen at the next call.  */
   if (np->dn_set_mtime)
     {
-      np->dn_stat.st_mtim.tv_sec = t.tv_sec;
-      np->dn_stat.st_mtim.tv_nsec = t.tv_usec * 1000;
+      np->dn_stat.st_mtim.tv_sec = t.seconds;
+      np->dn_stat.st_mtim.tv_nsec = t.nanoseconds;
       np->dn_stat_dirty = 1;
       np->dn_set_mtime = 0;
     }
   if (np->dn_set_atime)
     {
-      np->dn_stat.st_atim.tv_sec = t.tv_sec;
-      np->dn_stat.st_atim.tv_nsec = t.tv_usec * 1000;
+      np->dn_stat.st_atim.tv_sec = t.seconds;
+      np->dn_stat.st_atim.tv_nsec = t.nanoseconds;
       np->dn_stat_dirty = 1;
       np->dn_set_atime = 0;
     }
   if (np->dn_set_ctime)
     {
-      np->dn_stat.st_ctim.tv_sec = t.tv_sec;
-      np->dn_stat.st_ctim.tv_nsec = t.tv_usec * 1000;
+      np->dn_stat.st_ctim.tv_sec = t.seconds;
+      np->dn_stat.st_ctim.tv_nsec = t.nanoseconds;
       np->dn_stat_dirty = 1;
       np->dn_set_ctime = 0;
     }
-- 
2.49.0


Reply via email to