s3: add support for full windows timestamps resolution on files
authorBjörn Jacke <bj@sernet.de>
Wed, 4 Nov 2009 10:15:31 +0000 (11:15 +0100)
committerBjörn Jacke <bj@sernet.de>
Wed, 4 Nov 2009 14:54:51 +0000 (15:54 +0100)
setting nanosecond timestamps using utimensat() was first supported by Linux
kernel 2.6.22 and glibc 2.6. It's specified in POSIX.1-2008.

This effectively makes us use Windows' full 100ns timestamp resolution -
actually just an improvement from 10^-6 to 10^-7.

For now Linux CIFS vfs will also just be able to make use of 100ns resolution,
not 1ns.

source3/configure.in
source3/modules/vfs_default.c

index 83ea8579e6ae65e3160b034b9ab94dd78a2aa81c..715f1598ef0deba8d04e3b5f248731e7363e8a46 100644 (file)
@@ -1066,6 +1066,7 @@ AC_CHECK_FUNCS(setenv strcasecmp fcvt fcvtl)
 AC_CHECK_FUNCS(syslog vsyslog timegm)
 AC_CHECK_FUNCS(setlocale nl_langinfo)
 AC_CHECK_FUNCS(nanosleep,,[AC_CHECK_LIB_EXT(rt, LIBS, nanosleep)])
+AC_CHECK_FUNCS(utimensat)
 AC_CHECK_FUNCS(mlock munlock mlockall munlockall)
 AC_CHECK_FUNCS(memalign posix_memalign hstrerror)
 AC_CHECK_HEADERS(sys/mman.h)
index 036a4380025bc1e314140575734b34eb572b9b0f..b40e2ce27aabcfb2c5fc459b68082ab21359dfcf 100644 (file)
@@ -134,7 +134,9 @@ static uint32_t vfswrap_fs_capabilities(struct vfs_handle_struct *handle,
                 * we might be able to set sub-second timestamps.
                 * See what filetime set primitives we have.
                 */
-#if defined(HAVE_UTIMES)
+#if defined(HAVE_UTIMENSAT)
+               *p_ts_res = TIMESTAMP_SET_NT_OR_BETTER;
+#elif defined(HAVE_UTIMES)
                /* utimes allows msec timestamps to be set. */
                *p_ts_res = TIMESTAMP_SET_MSEC;
 #elif defined(HAVE_UTIME)
@@ -142,10 +144,6 @@ static uint32_t vfswrap_fs_capabilities(struct vfs_handle_struct *handle,
                *p_ts_res = TIMESTAMP_SET_SECONDS;
 #endif
 
-               /* TODO. Add a configure test for the Linux
-                * nsec timestamp set system call, and use it
-                * if available....
-                */
                DEBUG(10,("vfswrap_fs_capabilities: timestamp "
                        "resolution of %s "
                        "available on share %s, directory %s\n",
@@ -870,7 +868,16 @@ static int vfswrap_ntimes(vfs_handle_struct *handle,
                return 0;
        }
 
-#if defined(HAVE_UTIMES)
+#if defined(HAVE_UTIMENSAT)
+       if (ft != NULL) {
+               struct timespec ts[2];
+               ts[0] = ft->atime;
+               ts[1] = ft->mtime;
+               result = utimensat(AT_FDCWD, smb_fname->base_name, ts, 0);
+       } else {
+               result = utimensat(AT_FDCWD, smb_fname->base_name, NULL, 0);
+       }
+#elif defined(HAVE_UTIMES)
        if (ft != NULL) {
                struct timeval tv[2];
                tv[0] = convert_timespec_to_timeval(ft->atime);