]> Zhao Yanbai Git Server - minix.git/commitdiff
hgfs: subsecond timestamp precision
authorDavid van Moolenbroek <david@minix3.org>
Thu, 29 Mar 2012 23:39:12 +0000 (01:39 +0200)
committerDavid van Moolenbroek <david@minix3.org>
Thu, 29 Mar 2012 23:40:07 +0000 (01:40 +0200)
Slightly cleaned up version of patch contributed by Antoine Leca.

include/minix/hgfs.h
lib/libhgfs/proto.h
lib/libhgfs/time.c
servers/hgfs/stat.c

index 6a17e1dfa0b5e10a7f04e189a1858ab38155086e..22dc09db4401246b50e00dffbff0526c2189677e 100644 (file)
@@ -5,6 +5,7 @@
 
 #include <sys/types.h>
 #include <minix/u64.h>
+#include <time.h>
 
 typedef void *hgfs_file_t;             /* handle to open file */
 typedef void *hgfs_dir_t;              /* handle to directory search */
@@ -13,10 +14,10 @@ struct hgfs_attr {
   u32_t a_mask;                                /* which fields to retrieve/set */
   mode_t a_mode;                       /* file type and permissions */
   u64_t a_size;                                /* file size */
-  time_t a_crtime;                     /* file creation time */
-  time_t a_atime;                      /* file access time */
-  time_t a_mtime;                      /* file modification time */
-  time_t a_ctime;                      /* file change time */
+  struct timespec a_crtime;            /* file creation time */
+  struct timespec a_atime;             /* file access time */
+  struct timespec a_mtime;             /* file modification time */
+  struct timespec a_ctime;             /* file change time */
 };
 
 #define HGFS_ATTR_SIZE         0x01    /* get/set file size */
index 8e497501abdd723a97c6787e9a9ebfadf66d0811..7d38c72edd6e94aa8cf753839fc95b4e98c3a83e 100644 (file)
@@ -47,5 +47,5 @@ void rpc_close(void);
 #define time_put PREFIX(time_put)
 #define time_get PREFIX(time_get)
 void time_init(void);
-void time_put(time_t *timep);
-void time_get(time_t *timep);
+void time_put(struct timespec *tsp);
+void time_get(struct timespec *tsp);
index b14d5268896823dd890bb7ffb7e30bb650db37d9..1dc80605691e0e0beff5edc1b4d3aa974f35d2cb 100644 (file)
@@ -7,7 +7,7 @@ static u64_t time_offset;
 /*===========================================================================*
  *                             time_init                                    *
  *===========================================================================*/
-void time_init()
+void time_init(void)
 {
 /* Initialize the time conversion module.
  */
@@ -15,55 +15,55 @@ void time_init()
   /* Generate a 64-bit value for the offset to use in time conversion. The
    * HGFS time format uses Windows' FILETIME standard, expressing time in
    * 100ns-units since Jan 1, 1601 UTC. The value that is generated is
-   * 116444736000000000.
+   * the difference between that time and the UNIX epoch, in 100ns units.
    */
   /* FIXME: we currently do not take into account timezones. */
-  time_offset = make64(3577643008UL, 27111902UL);
+  time_offset = mul64u(116444736, 1000000000);
 }
 
 /*===========================================================================*
  *                             time_put                                     *
  *===========================================================================*/
