From cb14d3630d8c110405c2a43bef15aa31ec4a0fba Mon Sep 17 00:00:00 2001 From: Shachar Sharon Date: Wed, 19 Jun 2024 12:48:14 +0300 Subject: [PATCH] vfs_ceph_new: use low-level APIs for fchown/fchmod Use libcephfs' low-level APIs to implement 'fchown' and 'fchmod' using open file-handle. If fsp does not have an open cephfs Fh reference, set errno to EBADF and return -1 to VFS. BUG: https://bugzilla.samba.org/show_bug.cgi?id=15686 Signed-off-by: Shachar Sharon Reviewed-by: Guenther Deschner Reviewed-by: Anoop C S --- source3/modules/vfs_ceph_new.c | 79 +++++++++++++++++++++------------- 1 file changed, 48 insertions(+), 31 deletions(-) diff --git a/source3/modules/vfs_ceph_new.c b/source3/modules/vfs_ceph_new.c index e106a9bb4cb..20cd95ef16c 100644 --- a/source3/modules/vfs_ceph_new.c +++ b/source3/modules/vfs_ceph_new.c @@ -485,6 +485,14 @@ static int vfs_ceph_fetch_fh(struct vfs_handle_struct *handle, return (*out_cfh == NULL) ? -EBADF : 0; } +static int vfs_ceph_fetch_io_fh(struct vfs_handle_struct *handle, + const struct files_struct *fsp, + struct vfs_ceph_fh **out_cfh) +{ + *out_cfh = VFS_FETCH_FSP_EXTENSION(handle, fsp); + return (*out_cfh == NULL) || ((*out_cfh)->fh == NULL) ? -EBADF : 0; +} + static void vfs_ceph_assign_fh_fd(struct vfs_ceph_fh *cfh) { cfh->fd = cephmount_next_fd(cfh->cme); /* debug only */ @@ -593,6 +601,33 @@ static int vfs_ceph_ll_chown(struct vfs_handle_struct *handle, return ret; } +static int vfs_ceph_ll_fchown(struct vfs_handle_struct *handle, + const struct vfs_ceph_fh *cfh, + uid_t uid, + gid_t gid) +{ + struct ceph_statx stx = {.stx_uid = uid, .stx_gid = gid}; + + return ceph_ll_setattr(cmount_of(handle), + cfh->iref.inode, + &stx, + CEPH_STATX_UID | CEPH_STATX_GID, + cfh->uperm); +} + +static int vfs_ceph_ll_fchmod(struct vfs_handle_struct *handle, + const struct vfs_ceph_fh *cfh, + mode_t mode) +{ + struct ceph_statx stx = {.stx_mode = mode}; + + return ceph_ll_setattr(cmount_of(handle), + cfh->iref.inode, + &stx, + CEPH_STATX_MODE, + cfh->uperm); +} + static int vfs_ceph_ll_releasedir(const struct vfs_handle_struct *handle, const struct vfs_ceph_fh *dircfh) { @@ -1712,23 +1747,16 @@ static int vfs_ceph_fchmod(struct vfs_handle_struct *handle, mode_t mode) { int result; + struct vfs_ceph_fh *cfh = NULL; DBG_DEBUG("[CEPH] fchmod(%p, %p, %d)\n", handle, fsp, mode); - if (!fsp->fsp_flags.is_pathref) { - /* - * We can use an io_fd to change permissions. - */ - result = ceph_fchmod(cmount_of(handle), - fsp_get_io_fd(fsp), - mode); - } else { - /* - * This is no longer a handle based call. - */ - result = ceph_chmod(cmount_of(handle), - fsp->fsp_name->base_name, - mode); + result = vfs_ceph_fetch_io_fh(handle, fsp, &cfh); + if (result != 0) { + goto out; } + + result = vfs_ceph_ll_fchmod(handle, cfh, mode); +out: DBG_DEBUG("[CEPH] fchmod(...) = %d\n", result); return status_code(result); } @@ -1739,26 +1767,15 @@ static int vfs_ceph_fchown(struct vfs_handle_struct *handle, gid_t gid) { int result; + struct vfs_ceph_fh *cfh = NULL; DBG_DEBUG("[CEPH] fchown(%p, %p, %d, %d)\n", handle, fsp, uid, gid); - if (!fsp->fsp_flags.is_pathref) { - /* - * We can use an io_fd to change ownership. - */ - result = ceph_fchown(cmount_of(handle), - fsp_get_io_fd(fsp), - uid, - gid); - } else { - /* - * This is no longer a handle based call. - */ - result = ceph_chown(cmount_of(handle), - fsp->fsp_name->base_name, - uid, - gid); + result = vfs_ceph_fetch_io_fh(handle, fsp, &cfh); + if (result != 0) { + goto out; } - + result = vfs_ceph_ll_fchown(handle, cfh, uid, gid); +out: DBG_DEBUG("[CEPH] fchown(...) = %d\n", result); return status_code(result); } -- 2.47.3