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:56:41 +0000 (15:56 +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 790a0f02ba307009e5e51b0c522b9a7b8afc3d1e..819af5c4195bf9d02bbec1877a4776cfc779b418 100644 (file)
@@ -1016,6 +1016,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);