From: Ralph Boehme Date: Thu, 1 Jul 2021 14:08:02 +0000 (+0200) Subject: vfs_gpfs: add sys_proc_fd_path() fallback to vfs_gpfs_fset_dos_attributes() X-Git-Tag: ldb-2.5.0~827 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=882a466ea5f45e5e2197f2408ccd560383e13c3f;p=thirdparty%2Fsamba.git 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 --- 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); }