summaryrefslogtreecommitdiff
path: root/source3
diff options
context:
space:
mode:
Diffstat (limited to 'source3')
-rw-r--r--source3/modules/onefs.h3
-rw-r--r--source3/modules/onefs_streams.c128
-rw-r--r--source3/modules/vfs_onefs.c35
3 files changed, 124 insertions, 42 deletions
diff --git a/source3/modules/onefs.h b/source3/modules/onefs.h
index e189fc4570..9c1c1647ba 100644
--- a/source3/modules/onefs.h
+++ b/source3/modules/onefs.h
@@ -101,6 +101,9 @@ NTSTATUS onefs_streaminfo(vfs_handle_struct *handle,
unsigned int *num_streams,
struct stream_struct **streams);
+int onefs_vtimes_streams(vfs_handle_struct *handle, const char *fname,
+ int flags, struct timespec times[3]);
+
NTSTATUS onefs_fget_nt_acl(vfs_handle_struct *handle, files_struct *fsp,
uint32 security_info, SEC_DESC **ppdesc);
diff --git a/source3/modules/onefs_streams.c b/source3/modules/onefs_streams.c
index 184fe4f0c9..e9543e237f 100644
--- a/source3/modules/onefs_streams.c
+++ b/source3/modules/onefs_streams.c
@@ -51,6 +51,25 @@ NTSTATUS onefs_split_ntfs_stream_name(TALLOC_CTX *mem_ctx, const char *fname,
return NT_STATUS_OK;
}
+int onefs_is_stream(const char *path, char **pbase, char **pstream,
+ bool *is_stream)
+{
+ (*is_stream) = is_ntfs_stream_name(path);
+
+ if (!(*is_stream)) {
+ return 0;
+ }
+
+ if (!NT_STATUS_IS_OK(onefs_split_ntfs_stream_name(talloc_tos(), path,
+ pbase, pstream))) {
+ DEBUG(10, ("onefs_split_ntfs_stream_name failed\n"));
+ errno = ENOMEM;
+ return -1;
+ }
+
+ return 0;
+}
+
int onefs_close(vfs_handle_struct *handle, struct files_struct *fsp)
{
int ret2, ret = 0;
@@ -141,27 +160,18 @@ int onefs_rename(vfs_handle_struct *handle, const char *oldname,
char *nbase = NULL;
char *nsname = NULL;
- old_is_stream = is_ntfs_stream_name(oldname);
- new_is_stream = is_ntfs_stream_name(newname);
-
- if (!old_is_stream && !new_is_stream) {
- return SMB_VFS_NEXT_RENAME(handle, oldname, newname);
- }
-
frame = talloc_stackframe();
- if (!NT_STATUS_IS_OK(onefs_split_ntfs_stream_name(talloc_tos(),
- oldname, &obase,
- &osname))) {
- errno = ENOMEM;
- goto done;
- }
+ ret = onefs_is_stream(oldname, &obase, &osname, &old_is_stream);
+ if (ret)
+ return ret;
- if (!NT_STATUS_IS_OK(onefs_split_ntfs_stream_name(talloc_tos(),
- newname, &nbase,
- &nsname))) {
- errno = ENOMEM;
- goto done;
+ ret = onefs_is_stream(newname, &nbase, &nsname, &new_is_stream);
+ if (ret)
+ return ret;
+
+ if (!old_is_stream && !new_is_stream) {
+ return SMB_VFS_NEXT_RENAME(handle, oldname, newname);
}
dir_fd = get_stream_dir_fd(handle->conn, obase, NULL);
@@ -237,18 +247,17 @@ static int stat_stream(vfs_handle_struct *handle, const char *base,
int onefs_stat(vfs_handle_struct *handle, const char *path,
SMB_STRUCT_STAT *sbuf)
{
+ int ret;
+ bool is_stream;
char *base = NULL;
char *stream = NULL;
- if (!is_ntfs_stream_name(path)) {
- return SMB_VFS_NEXT_STAT(handle, path, sbuf);
- }
+ ret = onefs_is_stream(path, &base, &stream, &is_stream);
+ if (ret)
+ return ret;
- if (!NT_STATUS_IS_OK(onefs_split_ntfs_stream_name(talloc_tos(), path,
- &base, &stream))) {
- DEBUG(10, ("onefs_split_ntfs_stream_name failed\n"));
- errno = ENOMEM;
- return -1;
+ if (!is_stream) {
+ return SMB_VFS_NEXT_STAT(handle, path, sbuf);
}
/* If it's the ::$DATA stream just stat the base file name. */
@@ -285,18 +294,17 @@ int onefs_fstat(vfs_handle_struct *handle, struct files_struct *fsp,
int onefs_lstat(vfs_handle_struct *handle, const char *path,
SMB_STRUCT_STAT *sbuf)
{
+ int ret;
+ bool is_stream;
char *base = NULL;
char *stream = NULL;
- if (!is_ntfs_stream_name(path)) {
- return SMB_VFS_NEXT_LSTAT(handle, path, sbuf);
- }
+ ret = onefs_is_stream(path, &base, &stream, &is_stream);
+ if (ret)
+ return ret;
- if (!NT_STATUS_IS_OK(onefs_split_ntfs_stream_name(talloc_tos(), path,
- &base, &stream))) {
- DEBUG(10, ("onefs_split_ntfs_stream_name failed\n"));
- errno = ENOMEM;
- return -1;
+ if (!is_stream) {
+ return SMB_VFS_NEXT_LSTAT(handle, path, sbuf);
}
/* If it's the ::$DATA stream just stat the base file name. */
@@ -309,19 +317,19 @@ int onefs_lstat(vfs_handle_struct *handle, const char *path,
int onefs_unlink(vfs_handle_struct *handle, const char *path)
{
+ int ret;
+ bool is_stream;
char *base = NULL;
char *stream = NULL;
- int dir_fd, ret, saved_errno;
+ int dir_fd, saved_errno;
- if (!is_ntfs_stream_name(path)) {
- return SMB_VFS_NEXT_UNLINK(handle, path);
+ ret = onefs_is_stream(path, &base, &stream, &is_stream);
+ if (ret) {
+ return ret;
}
- if (!NT_STATUS_IS_OK(onefs_split_ntfs_stream_name(talloc_tos(), path,
- &base, &stream))) {
- DEBUG(10, ("onefs_split_ntfs_stream_name failed\n"));
- errno = ENOMEM;
- return -1;
+ if (!is_stream) {
+ return SMB_VFS_NEXT_UNLINK(handle, path);
}
/* If it's the ::$DATA stream just unlink the base file name. */
@@ -342,6 +350,42 @@ int onefs_unlink(vfs_handle_struct *handle, const char *path)
return ret;
}
+int onefs_vtimes_streams(vfs_handle_struct *handle, const char *fname,
+ int flags, struct timespec times[3])
+{
+ int ret;
+ bool is_stream;
+ char *base;
+ char *stream;
+ int dirfd;
+ int saved_errno;
+
+ START_PROFILE(syscall_ntimes);
+
+ ret = onefs_is_stream(fname, &base, &stream, &is_stream);
+ if (ret)
+ return ret;
+
+ if (!is_stream) {
+ ret = vtimes(fname, times, flags);
+ return ret;
+ }
+
+ dirfd = get_stream_dir_fd(handle->conn, base, NULL);
+ if (dirfd < -1) {
+ return -1;
+ }
+
+ ret = enc_vtimesat(dirfd, stream, ENC_DEFAULT, times, flags);
+
+ END_PROFILE(syscall_ntimes);
+
+ saved_errno = errno;
+ close(dirfd);
+ errno = saved_errno;
+ return ret;
+}
+
int onefs_chflags(vfs_handle_struct *handle, const char *path,
unsigned int flags)
{
diff --git a/source3/modules/vfs_onefs.c b/source3/modules/vfs_onefs.c
index 6b42c0f373..e048e89589 100644
--- a/source3/modules/vfs_onefs.c
+++ b/source3/modules/vfs_onefs.c
@@ -66,6 +66,39 @@ static int onefs_statvfs(vfs_handle_struct *handle, const char *path,
return result;
}
+static int onefs_ntimes(vfs_handle_struct *handle, const char *fname,
+ struct smb_file_time *ft)
+{
+ int flags = 0;
+ struct timespec times[3];
+
+ if (!null_timespec(ft->atime)) {
+ flags |= VT_ATIME;
+ times[0] = ft->atime;
+ DEBUG(6,("**** onefs_ntimes: actime: %s.%d\n",
+ time_to_asc(convert_timespec_to_time_t(ft->atime)),
+ ft->atime.tv_nsec));
+ }
+
+ if (!null_timespec(ft->mtime)) {
+ flags |= VT_MTIME;
+ times[1] = ft->mtime;
+ DEBUG(6,("**** onefs_ntimes: modtime: %s.%d\n",
+ time_to_asc(convert_timespec_to_time_t(ft->mtime)),
+ ft->mtime.tv_nsec));
+ }
+
+ if (!null_timespec(ft->create_time)) {
+ flags |= VT_BTIME;
+ times[2] = ft->create_time;
+ DEBUG(6,("**** onefs_ntimes: createtime: %s.%d\n",
+ time_to_asc(convert_timespec_to_time_t(ft->create_time)),
+ ft->create_time.tv_nsec));
+ }
+
+ return onefs_vtimes_streams(handle, fname, flags, times);
+}
+
static uint32_t onefs_fs_capabilities(struct vfs_handle_struct *handle)
{
return SMB_VFS_NEXT_FS_CAPABILITIES(handle) | FILE_NAMED_STREAMS;
@@ -92,6 +125,8 @@ static vfs_op_tuple onefs_ops[] = {
SMB_VFS_LAYER_TRANSPARENT},
{SMB_VFS_OP(onefs_unlink), SMB_VFS_OP_UNLINK,
SMB_VFS_LAYER_TRANSPARENT},
+ {SMB_VFS_OP(onefs_ntimes), SMB_VFS_OP_NTIMES,
+ SMB_VFS_LAYER_OPAQUE},
{SMB_VFS_OP(onefs_chflags), SMB_VFS_OP_CHFLAGS,
SMB_VFS_LAYER_TRANSPARENT},
{SMB_VFS_OP(onefs_streaminfo), SMB_VFS_OP_STREAMINFO,