]> git.ipfire.org Git - thirdparty/samba.git/commitdiff
vfs_ceph_new: Add path based fallback for SMB_VFS_FCHMOD
authorAnoop C S <anoopcs@samba.org>
Fri, 14 Mar 2025 14:29:33 +0000 (19:59 +0530)
committerJule Anger <janger@samba.org>
Mon, 24 Mar 2025 12:51:09 +0000 (12:51 +0000)
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 <anoopcs@samba.org>
Reviewed-by: Guenther Deschner <gd@samba.org>
(cherry picked from commit 9c019ecf4eae6e6bef48323a0b093e17b0708ee8)

source3/modules/vfs_ceph_new.c

index cd06fbcd3776b87253797f4fff5c3be14573e204..a0b05240b34452e6b5dd103be5130f083332e193 100644 (file)
@@ -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);