diff options
Diffstat (limited to 'source3')
-rw-r--r-- | source3/modules/onefs.h | 3 | ||||
-rw-r--r-- | source3/modules/onefs_streams.c | 128 | ||||
-rw-r--r-- | source3/modules/vfs_onefs.c | 35 |
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, |