}
+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)
.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,