-void time_put(timep)
-time_t *timep;
+void time_put(struct timespec *tsp)
 {
-/* Store a UNIX timestamp pointed to by the given pointer onto the RPC buffer,
+/* Store a POSIX timestamp pointed to by the given pointer onto the RPC buffer,
  * in HGFS timestamp format. If a NULL pointer is given, store a timestamp of
  * zero instead.
  */
   u64_t hgfstime;
 
-  if (timep != NULL) {
-       hgfstime = add64(mul64u(*timep, 10000000), time_offset);
+  if (tsp != NULL) {
+       hgfstime = add64ul(mul64u(tsp->tv_sec, 10000000), tsp->tv_nsec / 100);
+       hgfstime = add64(hgfstime, time_offset);
 
        RPC_NEXT32 = ex64lo(hgfstime);
        RPC_NEXT32 = ex64hi(hgfstime);
   } else {
-       RPC_NEXT32 = 0;
-       RPC_NEXT32 = 0;
+       RPC_NEXT32 = 0;
+       RPC_NEXT32 = 0;
   }
 }
 
 /*===========================================================================*
  *                             time_get                                     *
  *===========================================================================*/
-void time_get(timep)
-time_t *timep;
+void time_get(struct timespec *tsp)
 {
-/* Get a HGFS timestamp from the RPC buffer, convert it into a UNIX timestamp,
+/* Get a HGFS timestamp from the RPC buffer, convert it into a POSIX timestamp,
  * and store the result in the given time pointer. If the given pointer is
  * NULL, however, simply skip over the timestamp in the RPC buffer.
  */
   u64_t hgfstime;
   u32_t time_lo, time_hi;
 
-  if (timep != NULL) {
-       time_lo = RPC_NEXT32;
-       time_hi = RPC_NEXT32;
+  if (tsp != NULL) {
+       time_lo = RPC_NEXT32;
+       time_hi = RPC_NEXT32;
 
-       hgfstime = make64(time_lo, time_hi);
+       hgfstime = sub64(make64(time_lo, time_hi), time_offset);
 
-       *timep = div64u(sub64(hgfstime, time_offset), 10000000);
+       tsp->tv_sec = div64u(hgfstime, 10000000);
+       tsp->tv_nsec = rem64u(hgfstime, 10000000) * 100;
   }
   else RPC_ADVANCE(sizeof(u32_t) * 2);
 }
index 0924337cd6ab2d481f5e6d5a8ccbda93f6534693..cdb6d5661b485bf8dce8e9901c0b5a6db6155c79 100644 (file)
@@ -56,8 +56,8 @@ int do_stat()
   if ((ino = find_inode(ino_nr)) == NULL)
        return EINVAL;
 
-  attr.a_mask = HGFS_ATTR_MODE | HGFS_ATTR_SIZE | HGFS_ATTR_ATIME |
-               HGFS_ATTR_MTIME | HGFS_ATTR_CTIME;
+  attr.a_mask = HGFS_ATTR_MODE | HGFS_ATTR_SIZE | HGFS_ATTR_CRTIME |
+               HGFS_ATTR_ATIME | HGFS_ATTR_MTIME | HGFS_ATTR_CTIME;
 
   if ((r = verify_inode(ino, path, &attr)) != OK)
        return r;
@@ -74,9 +74,10 @@ int do_stat()
        stat.st_size = LONG_MAX;
   else
        stat.st_size = ex64lo(attr.a_size);
-  stat.st_atime = attr.a_atime;
-  stat.st_mtime = attr.a_mtime;
-  stat.st_ctime = attr.a_ctime;
+  stat.st_atimespec = attr.a_atime;
+  stat.st_mtimespec = attr.a_mtime;
+  stat.st_ctimespec = attr.a_ctime;
+  stat.st_birthtimespec = attr.a_crtime;
 
   stat.st_blocks = stat.st_size / S_BLKSIZE;
   if (stat.st_size % S_BLKSIZE != 0)
@@ -159,8 +160,10 @@ int do_utime()
 
   attr.a_mask = HGFS_ATTR_ATIME | HGFS_ATTR_MTIME | HGFS_ATTR_ATIME_SET |
        HGFS_ATTR_MTIME_SET;
-  attr.a_atime = m_in.REQ_ACTIME;
-  attr.a_mtime = m_in.REQ_MODTIME;
+  attr.a_atime.tv_sec = m_in.REQ_ACTIME;
+  attr.a_atime.tv_nsec = 0;
+  attr.a_mtime.tv_sec = m_in.REQ_MODTIME;
+  attr.a_mtime.tv_nsec = 0;
 
   return hgfs_setattr(path, &attr);
 }