From bf906afb071b588f6dd14dcb974fa6cc69d48da3 Mon Sep 17 00:00:00 2001 From: Ralph Boehme Date: Fri, 30 Jul 2021 15:17:44 +0200 Subject: [PATCH 01/13] smbd: avoid calling creating a pathref in smb_set_file_dosmode() We already have a fsp with a valid fsp->base_fsp if it's a stream. Also remove the struct smb_filename arg, it's not needed, the only caller already checks for a valid fsp. BUG: https://bugzilla.samba.org/show_bug.cgi?id=14771 Signed-off-by: Ralph Boehme Reviewed-by: Christof Schmitt (cherry picked from commit bcd6bed7b8611654a7e9752b258541f89414b020) --- source3/smbd/trans2.c | 67 +++++++++++++++++-------------------------- 1 file changed, 27 insertions(+), 40 deletions(-) diff --git a/source3/smbd/trans2.c b/source3/smbd/trans2.c index b9e2786eda6..a6bd232f679 100644 --- a/source3/smbd/trans2.c +++ b/source3/smbd/trans2.c @@ -6655,61 +6655,48 @@ NTSTATUS smb_set_file_time(connection_struct *conn, static NTSTATUS smb_set_file_dosmode(connection_struct *conn, struct files_struct *fsp, - struct smb_filename *smb_fname, uint32_t dosmode) { - struct smb_filename *smb_fname_base; - NTSTATUS status; + struct files_struct *dos_fsp = NULL; + uint32_t current_dosmode; + int ret; - if (!VALID_STAT(smb_fname->st)) { + if (!VALID_STAT(fsp->fsp_name->st)) { return NT_STATUS_OBJECT_NAME_NOT_FOUND; } - /* Always operate on the base_name, even if a stream was passed in. */ - status = synthetic_pathref(talloc_tos(), - conn->cwd_fsp, - smb_fname->base_name, - NULL, - NULL, - smb_fname->twrp, - smb_fname->flags, - &smb_fname_base); - - /* do we handle link as non error here ? */ - if (!NT_STATUS_IS_OK(status)) { - return status; - } + dos_fsp = fsp->base_fsp != NULL ? fsp->base_fsp : fsp; - if (dosmode) { - if (S_ISDIR(smb_fname_base->st.st_ex_mode)) { + if (dosmode != 0) { + if (S_ISDIR(fsp->fsp_name->st.st_ex_mode)) { dosmode |= FILE_ATTRIBUTE_DIRECTORY; } else { dosmode &= ~FILE_ATTRIBUTE_DIRECTORY; } } - DEBUG(6,("smb_set_file_dosmode: dosmode: 0x%x\n", (unsigned int)dosmode)); + DBG_DEBUG("dosmode: 0x%" PRIx32 "\n", dosmode); /* check the mode isn't different, before changing it */ - if ((dosmode != 0) && (dosmode != fdos_mode(fsp))) { - DEBUG(10,("smb_set_file_dosmode: file %s : setting dos mode " - "0x%x\n", smb_fname_str_dbg(smb_fname_base), - (unsigned int)dosmode)); - - if(file_set_dosmode(conn, smb_fname_base, dosmode, NULL, - false)) { - DEBUG(2,("smb_set_file_dosmode: file_set_dosmode of " - "%s failed (%s)\n", - smb_fname_str_dbg(smb_fname_base), - strerror(errno))); - status = map_nt_error_from_unix(errno); - goto out; - } + if (dosmode == 0) { + return NT_STATUS_OK; } - status = NT_STATUS_OK; - out: - TALLOC_FREE(smb_fname_base); - return status; + current_dosmode = fdos_mode(dos_fsp); + if (dosmode == current_dosmode) { + return NT_STATUS_OK; + } + + DBG_DEBUG("file %s : setting dos mode 0x%" PRIx32 "\n", + fsp_str_dbg(dos_fsp), dosmode); + + ret = file_set_dosmode(conn, dos_fsp->fsp_name, dosmode, NULL, false); + if (ret != 0) { + DBG_WARNING("file_set_dosmode of %s failed: %s\n", + fsp_str_dbg(dos_fsp), strerror(errno)); + return map_nt_error_from_unix(errno); + } + + return NT_STATUS_OK; } /**************************************************************************** @@ -7912,7 +7899,7 @@ static NTSTATUS smb_set_file_basic_info(connection_struct *conn, /* Set the attributes */ dosmode = IVAL(pdata,32); - status = smb_set_file_dosmode(conn, fsp, smb_fname, dosmode); + status = smb_set_file_dosmode(conn, fsp, dosmode); if (!NT_STATUS_IS_OK(status)) { return status; } -- 2.31.1 From e74d143688f6e51d0307f5a692fe2edcb8654804 Mon Sep 17 00:00:00 2001 From: Ralph Boehme Date: Fri, 6 Aug 2021 12:03:38 +0200 Subject: [PATCH 02/13] vfs_gpfs: call SMB_VFS_NEXT_CONNECT() before running some module initialization code No change in behaviour. Prepares for a subsequent commit that checks for IPC shares. BUG: https://bugzilla.samba.org/show_bug.cgi?id=14771 Signed-off-by: Ralph Boehme Reviewed-by: Christof Schmitt (cherry picked from commit 145e739c440d39651d4f3d30682035ab868488ba) --- source3/modules/vfs_gpfs.c | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/source3/modules/vfs_gpfs.c b/source3/modules/vfs_gpfs.c index d74bc43db0e..01c635e3f81 100644 --- a/source3/modules/vfs_gpfs.c +++ b/source3/modules/vfs_gpfs.c @@ -1873,6 +1873,11 @@ static int vfs_gpfs_connect(struct vfs_handle_struct *handle, int ret; bool check_fstype; + ret = SMB_VFS_NEXT_CONNECT(handle, service, user); + if (ret < 0) { + return ret; + } + gpfswrap_lib_init(0); config = talloc_zero(handle->conn, struct gpfs_config_data); @@ -1882,12 +1887,6 @@ static int vfs_gpfs_connect(struct vfs_handle_struct *handle, return -1; } - ret = SMB_VFS_NEXT_CONNECT(handle, service, user); - if (ret < 0) { - TALLOC_FREE(config); - return ret; - } - check_fstype = lp_parm_bool(SNUM(handle->conn), "gpfs", "check_fstype", true); -- 2.31.1 From 4e6dd9b3e7b8729cf096f485366be9bb8eaaa5f0 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 11 Aug 2021 16:23:24 +0200 Subject: [PATCH 03/13] vfs_gpfs: don't check for struct gpfs_config_data in vfs_gpfs_[l]stat() This is unused and the config object won't be avilable for IPC$ anymore with the next commit. BUG: https://bugzilla.samba.org/show_bug.cgi?id=14771 Signed-off-by: Stefan Metzmacher Reviewed-by: Ralph Boehme Reviewed-by: Christof Schmitt (cherry picked from commit 070dce224bbe190266682c5e362bc2b0ed798ecc) --- source3/modules/vfs_gpfs.c | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/source3/modules/vfs_gpfs.c b/source3/modules/vfs_gpfs.c index 01c635e3f81..ad0c2470d16 100644 --- a/source3/modules/vfs_gpfs.c +++ b/source3/modules/vfs_gpfs.c @@ -1616,11 +1616,6 @@ static int vfs_gpfs_stat(struct vfs_handle_struct *handle, struct smb_filename *smb_fname) { int ret; - struct gpfs_config_data *config; - - SMB_VFS_HANDLE_GET_DATA(handle, config, - struct gpfs_config_data, - return -1); ret = SMB_VFS_NEXT_STAT(handle, smb_fname); if (ret == -1 && errno == EACCES) { @@ -1635,11 +1630,6 @@ static int vfs_gpfs_lstat(struct vfs_handle_struct *handle, struct smb_filename *smb_fname) { int ret; - struct gpfs_config_data *config; - - SMB_VFS_HANDLE_GET_DATA(handle, config, - struct gpfs_config_data, - return -1); ret = SMB_VFS_NEXT_LSTAT(handle, smb_fname); if (ret == -1 && errno == EACCES) { -- 2.31.1 From b520399f94de608b1b983ac4f001bdab23b2ebf6 Mon Sep 17 00:00:00 2001 From: Ralph Boehme Date: Fri, 6 Aug 2021 12:05:44 +0200 Subject: [PATCH 04/13] vfs_gpfs: make vfs_gpfs_connect() a no-op on IPC shares We don't ever expect any filesystem IO operations to be called on an IPC shares, so there's no need to initialize the module here. BUG: https://bugzilla.samba.org/show_bug.cgi?id=14771 Signed-off-by: Ralph Boehme Reviewed-by: Christof Schmitt (cherry picked from commit 1a3ac7a940fbb4ad8575ee3b0c56c9de2bf4b1f6) --- source3/modules/vfs_gpfs.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/source3/modules/vfs_gpfs.c b/source3/modules/vfs_gpfs.c index ad0c2470d16..0aed912c022 100644 --- a/source3/modules/vfs_gpfs.c +++ b/source3/modules/vfs_gpfs.c @@ -1868,6 +1868,10 @@ static int vfs_gpfs_connect(struct vfs_handle_struct *handle, return ret; } + if (IS_IPC(handle->conn)) { + return 0; + } + gpfswrap_lib_init(0); config = talloc_zero(handle->conn, struct gpfs_config_data); @@ -1880,7 +1884,7 @@ static int vfs_gpfs_connect(struct vfs_handle_struct *handle, check_fstype = lp_parm_bool(SNUM(handle->conn), "gpfs", "check_fstype", true); - if (check_fstype && !IS_IPC(handle->conn)) { + if (check_fstype) { const char *connectpath = handle->conn->connectpath; struct statfs buf = { 0 }; -- 2.31.1 From 472a6dd6b5f59e97a34d75b0549c74995ddc22eb Mon Sep 17 00:00:00 2001 From: Ralph Boehme Date: Thu, 29 Jul 2021 15:53:04 +0200 Subject: [PATCH 05/13] vfs_gpfs: check for O_PATH support in gpfswrap_fstat_x() BUG: https://bugzilla.samba.org/show_bug.cgi?id=14771 Signed-off-by: Ralph Boehme Reviewed-by: Christof Schmitt (cherry picked from commit 730f8c49a9bc8333f0b722ad65e4e587421c21ec) --- source3/modules/vfs_gpfs.c | 73 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 73 insertions(+) diff --git a/source3/modules/vfs_gpfs.c b/source3/modules/vfs_gpfs.c index 0aed912c022..88d814cb8db 100644 --- a/source3/modules/vfs_gpfs.c +++ b/source3/modules/vfs_gpfs.c @@ -55,6 +55,9 @@ struct gpfs_config_data { bool acl; bool settimes; bool recalls; + struct { + bool gpfs_fstat_x; + } pathref_ok; }; struct gpfs_fsp_extension { @@ -1856,6 +1859,68 @@ static ssize_t vfs_gpfs_sendfile(vfs_handle_struct *handle, int tofd, return SMB_VFS_NEXT_SENDFILE(handle, tofd, fsp, hdr, offset, n); } +#ifdef O_PATH +static int vfs_gpfs_check_pathref_fstat_x(struct gpfs_config_data *config, + struct connection_struct *conn) +{ + struct gpfs_iattr64 iattr = {0}; + unsigned int litemask; + int saved_errno; + int fd; + int ret; + + fd = open(conn->connectpath, O_PATH); + if (fd == -1) { + DBG_ERR("openat() of share with O_PATH failed: %s\n", + strerror(errno)); + return -1; + } + + ret = gpfswrap_fstat_x(fd, &litemask, &iattr, sizeof(iattr)); + if (ret == 0) { + close(fd); + config->pathref_ok.gpfs_fstat_x = true; + return 0; + } + + saved_errno = errno; + ret = close(fd); + if (ret != 0) { + DBG_ERR("close failed: %s\n", strerror(errno)); + return -1; + } + + if (saved_errno != EBADF) { + DBG_ERR("gpfswrap_fstat_x() of O_PATH handle failed: %s\n", + strerror(saved_errno)); + return -1; + } + + return 0; +} +#endif + +static int vfs_gpfs_check_pathref(struct gpfs_config_data *config, + struct connection_struct *conn) +{ +#ifndef O_PATH + /* + * This code path leaves all struct gpfs_config_data.pathref_ok members + * initialized to false. + */ + return 0; +#else + int ret; + + ret = vfs_gpfs_check_pathref_fstat_x(config, conn); + if (ret != 0) { + return -1; + } + + return 0; +#endif +} + static int vfs_gpfs_connect(struct vfs_handle_struct *handle, const char *service, const char *user) { @@ -1945,6 +2010,14 @@ static int vfs_gpfs_connect(struct vfs_handle_struct *handle, config->recalls = lp_parm_bool(SNUM(handle->conn), "gpfs", "recalls", true); + ret = vfs_gpfs_check_pathref(config, handle->conn); + if (ret != 0) { + DBG_ERR("vfs_gpfs_check_pathref() on [%s] failed\n", + handle->conn->connectpath); + TALLOC_FREE(config); + return -1; + } + SMB_VFS_HANDLE_SET_DATA(handle, config, NULL, struct gpfs_config_data, return -1); -- 2.31.1 From 4ff1d46fe6191c5aee6ecc50481fd950ef270816 Mon Sep 17 00:00:00 2001 From: Ralph Boehme Date: Thu, 29 Jul 2021 19:28:14 +0200 Subject: [PATCH 06/13] vfs_gpfs: add path based fallback for gpfswrap_fstat_x() on pathref handles BUG: https://bugzilla.samba.org/show_bug.cgi?id=14771 Signed-off-by: Ralph Boehme Reviewed-by: Christof Schmitt (cherry picked from commit fde1b98143568fc816165502583f72e73b5d6b71) --- source3/modules/vfs_gpfs.c | 33 ++++++++++++++++++++++++++++++--- 1 file changed, 30 insertions(+), 3 deletions(-) diff --git a/source3/modules/vfs_gpfs.c b/source3/modules/vfs_gpfs.c index 88d814cb8db..a8e50b82a17 100644 --- a/source3/modules/vfs_gpfs.c +++ b/source3/modules/vfs_gpfs.c @@ -1474,6 +1474,9 @@ static NTSTATUS vfs_gpfs_fget_dos_attributes(struct vfs_handle_struct *handle, uint32_t *dosmode) { struct gpfs_config_data *config; + int fd = fsp_get_pathref_fd(fsp); + char buf[PATH_MAX]; + const char *p = NULL; struct gpfs_iattr64 iattr = { }; unsigned int litemask; struct timespec ts; @@ -1489,7 +1492,22 @@ static NTSTATUS vfs_gpfs_fget_dos_attributes(struct vfs_handle_struct *handle, return SMB_VFS_NEXT_FGET_DOS_ATTRIBUTES(handle, fsp, dosmode); } - ret = gpfswrap_fstat_x(fsp_get_pathref_fd(fsp), &litemask, &iattr, sizeof(iattr)); + if (fsp->fsp_flags.is_pathref && !config->pathref_ok.gpfs_fstat_x) { + if (fsp->fsp_flags.have_proc_fds) { + p = sys_proc_fd_path(fd, buf, sizeof(buf)); + if (p == NULL) { + return NT_STATUS_NO_MEMORY; + } + } else { + p = fsp->fsp_name->base_name; + } + } + + if (p != NULL) { + ret = gpfswrap_stat_x(p, &litemask, &iattr, sizeof(iattr)); + } else { + ret = gpfswrap_fstat_x(fd, &litemask, &iattr, sizeof(iattr)); + } if (ret == -1 && errno == ENOSYS) { return SMB_VFS_NEXT_FGET_DOS_ATTRIBUTES(handle, fsp, dosmode); } @@ -1506,8 +1524,17 @@ static NTSTATUS vfs_gpfs_fget_dos_attributes(struct vfs_handle_struct *handle, set_effective_capability(DAC_OVERRIDE_CAPABILITY); - ret = gpfswrap_fstat_x(fsp_get_pathref_fd(fsp), &litemask, - &iattr, sizeof(iattr)); + if (p != NULL) { + ret = gpfswrap_stat_x(p, + &litemask, + &iattr, + sizeof(iattr)); + } else { + ret = gpfswrap_fstat_x(fd, + &litemask, + &iattr, + sizeof(iattr)); + } if (ret == -1) { saved_errno = errno; } -- 2.31.1 From a687e616e9e64fb03ee75055840a8565f1d48a30 Mon Sep 17 00:00:00 2001 From: Ralph Boehme Date: Fri, 13 Aug 2021 11:39:05 +0200 Subject: [PATCH 07/13] vfs_gpfs: remove ENOSYS fallback from vfs_gpfs_fset_dos_attributes() This API call has existed for a long time, so we can safely assume that this always works. BUG: https://bugzilla.samba.org/show_bug.cgi?id=14771 Pair-Programmed-With: Christof Schmitt Signed-off-by: Ralph Boehme Signed-off-by: Christof Schmitt (cherry picked from commit 3679f54f178ba6ddb940cc66f701e9b3a1dd543d) --- source3/modules/vfs_gpfs.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/source3/modules/vfs_gpfs.c b/source3/modules/vfs_gpfs.c index a8e50b82a17..94d0258b38d 100644 --- a/source3/modules/vfs_gpfs.c +++ b/source3/modules/vfs_gpfs.c @@ -1584,13 +1584,9 @@ static NTSTATUS vfs_gpfs_fset_dos_attributes(struct vfs_handle_struct *handle, } attrs.winAttrs = vfs_gpfs_dosmode_to_winattrs(dosmode); + ret = gpfswrap_set_winattrs(fsp_get_io_fd(fsp), GPFS_WINATTR_SET_ATTRS, &attrs); - - if (ret == -1 && errno == ENOSYS) { - return SMB_VFS_NEXT_FSET_DOS_ATTRIBUTES(handle, fsp, dosmode); - } - if (ret == -1) { DBG_WARNING("Setting winattrs failed for %s: %s\n", fsp->fsp_name->base_name, strerror(errno)); -- 2.31.1 From 92953cc811535ec9c54b677cfd65c5bd35c25711 Mon Sep 17 00:00:00 2001 From: Ralph Boehme Date: Thu, 1 Jul 2021 16:08:02 +0200 Subject: [PATCH 08/13] vfs_gpfs: add sys_proc_fd_path() fallback to vfs_gpfs_fset_dos_attributes() gpfs_set_winattrs() is a modifying operation, my expectation thus is that it is not allowed on pathref (O_PATH) handles even though a recent Linux kernel commit 44a3b87444058b2cb055092cdebc63858707bf66 allowed calling utimensat() on pathref handles. BUG: https://bugzilla.samba.org/show_bug.cgi?id=14771 RN: Some VFS operations on pathref (O_PATH) handles fail on GPFS Signed-off-by: Ralph Boehme Reviewed-by: Christof Schmitt (cherry picked from commit 882a466ea5f45e5e2197f2408ccd560383e13c3f) --- source3/modules/vfs_gpfs.c | 44 ++++++++++++++++++++++++++++++++++---- 1 file changed, 40 insertions(+), 4 deletions(-) diff --git a/source3/modules/vfs_gpfs.c b/source3/modules/vfs_gpfs.c index 94d0258b38d..cc653c22712 100644 --- a/source3/modules/vfs_gpfs.c +++ b/source3/modules/vfs_gpfs.c @@ -1585,11 +1585,47 @@ static NTSTATUS vfs_gpfs_fset_dos_attributes(struct vfs_handle_struct *handle, attrs.winAttrs = vfs_gpfs_dosmode_to_winattrs(dosmode); - ret = gpfswrap_set_winattrs(fsp_get_io_fd(fsp), - GPFS_WINATTR_SET_ATTRS, &attrs); + if (!fsp->fsp_flags.is_pathref) { + ret = gpfswrap_set_winattrs(fsp_get_io_fd(fsp), + GPFS_WINATTR_SET_ATTRS, &attrs); + if (ret == -1) { + DBG_WARNING("Setting winattrs failed for %s: %s\n", + fsp_str_dbg(fsp), strerror(errno)); + return map_nt_error_from_unix(errno); + } + return NT_STATUS_OK; + } + + if (fsp->fsp_flags.have_proc_fds) { + int fd = fsp_get_pathref_fd(fsp); + const char *p = NULL; + char buf[PATH_MAX]; + + p = sys_proc_fd_path(fd, buf, sizeof(buf)); + if (p == NULL) { + return NT_STATUS_NO_MEMORY; + } + + ret = gpfswrap_set_winattrs_path(p, + GPFS_WINATTR_SET_ATTRS, + &attrs); + if (ret == -1) { + DBG_WARNING("Setting winattrs failed for [%s][%s]: %s\n", + p, fsp_str_dbg(fsp), strerror(errno)); + return map_nt_error_from_unix(errno); + } + return NT_STATUS_OK; + } + + /* + * This is no longer a handle based call. + */ + ret = gpfswrap_set_winattrs_path(fsp->fsp_name->base_name, + GPFS_WINATTR_SET_ATTRS, + &attrs); if (ret == -1) { - DBG_WARNING("Setting winattrs failed for %s: %s\n", - fsp->fsp_name->base_name, strerror(errno)); + DBG_WARNING("Setting winattrs failed for [%s]: %s\n", + fsp_str_dbg(fsp), strerror(errno)); return map_nt_error_from_unix(errno); } -- 2.31.1 From 741779bd13a806292b2fe81c99164bd9ff5a3d63 Mon Sep 17 00:00:00 2001 From: Ralph Boehme Date: Thu, 5 Aug 2021 11:55:30 +0200 Subject: [PATCH 09/13] vfs_gpfs: deal with pathref fsps in vfs_gpfs_fntimes() BUG: https://bugzilla.samba.org/show_bug.cgi?id=14771 Signed-off-by: Ralph Boehme Reviewed-by: Christof Schmitt (cherry picked from commit 443608ee8122a2c17258db8dca9885bb524957af) --- source3/modules/vfs_gpfs.c | 40 +++++++++++++++++++++++++++++++++++--- 1 file changed, 37 insertions(+), 3 deletions(-) diff --git a/source3/modules/vfs_gpfs.c b/source3/modules/vfs_gpfs.c index cc653c22712..8fc6bb21c90 100644 --- a/source3/modules/vfs_gpfs.c +++ b/source3/modules/vfs_gpfs.c @@ -1792,9 +1792,43 @@ static int vfs_gpfs_fntimes(struct vfs_handle_struct *handle, 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 (!fsp->fsp_flags.is_pathref) { + 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 ret; + } + + if (fsp->fsp_flags.have_proc_fds) { + int fd = fsp_get_pathref_fd(fsp); + const char *p = NULL; + char buf[PATH_MAX]; + + p = sys_proc_fd_path(fd, buf, sizeof(buf)); + if (p == NULL) { + return -1; + } + + ret = gpfswrap_set_winattrs_path(p, + GPFS_WINATTR_SET_CREATION_TIME, + &attrs); + if (ret == -1 && errno != ENOSYS) { + DBG_WARNING("Set GPFS ntimes failed %d\n", ret); + return -1; + } + return ret; + } + + /* + * This is no longer a handle based call. + */ + ret = gpfswrap_set_winattrs_path(fsp->fsp_name->base_name, + GPFS_WINATTR_SET_CREATION_TIME, + &attrs); if (ret == -1 && errno != ENOSYS) { DBG_WARNING("Set GPFS ntimes failed %d\n", ret); return -1; -- 2.31.1 From 53060bd01fbd7b995b3d60c0e54c7e7ad4f63a6d Mon Sep 17 00:00:00 2001 From: Ralph Boehme Date: Thu, 5 Aug 2021 11:58:58 +0200 Subject: [PATCH 10/13] vfs_gpfs: pass fsp to smbd_gpfs_set_times() No change in behaviour. Prepares for dealing with pathref fsps in smbd_gpfs_set_times(). BUG: https://bugzilla.samba.org/show_bug.cgi?id=14771 Signed-off-by: Ralph Boehme Reviewed-by: Christof Schmitt (cherry picked from commit 9a237e168a4bbd5665bd40d521506ca3a6825198) --- source3/modules/vfs_gpfs.c | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/source3/modules/vfs_gpfs.c b/source3/modules/vfs_gpfs.c index 8fc6bb21c90..a3e725f0fd8 100644 --- a/source3/modules/vfs_gpfs.c +++ b/source3/modules/vfs_gpfs.c @@ -1714,7 +1714,8 @@ static void timespec_to_gpfs_time(struct timespec ts, gpfs_timestruc_t *gt, } } -static int smbd_gpfs_set_times(int fd, char *path, struct smb_file_time *ft) +static int smbd_gpfs_set_times(struct files_struct *fsp, + struct smb_file_time *ft) { gpfs_timestruc_t gpfs_times[4]; int flags = 0; @@ -1731,12 +1732,12 @@ static int smbd_gpfs_set_times(int fd, char *path, struct smb_file_time *ft) return 0; } - rc = gpfswrap_set_times(fd, flags, gpfs_times); + rc = gpfswrap_set_times(fsp_get_io_fd(fsp), flags, gpfs_times); if (rc != 0 && errno != ENOSYS) { DBG_WARNING("gpfs_set_times() returned with error %s for %s\n", strerror(errno), - path); + fsp_str_dbg(fsp)); } return rc; @@ -1758,9 +1759,7 @@ static int vfs_gpfs_fntimes(struct vfs_handle_struct *handle, /* 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); + ret = smbd_gpfs_set_times(fsp, ft); if (ret == 0 || (ret == -1 && errno != ENOSYS)) { return ret; } -- 2.31.1 From fcc68a1a88665103598b0531da5d078e35a4bfce Mon Sep 17 00:00:00 2001 From: Ralph Boehme Date: Fri, 13 Aug 2021 11:55:16 +0200 Subject: [PATCH 11/13] vfs_gpfs: remove ENOSYS fallback from vfs_gpfs_fntimes() BUG: https://bugzilla.samba.org/show_bug.cgi?id=14771 Signed-off-by: Ralph Boehme Reviewed-by: Christof Schmitt (cherry picked from commit 1bbdb81899be6c1da6fa9a63bf16a00401e09399) --- source3/modules/vfs_gpfs.c | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/source3/modules/vfs_gpfs.c b/source3/modules/vfs_gpfs.c index a3e725f0fd8..1f5fdadc9c5 100644 --- a/source3/modules/vfs_gpfs.c +++ b/source3/modules/vfs_gpfs.c @@ -1733,8 +1733,7 @@ static int smbd_gpfs_set_times(struct files_struct *fsp, } rc = gpfswrap_set_times(fsp_get_io_fd(fsp), flags, gpfs_times); - - if (rc != 0 && errno != ENOSYS) { + if (rc != 0) { DBG_WARNING("gpfs_set_times() returned with error %s for %s\n", strerror(errno), fsp_str_dbg(fsp)); @@ -1759,10 +1758,7 @@ static int vfs_gpfs_fntimes(struct vfs_handle_struct *handle, /* Try to use gpfs_set_times if it is enabled and available */ if (config->settimes) { - ret = smbd_gpfs_set_times(fsp, ft); - if (ret == 0 || (ret == -1 && errno != ENOSYS)) { - return ret; - } + return smbd_gpfs_set_times(fsp, ft); } DBG_DEBUG("gpfs_set_times() not available or disabled, " -- 2.31.1 From 99aa82fb6a4278a6fefab6466c3bfeae8f3b4ea7 Mon Sep 17 00:00:00 2001 From: Ralph Boehme Date: Thu, 5 Aug 2021 12:05:16 +0200 Subject: [PATCH 12/13] lib/gpfswrap: add gpfs_set_times_path() wrapper BUG: https://bugzilla.samba.org/show_bug.cgi?id=14771 Signed-off-by: Ralph Boehme Reviewed-by: Christof Schmitt (cherry picked from commit 93a48399f427d114df63b434e7fcddc62a1d9ce5) --- lib/util/gpfswrap.c | 14 ++++++++++++++ lib/util/gpfswrap.h | 1 + 2 files changed, 15 insertions(+) diff --git a/lib/util/gpfswrap.c b/lib/util/gpfswrap.c index c348ed7c5b8..5cf6d2148e7 100644 --- a/lib/util/gpfswrap.c +++ b/lib/util/gpfswrap.c @@ -39,6 +39,9 @@ static int (*gpfs_get_winattrs_fn)(int fd, struct gpfs_winattr *attrs); static int (*gpfs_ftruncate_fn)(int fd, gpfs_off64_t length); static int (*gpfs_lib_init_fn)(int flags); static int (*gpfs_set_times_fn)(int fd, int flags, gpfs_timestruc_t times[4]); +static int (*gpfs_set_times_path_fn)(char *path, + int flags, + gpfs_timestruc_t times[4]); static int (*gpfs_quotactl_fn)(const char *pathname, int cmd, int id, @@ -77,6 +80,7 @@ int gpfswrap_init(void) gpfs_ftruncate_fn = dlsym(l, "gpfs_ftruncate"); gpfs_lib_init_fn = dlsym(l, "gpfs_lib_init"); gpfs_set_times_fn = dlsym(l, "gpfs_set_times"); + gpfs_set_times_path_fn = dlsym(l, "gpfs_set_times_path"); gpfs_quotactl_fn = dlsym(l, "gpfs_quotactl"); gpfs_init_trace_fn = dlsym(l, "gpfs_init_trace"); gpfs_query_trace_fn = dlsym(l, "gpfs_query_trace"); @@ -213,6 +217,16 @@ int gpfswrap_set_times(int fd, int flags, gpfs_timestruc_t times[4]) return gpfs_set_times_fn(fd, flags, times); } +int gpfswrap_set_times_path(char *path, int flags, gpfs_timestruc_t times[4]) +{ + if (gpfs_set_times_path_fn == NULL) { + errno = ENOSYS; + return -1; + } + + return gpfs_set_times_path_fn(path, flags, times); +} + int gpfswrap_quotactl(const char *pathname, int cmd, int id, void *bufp) { if (gpfs_quotactl_fn == NULL) { diff --git a/lib/util/gpfswrap.h b/lib/util/gpfswrap.h index 138e6ec696e..764cf686d2e 100644 --- a/lib/util/gpfswrap.h +++ b/lib/util/gpfswrap.h @@ -44,6 +44,7 @@ int gpfswrap_get_winattrs(int fd, struct gpfs_winattr *attrs); int gpfswrap_ftruncate(int fd, gpfs_off64_t length); int gpfswrap_lib_init(int flags); int gpfswrap_set_times(int fd, int flags, gpfs_timestruc_t times[4]); +int gpfswrap_set_times_path(char *path, int flags, gpfs_timestruc_t times[4]); int gpfswrap_quotactl(const char *pathname, int cmd, int id, void *bufp); int gpfswrap_init_trace(void); int gpfswrap_query_trace(void); -- 2.31.1 From 1a88cae03905139a3a9630f9d0ca482024889346 Mon Sep 17 00:00:00 2001 From: Ralph Boehme Date: Thu, 5 Aug 2021 12:08:00 +0200 Subject: [PATCH 13/13] vfs_gpfs: deal with pathrefs fsps in smbd_gpfs_set_times() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit BUG: https://bugzilla.samba.org/show_bug.cgi?id=14771 Signed-off-by: Ralph Boehme Reviewed-by: Christof Schmitt Autobuild-User(master): Ralph Böhme Autobuild-Date(master): Thu Aug 26 20:08:51 UTC 2021 on sn-devel-184 (cherry picked from commit fead05a45556993b80a84fe9bb07b10debb4ae62) --- source3/modules/vfs_gpfs.c | 42 +++++++++++++++++++++++++++++++++----- 1 file changed, 37 insertions(+), 5 deletions(-) diff --git a/source3/modules/vfs_gpfs.c b/source3/modules/vfs_gpfs.c index 1f5fdadc9c5..4d1cfa6075a 100644 --- a/source3/modules/vfs_gpfs.c +++ b/source3/modules/vfs_gpfs.c @@ -1732,13 +1732,45 @@ static int smbd_gpfs_set_times(struct files_struct *fsp, return 0; } - rc = gpfswrap_set_times(fsp_get_io_fd(fsp), flags, gpfs_times); - if (rc != 0) { - DBG_WARNING("gpfs_set_times() returned with error %s for %s\n", - strerror(errno), - fsp_str_dbg(fsp)); + if (!fsp->fsp_flags.is_pathref) { + rc = gpfswrap_set_times(fsp_get_io_fd(fsp), flags, gpfs_times); + if (rc != 0) { + DBG_WARNING("gpfs_set_times(%s) failed: %s\n", + fsp_str_dbg(fsp), strerror(errno)); + } + return rc; } + + if (fsp->fsp_flags.have_proc_fds) { + int fd = fsp_get_pathref_fd(fsp); + const char *p = NULL; + char buf[PATH_MAX]; + + p = sys_proc_fd_path(fd, buf, sizeof(buf)); + if (p == NULL) { + return -1; + } + + rc = gpfswrap_set_times_path(buf, flags, gpfs_times); + if (rc != 0) { + DBG_WARNING("gpfs_set_times_path(%s,%s) failed: %s\n", + fsp_str_dbg(fsp), p, strerror(errno)); + } + return rc; + } + + /* + * This is no longer a handle based call. + */ + + rc = gpfswrap_set_times_path(fsp->fsp_name->base_name, + flags, + gpfs_times); + if (rc != 0) { + DBG_WARNING("gpfs_set_times_path(%s) failed: %s\n", + fsp_str_dbg(fsp), strerror(errno)); + } return rc; } -- 2.31.1