From 02d624c46f20c3685431cb746fb711fcf30b6b87 Mon Sep 17 00:00:00 2001 From: Samuel Cabrero Date: Tue, 13 Apr 2021 14:40:24 +0200 Subject: [PATCH] s3: VFS: gpfs: Implement SMB_VFS_FNTIMES() Signed-off-by: Samuel Cabrero Reviewed-by: Ralph Boehme --- source3/modules/vfs_gpfs.c | 90 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 90 insertions(+) diff --git a/source3/modules/vfs_gpfs.c b/source3/modules/vfs_gpfs.c index a936b7aa2ec..1d144bfaeca 100644 --- a/source3/modules/vfs_gpfs.c +++ b/source3/modules/vfs_gpfs.c @@ -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, -- 2.47.3