Modify OneFS module to support new NTIMES interfaces
authortodd stecher <todd.stecher@gmail.com>
Sat, 24 Jan 2009 00:55:18 +0000 (16:55 -0800)
committerTim Prouty <tprouty@samba.org>
Sat, 24 Jan 2009 05:05:38 +0000 (21:05 -0800)
source3/modules/onefs.h
source3/modules/onefs_streams.c
source3/modules/vfs_onefs.c

index e189fc45702c650ad0c4c700820bccb1fd5177fb..9c1c1647ba55a36ed7054463198aa55195ff6d59 100644 (file)
@@ -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);
 
index 184fe4f0c99a4edc38c7422739bd0b0bcdb85644..e9543e237f42577117f7d0fa8ca864ed8319ab4d 100644 (file)
@@ -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)
 {
index 6b42c0f373f22d3dde647eb1645961f90976a047..e048e8958972bdba160a5658972ea4f9b62052f0 100644 (file)
@@ -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,