From: Anoop C S Date: Fri, 14 Mar 2025 14:29:33 +0000 (+0530) Subject: vfs_ceph_new: Add path based fallback for SMB_VFS_FCHMOD X-Git-Tag: samba-4.21.5~5 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=8f3bc967657862d30ba3890b8b07b7c68790654e;p=thirdparty%2Fsamba.git vfs_ceph_new: Add path based fallback for SMB_VFS_FCHMOD Fallback mechanism was missing in vfs_ceph_fchmod() for path based call. BUG: https://bugzilla.samba.org/show_bug.cgi?id=15834 Signed-off-by: Anoop C S Reviewed-by: Guenther Deschner (cherry picked from commit 9c019ecf4eae6e6bef48323a0b093e17b0708ee8) --- diff --git a/source3/modules/vfs_ceph_new.c b/source3/modules/vfs_ceph_new.c index cd06fbcd377..a0b05240b34 100644 --- a/source3/modules/vfs_ceph_new.c +++ b/source3/modules/vfs_ceph_new.c @@ -973,6 +973,36 @@ static int vfs_ceph_ll_fchown(struct vfs_handle_struct *handle, cfh->uperm); } +static int vfs_ceph_ll_chmod(const struct vfs_handle_struct *handle, + const struct vfs_ceph_iref *iref, + mode_t mode) +{ + struct ceph_statx stx = {.stx_mode = mode}; + struct UserPerm *uperm = NULL; + int ret = -1; + struct vfs_ceph_config *config = NULL; + + SMB_VFS_HANDLE_GET_DATA(handle, config, struct vfs_ceph_config, + return -ENOMEM); + + DBG_DEBUG("[CEPH] ceph_ll_setattr: ino=%" PRIu64 " mode=%o\n", iref->ino, mode); + + uperm = vfs_ceph_userperm_new(config, handle->conn); + if (uperm == NULL) { + return -ENOMEM; + } + + ret = config->ceph_ll_setattr_fn(config->mount, + iref->inode, + &stx, + CEPH_STATX_MODE, + uperm); + + vfs_ceph_userperm_del(config, uperm); + DBG_DEBUG("[CEPH] ceph_ll_setattr: ret=%d\n", ret); + return ret; +} + static int vfs_ceph_ll_fchmod(struct vfs_handle_struct *handle, const struct vfs_ceph_fh *cfh, mode_t mode) @@ -3140,16 +3170,30 @@ static int vfs_ceph_fchmod(struct vfs_handle_struct *handle, mode_t mode) { int result; - struct vfs_ceph_fh *cfh = NULL; START_PROFILE(syscall_fchmod); DBG_DEBUG("[CEPH] fchmod(%p, %p, %d)\n", handle, fsp, mode); - result = vfs_ceph_fetch_io_fh(handle, fsp, &cfh); - if (result != 0) { - goto out; - } - result = vfs_ceph_ll_fchmod(handle, cfh, mode); + if (!fsp->fsp_flags.is_pathref) { + struct vfs_ceph_fh *cfh = NULL; + + result = vfs_ceph_fetch_io_fh(handle, fsp, &cfh); + if (result != 0) { + goto out; + } + + result = vfs_ceph_ll_fchmod(handle, cfh, mode); + } else { + struct vfs_ceph_iref iref = {0}; + + result = vfs_ceph_iget(handle, fsp->fsp_name->base_name, 0, &iref); + if (result != 0) { + goto out; + } + + result = vfs_ceph_ll_chmod(handle, &iref, mode); + vfs_ceph_iput(handle, &iref); + } out: DBG_DEBUG("[CEPH] fchmod(...) = %d\n", result); END_PROFILE(syscall_fchmod);