The branch, v4-22-test has been updated
       via  2871634a9f3 vfs_ceph_new: Add path based fallback for 
SMB_VFS_FNTIMES
       via  d6232bbda2f vfs_ceph_new: Add path based fallback for SMB_VFS_FCHMOD
       via  112099fb110 vfs_ceph_new: Add path based fallback for SMB_VFS_FCHOWN
       via  b38c179898e s3/lib: fix matching interfaces with multiple assigned 
IPs
       via  09f3bbd4175 vfs_ceph_new: detect case sensitivity in CephFS
      from  bf440caab97 vfs_ceph_new: Do not resolve by inode number

https://git.samba.org/?p=samba.git;a=shortlog;h=v4-22-test


- Log -----------------------------------------------------------------
commit 2871634a9f3ca8748e4a59622e6dc4595d3535b7
Author: Anoop C S <[email protected]>
Date:   Mon Mar 17 19:52:10 2025 +0530

    vfs_ceph_new: Add path based fallback for SMB_VFS_FNTIMES
    
    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 <[email protected]>
    Reviewed-by: Guenther Deschner <[email protected]>
    
    Autobuild-User(master): Günther Deschner <[email protected]>
    Autobuild-Date(master): Mon Mar 17 20:48:55 UTC 2025 on atb-devel-224
    
    (cherry picked from commit dbc48a4cda7489363688bb38f6fa678011fedfaf)
    
    Autobuild-User(v4-22-test): Jule Anger <[email protected]>
    Autobuild-Date(v4-22-test): Tue Mar 18 16:50:49 UTC 2025 on atb-devel-224

commit d6232bbda2faa94bedac5d860065058b5189d22e
Author: Anoop C S <[email protected]>
Date:   Fri Mar 14 19:59:33 2025 +0530

    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 <[email protected]>
    Reviewed-by: Guenther Deschner <[email protected]>
    (cherry picked from commit 9c019ecf4eae6e6bef48323a0b093e17b0708ee8)

commit 112099fb1107f39577843bb428d3efed0c25323e
Author: Anoop C S <[email protected]>
Date:   Fri Mar 14 19:47:42 2025 +0530

    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 <[email protected]>
    Reviewed-by: Guenther Deschner <[email protected]>
    (cherry picked from commit abb97683902f50b2a57989f30c0fb53fd3492af9)

commit b38c179898e4279dabb0ce88a099759c01543dea
Author: Ralph Boehme <[email protected]>
Date:   Mon Mar 10 14:29:23 2025 +0100

    s3/lib: fix matching interfaces with multiple assigned IPs
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=15823
    
    Signed-off-by: Ralph Boehme <[email protected]>
    Reviewed-by: Björn Jacke <[email protected]>
    Reviewed-by: Martin Schwenke <[email protected]>
    
    Autobuild-User(master): Martin Schwenke <[email protected]>
    Autobuild-Date(master): Wed Mar 12 01:32:30 UTC 2025 on atb-devel-224
    
    (cherry picked from commit b85f056e7312ea9839b6fda617132fcc956da3c1)

commit 09f3bbd41758fb402261121e6f3ffff52171b470
Author: Xavi Hernandez <[email protected]>
Date:   Tue Mar 4 12:48:41 2025 +0100

    vfs_ceph_new: detect case sensitivity in CephFS
    
    CephFS has recently added support for case insensitive access to the
    file system. This modification detects whether the shared volume is case
    sensitive or not and reports the FILE_CASE_SENSITIVE_SEARCH capability
    accordingly.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=15822
    
    Signed-off-by: Xavi Hernandez <[email protected]>
    Reviewed-by: Anoop C S <[email protected]>
    Reviewed-by: Guenther Deschner <[email protected]>
    
    Autobuild-User(master): Günther Deschner <[email protected]>
    Autobuild-Date(master): Tue Mar 11 20:34:26 UTC 2025 on atb-devel-224
    
    (cherry picked from commit a52602030e6ba0e1bcddf5f611464b58076fadd0)

-----------------------------------------------------------------------

Summary of changes:
 source3/lib/interface.c        |   5 +-
 source3/modules/vfs_ceph_new.c | 276 +++++++++++++++++++++++++++++++++++------
 2 files changed, 243 insertions(+), 38 deletions(-)


Changeset truncated at 500 lines:

diff --git a/source3/lib/interface.c b/source3/lib/interface.c
index 032362b4da3..5f351999e41 100644
--- a/source3/lib/interface.c
+++ b/source3/lib/interface.c
@@ -624,9 +624,12 @@ static void interpret_interface(char *token)
                                }
                                add_interface(&probed_ifaces[i]);
                                probed_ifaces[i].netmask = saved_mask;
-                               return;
+                               added = true;
                        }
                }
+               if (added) {
+                       return;
+               }
                DEBUG(2,("interpret_interface: Can't determine ip for "
                        "broadcast address %s\n",
                        token));
