From: Xavi Hernandez Date: Tue, 4 Mar 2025 11:48:41 +0000 (+0100) Subject: vfs_ceph_new: detect case sensitivity in CephFS X-Git-Tag: samba-4.22.1~38 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=09f3bbd41758fb402261121e6f3ffff52171b470;p=thirdparty%2Fsamba.git 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 Reviewed-by: Anoop C S Reviewed-by: Guenther Deschner Autobuild-User(master): Günther Deschner Autobuild-Date(master): Tue Mar 11 20:34:26 UTC 2025 on atb-devel-224 (cherry picked from commit a52602030e6ba0e1bcddf5f611464b58076fadd0) --- diff --git a/source3/modules/vfs_ceph_new.c b/source3/modules/vfs_ceph_new.c index 05c2a72d57f..4f1849b3ed5 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); @@ -1932,12 +1941,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 +2026,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 +2039,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",