]> git.ipfire.org Git - thirdparty/samba.git/commitdiff
s3: VFS: gpfs: Implement SMB_VFS_FNTIMES()
authorSamuel Cabrero <scabrero@samba.org>
Tue, 13 Apr 2021 12:40:24 +0000 (14:40 +0200)
committerSamuel Cabrero <scabrero@sn-devel-184>
Mon, 19 Apr 2021 12:28:30 +0000 (12:28 +0000)
Signed-off-by: Samuel Cabrero <scabrero@samba.org>
Reviewed-by: Ralph Boehme <slow@samba.org>
source3/modules/vfs_gpfs.c

index a936b7aa2ec67cc5977fb0c0337704382b7087b0..1d144bfaeca2947bfe32164ad197a9266f2daae0 100644 (file)
@@ -1897,6 +1897,95 @@ static int vfs_gpfs_ntimes(struct vfs_handle_struct *handle,
 
 }
 
+static int smbd_gpfs_set_times(int fd, char *path, struct smb_file_time *ft)
+{
+       gpfs_timestruc_t gpfs_times[4];
+       int flags = 0;
+       int rc;
+
+       ZERO_ARRAY(gpfs_times);
+       timespec_to_gpfs_time(ft->atime, gpfs_times, 0, &flags);
+       timespec_to_gpfs_time(ft->mtime, gpfs_times, 1, &flags);
+       /* No good mapping from LastChangeTime to ctime, not storing */
+       timespec_to_gpfs_time(ft->create_time, gpfs_times, 3, &flags);
+
+       if (!flags) {
+               DBG_DEBUG("nothing to do, return to avoid EINVAL\n");
+               return 0;
+       }
+
+       rc = gpfswrap_set_times(fd, flags, gpfs_times);
+
+       if (rc != 0 && errno != ENOSYS) {
+               DBG_WARNING("gpfs_set_times() returned with error %s for %s\n",
+                           strerror(errno),
+                           path);
+       }
+
+       return rc;
+}
+
+static int vfs_gpfs_fntimes(struct vfs_handle_struct *handle,
+               files_struct *fsp,
+               struct smb_file_time *ft)
+{
+
+       struct gpfs_winattr attrs;
+       int ret;
+       struct gpfs_config_data *config;
+
+       SMB_VFS_HANDLE_GET_DATA(handle,
+                               config,
+                               struct gpfs_config_data,
+                               return -1);
+
+       /* Try to use gpfs_set_times if it is enabled and available */
+       if (config->settimes) {
+               ret = smbd_gpfs_set_times(fsp_get_io_fd(fsp),
+                                         fsp->fsp_name->base_name,
+                                         ft);
+               if (ret == 0 || (ret == -1 && errno != ENOSYS)) {
+                       return ret;
+               }
+       }
+
+       DBG_DEBUG("gpfs_set_times() not available or disabled, "
+                 "use ntimes and winattr\n");
+
+       ret = SMB_VFS_NEXT_FNTIMES(handle, fsp, ft);
+       if (ret == -1) {
+               /* don't complain if access was denied */
+               if (errno != EPERM && errno != EACCES) {
+                       DBG_WARNING("SMB_VFS_NEXT_FNTIMES failed: %s",
+                                   strerror(errno));
+               }
+               return -1;
+       }
+
+       if (is_omit_timespec(&ft->create_time)) {
+               DBG_DEBUG("Create Time is NULL\n");
+               return 0;
+       }
+
+       if (!config->winattr) {
+               return 0;
+       }
+
+       attrs.winAttrs = 0;
+       attrs.creationTime.tv_sec = ft->create_time.tv_sec;
+       attrs.creationTime.tv_nsec = ft->create_time.tv_nsec;
+
+       ret = gpfswrap_set_winattrs(fsp_get_io_fd(fsp),
+                                   GPFS_WINATTR_SET_CREATION_TIME,
+                                   &attrs);
+       if (ret == -1 && errno != ENOSYS) {
+               DBG_WARNING("Set GPFS ntimes failed %d\n", ret);
+               return -1;
+       }
+
+       return 0;
+}
+
 static int vfs_gpfs_fallocate(struct vfs_handle_struct *handle,
                              struct files_struct *fsp, uint32_t mode,
                              off_t offset, off_t len)
@@ -2567,6 +2656,7 @@ static struct vfs_fn_pointers vfs_gpfs_fns = {
        .stat_fn = vfs_gpfs_stat,
        .lstat_fn = vfs_gpfs_lstat,
        .ntimes_fn = vfs_gpfs_ntimes,
+       .fntimes_fn = vfs_gpfs_fntimes,
        .aio_force_fn = vfs_gpfs_aio_force,
        .sendfile_fn = vfs_gpfs_sendfile,
        .fallocate_fn = vfs_gpfs_fallocate,