diff --git a/source3/modules/vfs_ceph_new.c b/source3/modules/vfs_ceph_new.c
index 05c2a72d57f..b97279982cd 100644
--- a/source3/modules/vfs_ceph_new.c
+++ b/source3/modules/vfs_ceph_new.c
@@ -113,6 +113,15 @@ struct vfs_ceph_config {
        enum vfs_cephfs_proxy_mode proxy;
        void *libhandle;
 
+       /*
+       * This field stores the Samba capabilities for the share represented
+       * by this struct. The share capabilities are computed once during the
+       * module startup and then cached here for future references.
+       *
+       * It's completely independent of the CephFS capabilities concept.
+       */
+       uint32_t capabilities;
+
        CEPH_FN(ceph_ll_walk);
        CEPH_FN(ceph_ll_getattr);
        CEPH_FN(ceph_ll_setattr);
@@ -964,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)
@@ -984,6 +1023,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)
@@ -995,22 +1095,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;
        }
@@ -1932,12 +2017,79 @@ static uint64_t vfs_ceph_disk_free(struct 
vfs_handle_struct *handle,
        return *dfree;
 }
 
+static int vfs_ceph_check_case_sensitivity(struct vfs_handle_struct *handle,
+                                          uint32_t *capabilities)
+{
+       struct vfs_ceph_iref iref = {0};
+       char value[8] = {0};
+       struct vfs_ceph_config *config = NULL;
+       uint32_t caps;
+       int ret;
+
+       SMB_VFS_HANDLE_GET_DATA(handle, config, struct vfs_ceph_config,
+                               return -ENOMEM);
+
+       if (config->capabilities != 0) {
+               *capabilities = config->capabilities;
+               return 0;
+       }
+
+       /*
+        * In CephFS, case sensitivity configuration is inherited by default,
+        * but it can be manually overridden by an administrator. Samba assumes
+        * that all directories inherit the configuration from the root of the
+        * share and the administrator doesn't change it manually.
+        */
+       ret = vfs_ceph_iget(handle, handle->conn->connectpath, 0, &iref);
+       if (ret != 0) {
+               return ret;
+       }
+
+       caps = FILE_CASE_PRESERVED_NAMES;
+
+       ret = vfs_ceph_ll_getxattr(handle, &iref, "ceph.dir.casesensitive",
+                                  value, sizeof(value) - 1);
+       if (ret < 0) {
+               if (ret != -ENODATA) {
+                       DBG_ERR("[CEPH] failed to get case sensitivity "
+                               "settings: path='%s' %s",
+                               handle->conn->connectpath, strerror(-ret));
+                       goto out;
+               }
+
+               /*
+                * The xattr is not defined, so the filesystem is case sensitive
+                * by default.
+                */
+               caps |= FILE_CASE_SENSITIVE_SEARCH;
+       } else {
+               /*
+                * We only accept "0" as 'false' (as defined in the CephFS
+                * documentation). All other values are interpreted as 'true'
+                */
+               if (strcmp(value, "0") != 0) {
+                       caps |= FILE_CASE_SENSITIVE_SEARCH;
+               }
+       }
+
+       config->capabilities = caps;
+       *capabilities = caps;
+
+       ret = 0;
+
+out:
+       vfs_ceph_iput(handle, &iref);
+
+       return ret;
+}
+
 static int vfs_ceph_statvfs(struct vfs_handle_struct *handle,
                            const struct smb_filename *smb_fname,
                            struct vfs_statvfs_struct *statbuf)
 {
        struct statvfs statvfs_buf = { 0 };
        struct vfs_ceph_iref iref = {0};
+       uint32_t caps = 0;
        int ret;
 
        ret = vfs_ceph_iget(handle, smb_fname->base_name, 0, &iref);
@@ -1950,6 +2102,11 @@ static int vfs_ceph_statvfs(struct vfs_handle_struct 
*handle,
                goto out;
        }
 
+       ret = vfs_ceph_check_case_sensitivity(handle, &caps);
+       if (ret < 0) {
+               goto out;
+       }
+
        statbuf->OptimalTransferSize = statvfs_buf.f_frsize;
        statbuf->BlockSize = statvfs_buf.f_bsize;
        statbuf->TotalBlocks = statvfs_buf.f_blocks;
@@ -1958,8 +2115,7 @@ static int vfs_ceph_statvfs(struct vfs_handle_struct 
*handle,
        statbuf->TotalFileNodes = statvfs_buf.f_files;
        statbuf->FreeFileNodes = statvfs_buf.f_ffree;
        statbuf->FsIdentifier = statvfs_buf.f_fsid;
-       statbuf->FsCapabilities =
-               FILE_CASE_SENSITIVE_SEARCH | FILE_CASE_PRESERVED_NAMES;
+       statbuf->FsCapabilities = caps;
 
        DBG_DEBUG("[CEPH] f_bsize: %ld, f_blocks: %ld, f_bfree: %ld, "
                  "f_bavail: %ld\n",
@@ -3000,18 +3156,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)) {
@@ -3066,16 +3236,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);
@@ -3088,15 +3272,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);


-- 
Samba Shared Repository

Reply via email to