From e70abbc627a6e25cf4cca0ed5e58c9ac4d24c8b2 Mon Sep 17 00:00:00 2001 From: Anoop C S Date: Fri, 14 Mar 2025 19:47:42 +0530 Subject: [PATCH 1/3] vfs_ceph_new: Add path based fallback for SMB_VFS_FCHOWN Fallback mechanism was missing in vfs_ceph_fchown() 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 abb97683902f50b2a57989f30c0fb53fd3492af9) --- source3/modules/vfs_ceph_new.c | 28 +++++++++++++++++++++++----- 1 file changed, 23 insertions(+), 5 deletions(-) diff --git a/source3/modules/vfs_ceph_new.c b/source3/modules/vfs_ceph_new.c index 8b051e0f226..20b762b4cc6 100644 --- a/source3/modules/vfs_ceph_new.c +++ b/source3/modules/vfs_ceph_new.c @@ -3081,15 +3081,33 @@ static int vfs_ceph_fchown(struct vfs_handle_struct *handle, gid_t gid) { int result; - struct vfs_ceph_fh *cfh = NULL; START_PROFILE(syscall_fchown); DBG_DEBUG("[CEPH] fchown(%p, %p, %d, %d)\n", handle, fsp, uid, gid); - result = vfs_ceph_fetch_io_fh(handle, fsp, &cfh); - if (result != 0) { - goto out; + + 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_fchown(handle, cfh, uid, gid); + } 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_chown(handle, &iref, uid, gid); + vfs_ceph_iput(handle, &iref); } - result = vfs_ceph_ll_fchown(handle, cfh, uid, gid); out: DBG_DEBUG("[CEPH] fchown(...) = %d\n", result); END_PROFILE(syscall_fchown); -- 2.48.1 From 880771a1ea0d2a0cb401445ee5ea93c4defecaeb Mon Sep 17 00:00:00 2001 From: Anoop C S Date: Fri, 14 Mar 2025 19:59:33 +0530 Subject: [PATCH 2/3] 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) --- source3/modules/vfs_ceph_new.c | 56 ++++++++++++++++++++++++++++++---- 1 file changed, 50 insertions(+), 6 deletions(-) diff --git a/source3/modules/vfs_ceph_new.c b/source3/modules/vfs_ceph_new.c index 20b762b4cc6..63f7bbf7001 100644 --- a/source3/modules/vfs_ceph_new.c +++ b/source3/modules/vfs_ceph_new.c @@ -964,6 +964,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) @@ -3059,16 +3089,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); -- 2.48.1 From 057d79d9e438bb39236048c9aa4f5b9ce43b0a00 Mon Sep 17 00:00:00 2001 From: Anoop C S Date: Mon, 17 Mar 2025 19:52:10 +0530 Subject: [PATCH 3/3] vfs_ceph_new: Add path based fallback for SMB_VFS_FNTIMES MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fallback mechanism was missing in vfs_ceph_fntimes() for path based call. BUG: https://bugzilla.samba.org/show_bug.cgi?id=15834 Signed-off-by: Anoop C S Reviewed-by: Guenther Deschner Autobuild-User(master): Günther Deschner Autobuild-Date(master): Mon Mar 17 20:48:55 UTC 2025 on atb-devel-224 (cherry picked from commit dbc48a4cda7489363688bb38f6fa678011fedfaf) --- source3/modules/vfs_ceph_new.c | 108 +++++++++++++++++++++++++-------- 1 file changed, 84 insertions(+), 24 deletions(-) diff --git a/source3/modules/vfs_ceph_new.c b/source3/modules/vfs_ceph_new.c index 63f7bbf7001..b7e1c5156a4 100644 --- a/source3/modules/vfs_ceph_new.c +++ b/source3/modules/vfs_ceph_new.c @@ -1014,6 +1014,67 @@ static int vfs_ceph_ll_fchmod(struct vfs_handle_struct *handle, cfh->uperm); } +static void vfs_ceph_fill_statx_mask_from_ft(const struct smb_file_time *ft, + struct ceph_statx *stx, + int *mask) +{ + if (!is_omit_timespec(&ft->atime)) { + stx->stx_atime = ft->atime; + *mask |= CEPH_SETATTR_ATIME; + } + if (!is_omit_timespec(&ft->mtime)) { + stx->stx_mtime = ft->mtime; + *mask |= CEPH_SETATTR_MTIME; + } + if (!is_omit_timespec(&ft->ctime)) { + stx->stx_ctime = ft->ctime; + *mask |= CEPH_SETATTR_CTIME; + } + if (!is_omit_timespec(&ft->create_time)) { + stx->stx_btime = ft->create_time; + *mask |= CEPH_SETATTR_BTIME; + } +} + +static int vfs_ceph_ll_utimes(struct vfs_handle_struct *handle, + const struct vfs_ceph_iref *iref, + const struct smb_file_time *ft) +{ + struct ceph_statx stx = {0}; + struct UserPerm *uperm = NULL; + int ret = -1; + int mask = 0; + struct vfs_ceph_config *config = NULL; + + SMB_VFS_HANDLE_GET_DATA(handle, config, struct vfs_ceph_config, + return -ENOMEM); + + vfs_ceph_fill_statx_mask_from_ft(ft, &stx, &mask); + if (!mask) { + return 0; + } + + DBG_DEBUG("[CEPH] ceph_ll_setattr: ino=%" PRIu64 " mtime=%" PRIu64 + " atime=%" PRIu64 " ctime=%" PRIu64 " btime=%" PRIu64 "\n", + iref->ino, + full_timespec_to_nt_time(&stx.stx_mtime), + full_timespec_to_nt_time(&stx.stx_atime), + full_timespec_to_nt_time(&stx.stx_ctime), + full_timespec_to_nt_time(&stx.stx_btime)); + + uperm = vfs_ceph_userperm_new(config, handle->conn); + if (uperm == NULL) { + return -ENOMEM; + } + ret = config->ceph_ll_setattr_fn(config->mount, + iref->inode, + &stx, + mask, + uperm); + vfs_ceph_userperm_del(config, uperm); + return ret; +} + static int vfs_ceph_ll_futimes(struct vfs_handle_struct *handle, const struct vfs_ceph_fh *cfh, const struct smb_file_time *ft) @@ -1025,22 +1086,7 @@ static int vfs_ceph_ll_futimes(struct vfs_handle_struct *handle, SMB_VFS_HANDLE_GET_DATA(handle, config, struct vfs_ceph_config, return -ENOMEM); - if (!is_omit_timespec(&ft->atime)) { - stx.stx_atime = ft->atime; - mask |= CEPH_SETATTR_ATIME; - } - if (!is_omit_timespec(&ft->mtime)) { - stx.stx_mtime = ft->mtime; - mask |= CEPH_SETATTR_MTIME; - } - if (!is_omit_timespec(&ft->ctime)) { - stx.stx_ctime = ft->ctime; - mask |= CEPH_SETATTR_CTIME; - } - if (!is_omit_timespec(&ft->create_time)) { - stx.stx_btime = ft->create_time; - mask |= CEPH_SETATTR_BTIME; - } + vfs_ceph_fill_statx_mask_from_ft(ft, &stx, &mask); if (!mask) { return 0; } @@ -3023,18 +3069,32 @@ static int vfs_ceph_fntimes(struct vfs_handle_struct *handle, files_struct *fsp, struct smb_file_time *ft) { - struct vfs_ceph_fh *cfh = NULL; int result; START_PROFILE(syscall_fntimes); - result = vfs_ceph_fetch_fh(handle, fsp, &cfh); - if (result != 0) { - goto out; - } - result = vfs_ceph_ll_futimes(handle, cfh, ft); - if (result != 0) { - goto out; + 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_futimes(handle, cfh, ft); + } 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_utimes(handle, &iref, ft); + vfs_ceph_iput(handle, &iref); } if (!is_omit_timespec(&ft->create_time)) { -- 2.48.1