summaryrefslogtreecommitdiff
path: root/source3/modules
diff options
context:
space:
mode:
Diffstat (limited to 'source3/modules')
-rw-r--r--source3/modules/vfs_default.c80
-rw-r--r--source3/modules/vfs_full_audit.c4
-rw-r--r--source3/modules/vfs_onefs.c6
-rw-r--r--source3/modules/vfs_streams_depot.c5
-rw-r--r--source3/modules/vfs_streams_xattr.c5
-rw-r--r--source3/modules/vfs_tsmsm.c5
6 files changed, 83 insertions, 22 deletions
diff --git a/source3/modules/vfs_default.c b/source3/modules/vfs_default.c
index a793b337a8..b70868eb9f 100644
--- a/source3/modules/vfs_default.c
+++ b/source3/modules/vfs_default.c
@@ -90,15 +90,71 @@ 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_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_SEC;
+#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",
+ *p_ts_res == TIMESTAMP_SET_MSEC ? "msec" : "sec",
+ lp_servicename(conn->cnum),
+ conn->connectpath ));
+ }
+ TALLOC_FREE(smb_fname_cpath);
+ return caps;
}
/* Directory operations */
@@ -788,6 +844,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,
@@ -818,14 +882,6 @@ static int vfswrap_ntimes(vfs_handle_struct *handle,
result = -1;
#endif
- 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);
- }
-
out:
END_PROFILE(syscall_ntimes);
return result;
diff --git a/source3/modules/vfs_full_audit.c b/source3/modules/vfs_full_audit.c
index 4089f22968..6930a5573f 100644
--- a/source3/modules/vfs_full_audit.c
+++ b/source3/modules/vfs_full_audit.c
@@ -710,11 +710,11 @@ static int smb_full_audit_statvfs(struct vfs_handle_struct *handle,
return result;
}
-static uint32_t smb_full_audit_fs_capabilities(struct vfs_handle_struct *handle)
+static uint32_t smb_full_audit_fs_capabilities(struct vfs_handle_struct *handle, enum timestamp_set_resolution *p_ts_res)
{
int result;
- result = SMB_VFS_NEXT_FS_CAPABILITIES(handle);
+ result = SMB_VFS_NEXT_FS_CAPABILITIES(handle, p_ts_res);
do_log(SMB_VFS_OP_FS_CAPABILITIES, true, handle, "");
diff --git a/source3/modules/vfs_onefs.c b/source3/modules/vfs_onefs.c
index 31f0b853fb..865eccdbf5 100644
--- a/source3/modules/vfs_onefs.c
+++ b/source3/modules/vfs_onefs.c
@@ -234,7 +234,7 @@ static int onefs_ntimes(vfs_handle_struct *handle,
return onefs_vtimes_streams(handle, smb_fname, flags, times);
}
-static uint32_t onefs_fs_capabilities(struct vfs_handle_struct *handle)
+static uint32_t onefs_fs_capabilities(struct vfs_handle_struct *handle, enum timestamp_set_resolution *p_ts_res)
{
uint32_t result = 0;
@@ -243,7 +243,9 @@ static uint32_t onefs_fs_capabilities(struct vfs_handle_struct *handle)
result |= FILE_NAMED_STREAMS;
}
- return result | SMB_VFS_NEXT_FS_CAPABILITIES(handle);
+ result |= SMB_VFS_NEXT_FS_CAPABILITIES(handle, p_ts_res);
+ *p_ts_res = TIMESTAMP_SET_MSEC;
+ return result;
}
static struct vfs_fn_pointers onefs_fns = {
diff --git a/source3/modules/vfs_streams_depot.c b/source3/modules/vfs_streams_depot.c
index 2581c7fd5b..d09255a4a2 100644
--- a/source3/modules/vfs_streams_depot.c
+++ b/source3/modules/vfs_streams_depot.c
@@ -875,9 +875,10 @@ static NTSTATUS streams_depot_streaminfo(vfs_handle_struct *handle,
return status;
}
-static uint32_t streams_depot_fs_capabilities(struct vfs_handle_struct *handle)
+static uint32_t streams_depot_fs_capabilities(struct vfs_handle_struct *handle,
+ enum timestamp_set_resolution *p_ts_res)
{
- return SMB_VFS_NEXT_FS_CAPABILITIES(handle) | FILE_NAMED_STREAMS;
+ return SMB_VFS_NEXT_FS_CAPABILITIES(handle, p_ts_res) | FILE_NAMED_STREAMS;
}
static struct vfs_fn_pointers vfs_streams_depot_fns = {
diff --git a/source3/modules/vfs_streams_xattr.c b/source3/modules/vfs_streams_xattr.c
index 3ec38d6cc0..033d0272c2 100644
--- a/source3/modules/vfs_streams_xattr.c
+++ b/source3/modules/vfs_streams_xattr.c
@@ -837,9 +837,10 @@ static NTSTATUS streams_xattr_streaminfo(vfs_handle_struct *handle,
return NT_STATUS_OK;
}
-static uint32_t streams_xattr_fs_capabilities(struct vfs_handle_struct *handle)
+static uint32_t streams_xattr_fs_capabilities(struct vfs_handle_struct *handle,
+ enum timestamp_set_resolution *p_ts_res)
{
- return SMB_VFS_NEXT_FS_CAPABILITIES(handle) | FILE_NAMED_STREAMS;
+ return SMB_VFS_NEXT_FS_CAPABILITIES(handle, p_ts_res) | FILE_NAMED_STREAMS;
}
static ssize_t streams_xattr_pwrite(vfs_handle_struct *handle,
diff --git a/source3/modules/vfs_tsmsm.c b/source3/modules/vfs_tsmsm.c
index 19dc79b581..b5104329e1 100644
--- a/source3/modules/vfs_tsmsm.c
+++ b/source3/modules/vfs_tsmsm.c
@@ -357,9 +357,10 @@ static int tsmsm_set_offline(struct vfs_handle_struct *handle,
return result;
}
-static uint32_t tsmsm_fs_capabilities(struct vfs_handle_struct *handle)
+static uint32_t tsmsm_fs_capabilities(struct vfs_handle_struct *handle,
+ enum timestamp_set_resolution *p_ts_res)
{
- return SMB_VFS_NEXT_FS_CAPABILITIES(handle) | FILE_SUPPORTS_REMOTE_STORAGE | FILE_SUPPORTS_REPARSE_POINTS;
+ return SMB_VFS_NEXT_FS_CAPABILITIES(handle, p_ts_res) | FILE_SUPPORTS_REMOTE_STORAGE | FILE_SUPPORTS_REPARSE_POINTS;
}
static struct vfs_fn_pointers tsmsm_fns = {