diff options
Diffstat (limited to 'source3/modules')
-rw-r--r-- | source3/modules/vfs_default.c | 80 | ||||
-rw-r--r-- | source3/modules/vfs_full_audit.c | 4 | ||||
-rw-r--r-- | source3/modules/vfs_onefs.c | 6 | ||||
-rw-r--r-- | source3/modules/vfs_streams_depot.c | 5 | ||||
-rw-r--r-- | source3/modules/vfs_streams_xattr.c | 5 | ||||
-rw-r--r-- | source3/modules/vfs_tsmsm.c | 5 |
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 = { |