s3:vfs_fs_capabilities: fix a debug message
[amitay/samba.git] / source3 / modules / vfs_default.c
index 2ee2fd124997f41199c1b277697dbe28a120a50d..17237ac83fc516b7f7baca065a42277abaa63536 100644 (file)
@@ -90,15 +90,69 @@ static int vfswrap_statvfs(struct vfs_handle_struct *handle,  const char *path,
        return sys_statvfs(path, statbuf);
 }
 
-static uint32_t vfswrap_fs_capabilities(struct vfs_handle_struct *handle)
+static uint32_t vfswrap_fs_capabilities(struct vfs_handle_struct *handle,
+               enum timestamp_set_resolution *p_ts_res)
 {
+       connection_struct *conn = handle->conn;
+       uint32_t caps = FILE_CASE_SENSITIVE_SEARCH | FILE_CASE_PRESERVED_NAMES;
+       struct smb_filename *smb_fname_cpath = NULL;
+       NTSTATUS status;
+       int ret = -1;
+
 #if defined(DARWINOS)
        struct vfs_statvfs_struct statbuf;
        ZERO_STRUCT(statbuf);
-       sys_statvfs(handle->conn->connectpath, &statbuf);
-       return statbuf.FsCapabilities;
+       sys_statvfs(conn->connectpath, &statbuf);
+       caps = statbuf.FsCapabilities;
 #endif
-       return FILE_CASE_SENSITIVE_SEARCH | FILE_CASE_PRESERVED_NAMES;
+
+       *p_ts_res = TIMESTAMP_SET_SECONDS;
+
+       /* Work out what timestamp resolution we can
+        * use when setting a timestamp. */
+
+       status = create_synthetic_smb_fname(talloc_tos(),
+                               conn->connectpath,
+                               NULL,
+                               NULL,
+                               &smb_fname_cpath);
+       if (!NT_STATUS_IS_OK(status)) {
+               return caps;
+       }
+
+       ret = SMB_VFS_STAT(conn, smb_fname_cpath);
+       if (ret == -1) {
+               TALLOC_FREE(smb_fname_cpath);
+               return caps;
+       }
+
+       if (smb_fname_cpath->st.st_ex_mtime.tv_nsec ||
+                       smb_fname_cpath->st.st_ex_atime.tv_nsec ||
+                       smb_fname_cpath->st.st_ex_ctime.tv_nsec) {
+               /* If any of the normal UNIX directory timestamps
+                * have a non-zero tv_nsec component assume
+                * we might be able to set sub-second timestamps.
+                * See what filetime set primitives we have.
+                */
+#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)
+               /* utime only allows sec timestamps to be set. */
+               *p_ts_res = TIMESTAMP_SET_SECONDS;
+#endif
+
+               DEBUG(10,("vfswrap_fs_capabilities: timestamp "
+                       "resolution of %s "
+                       "available on share %s, directory %s\n",
+                       *p_ts_res == TIMESTAMP_SET_MSEC ? "msec" : "sec",
+                       lp_servicename(conn->params->service),
+                       conn->connectpath ));
+       }
+       TALLOC_FREE(smb_fname_cpath);
+       return caps;
 }
 
 /* Directory operations */
@@ -595,6 +649,17 @@ static int vfswrap_lstat(vfs_handle_struct *handle,
        return result;
 }
 
+static NTSTATUS vfswrap_translate_name(vfs_handle_struct *handle,
+                                      char **mapped_name,
+                                      enum vfs_translate_direction direction)
+{
+       /* Default behavior is a NOOP */
+
+       if (*mapped_name != NULL)
+               return NT_STATUS_OK;
+
+       return NT_STATUS_INVALID_PARAMETER;
+}
 /********************************************************************
  Given a stat buffer return the allocated size on disk, taking into
  account sparse files.
@@ -788,6 +853,14 @@ static int vfswrap_ntimes(vfs_handle_struct *handle,
                ft->mtime = smb_fname->st.st_ex_mtime;
        }
 
+       if (!null_timespec(ft->create_time) &&
+                       lp_store_create_time(SNUM(handle->conn))) {
+               set_create_timespec_ea(handle->conn,
+                               NULL,
+                               smb_fname,
+                               ft->create_time);
+       }
+
        if ((timespec_compare(&ft->atime,
                                &smb_fname->st.st_ex_atime) == 0) &&
                        (timespec_compare(&ft->mtime,
@@ -795,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);
@@ -817,6 +899,7 @@ static int vfswrap_ntimes(vfs_handle_struct *handle,
        errno = ENOSYS;
        result = -1;
 #endif
+
  out:
        END_PROFILE(syscall_ntimes);
        return result;
@@ -981,10 +1064,10 @@ static bool vfswrap_lock(vfs_handle_struct *handle, files_struct *fsp, int op, S
 }
 
 static int vfswrap_kernel_flock(vfs_handle_struct *handle, files_struct *fsp,
-                               uint32 share_mode)
+                               uint32 share_mode, uint32 access_mask)
 {
        START_PROFILE(syscall_kernel_flock);
-       kernel_flock(fsp->fh->fd, share_mode);
+       kernel_flock(fsp->fh->fd, share_mode, access_mask);
        END_PROFILE(syscall_kernel_flock);
        return 0;
 }
@@ -1155,7 +1238,11 @@ static NTSTATUS vfswrap_streaminfo(vfs_handle_struct *handle,
                if (!NT_STATUS_IS_OK(status)) {
                        return status;
                }
-               ret = SMB_VFS_STAT(handle->conn, smb_fname);
+               if (lp_posix_pathnames()) {
+                       ret = SMB_VFS_LSTAT(handle->conn, smb_fname);
+               } else {
+                       ret = SMB_VFS_STAT(handle->conn, smb_fname);
+               }
                sbuf = smb_fname->st;
                TALLOC_FREE(smb_fname);
        }
@@ -1660,6 +1747,7 @@ static struct vfs_fn_pointers vfs_default_fns = {
        .brl_cancel_windows = vfswrap_brl_cancel_windows,
        .strict_lock = vfswrap_strict_lock,
        .strict_unlock = vfswrap_strict_unlock,
+       .translate_name = vfswrap_translate_name,
 
        /* NT ACL operations. */