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 */
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.
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,
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);
errno = ENOSYS;
result = -1;
#endif
+
out:
END_PROFILE(syscall_ntimes);
return result;
}
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;
}
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);
}
.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. */