[SCM] Samba Shared Repository - branch master updated

Günther Deschner gd at samba.org
Mon Jul 29 15:59:01 UTC 2024


The branch, master has been updated
       via  3bb6d441bf0 vfs_ceph_new: common prefix to debug-log messages
       via  d00f20f30f4 vfs_ceph_new: debug-log upon libcephfs low-level calls
       via  0a8445e891c vfs_ceph_new: use low-level APIs for xattr ops
       via  e714e5ddc50 vfs_ceph_new: use low-level APIs for mknodat
       via  83011357fb8 vfs_ceph_new: use low-level APIs for renameat
       via  9a70bd60672 vfs_ceph_new: use low-level APIs for linkat
       via  b536bf1fa87 vfs_ceph_new: use low-level APIs for ftruncate/fallocate
       via  e15586fc609 vfs_ceph_new: use low-level APIs for fsync
       via  30c1a613fee vfs_ceph_new: use low-level APIs for lseek
       via  29bbe0f52d4 vfs_ceph_new: use low-level APIs for read/write
       via  53c9269b219 vfs_ceph_new: use low-level APIs for symlink/readlink
       via  362a7cf8664 vfs_ceph_new: use low-level APIs for unlinkat
       via  20b7d2bfe06 vfs_ceph_new: use low-level APIs for fntimes
       via  cb14d3630d8 vfs_ceph_new: use low-level APIs for fchown/fchmod
       via  24a3423949e vfs_ceph_new: proper error handling to readdir
       via  99c7179e5da vfs_ceph_new: use low-level APIs for readdir ops
       via  bd955af86e7 vfs_ceph_new: use low-level APIs for mkdirat
       via  a8a7339c6b7 vfs_ceph_new: use low-level APIs for fdopendir
       via  13671cefffb vfs_ceph_new: use low-level APIs for fstatat
       via  f16183f90ab vfs_ceph_new: use low-level APIs for fstat
       via  49167684645 vfs_ceph_new: use low-level APIs for open/close
       via  31085c7efc3 vfs_ceph_new: ref cephmount_cached entry in handle->data
       via  beb21324c9a vfs_ceph_new: use low-level APIs for lchown
       via  47224fbdeb5 vfs_ceph_new: use low-level APIs for statfs
       via  93d786b1435 vfs_ceph_new: use low-level APIs for lstat
       via  1b78d79663c vfs_ceph_new: use low-level APIs for stat
       via  192b0cf8717 vfs_ceph_new: use low-level APIs for disk_free
       via  3720452720b vfs_ceph_new: next iteration of samba-to-cephfs bridge
      from  dbc5b73d860 ldb: change the version to 2.11.0 for Samba 4.22

https://git.samba.org/?p=samba.git;a=shortlog;h=master


- Log -----------------------------------------------------------------
commit 3bb6d441bf047bef6d95675057cecd3865a25540
Author: Shachar Sharon <ssharon at redhat.com>
Date:   Tue Jul 16 14:33:16 2024 +0300

    vfs_ceph_new: common prefix to debug-log messages
    
    Keep logging consistent: add "[CEPH] " prefix to DBG_DEBUG log messages
    where missing.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=15686
    
    Signed-off-by: Shachar Sharon <ssharon at redhat.com>
    Reviewed-by: Guenther Deschner <gd at samba.org>
    Reviewed-by: Anoop C S <anoopcs at samba.org>
    
    Autobuild-User(master): Günther Deschner <gd at samba.org>
    Autobuild-Date(master): Mon Jul 29 15:58:15 UTC 2024 on atb-devel-224

commit d00f20f30f4e77463e82d202099682b7ef68260f
Author: Shachar Sharon <ssharon at redhat.com>
Date:   Wed Jun 26 17:24:37 2024 +0300

    vfs_ceph_new: debug-log upon libcephfs low-level calls
    
    Add developer's debug-logging upon each call to libcephfs' low-level
    APIs.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=15686
    
    Signed-off-by: Shachar Sharon <ssharon at redhat.com>
    Reviewed-by: Guenther Deschner <gd at samba.org>
    Reviewed-by: Anoop C S <anoopcs at samba.org>

commit 0a8445e891c64d703d44258b2eef85296265c55f
Author: Shachar Sharon <ssharon at redhat.com>
Date:   Sun Jun 23 14:57:10 2024 +0300

    vfs_ceph_new: use low-level APIs for xattr ops
    
    Implement extended-attributes operations using libcephfs' low-level
    APIs. Whenever possible, use the open file-handle from fsp-extension to
    resolve inode-reference and user-permissions. Otherwise, resolve both
    on-the-fly.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=15686
    
    Signed-off-by: Shachar Sharon <ssharon at redhat.com>
    Reviewed-by: Guenther Deschner <gd at samba.org>
    Reviewed-by: Anoop C S <anoopcs at samba.org>

commit e714e5ddc50a771e743f5e63f686c106abe33b75
Author: Shachar Sharon <ssharon at redhat.com>
Date:   Sun Jun 23 13:08:25 2024 +0300

    vfs_ceph_new: use low-level APIs for mknodat
    
    Implement mknodat operations using libcephfs' low-level APIs. Requires
    parent directory to have valid inode-ref associated with its fsp
    extension.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=15686
    
    Signed-off-by: Shachar Sharon <ssharon at redhat.com>
    Reviewed-by: Guenther Deschner <gd at samba.org>
    Reviewed-by: Anoop C S <anoopcs at samba.org>

commit 83011357fb834e92505f17d6f65d5f32e3d37ec0
Author: Shachar Sharon <ssharon at redhat.com>
Date:   Sun Jun 23 12:47:19 2024 +0300

    vfs_ceph_new: use low-level APIs for renameat
    
    Implement renameat operations using libcephfs' low-level APIs. Requires
    both directories to have valid inode-ref associated with their fsp
    extension.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=15686
    
    Signed-off-by: Shachar Sharon <ssharon at redhat.com>
    Reviewed-by: Guenther Deschner <gd at samba.org>
    Reviewed-by: Anoop C S <anoopcs at samba.org>

commit 9a70bd606728110ad91cab547a4e31350010bb68
Author: Shachar Sharon <ssharon at redhat.com>
Date:   Thu Jun 20 22:46:52 2024 +0300

    vfs_ceph_new: use low-level APIs for linkat
    
    Implement link operations using libcephfs' low-level APIs. Requires two
    phase operation: resolve (by-lookup) reference to inode and then do the
    actual (hard) link operation using parent dir-inode reference to the
    locally-cached inode.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=15686
    
    Signed-off-by: Shachar Sharon <ssharon at redhat.com>
    Reviewed-by: Guenther Deschner <gd at samba.org>
    Reviewed-by: Anoop C S <anoopcs at samba.org>

commit b536bf1fa87fb794e2992ab5368f41fdba80e3ad
Author: Shachar Sharon <ssharon at redhat.com>
Date:   Thu Jun 20 14:58:34 2024 +0300

    vfs_ceph_new: use low-level APIs for ftruncate/fallocate
    
    Implement ftruncate/fallocate operations using libcephfs' low-level
    APIs. Requires open ceph Fh* associated with fsp (extension).
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=15686
    
    Signed-off-by: Shachar Sharon <ssharon at redhat.com>
    Reviewed-by: Guenther Deschner <gd at samba.org>
    Reviewed-by: Anoop C S <anoopcs at samba.org>

commit e15586fc6097565208011c556282d83eeec2230b
Author: Shachar Sharon <ssharon at redhat.com>
Date:   Thu Jun 20 12:43:39 2024 +0300

    vfs_ceph_new: use low-level APIs for fsync
    
    Implement fsync operation using libcephfs' low-level APIs. Requires
    open ceph Fh* associated with fsp (extension).
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=15686
    
    Signed-off-by: Shachar Sharon <ssharon at redhat.com>
    Reviewed-by: Guenther Deschner <gd at samba.org>
    Reviewed-by: Anoop C S <anoopcs at samba.org>

commit 30c1a613fee3f625c0559e49e037af9fad04c3b8
Author: Shachar Sharon <ssharon at redhat.com>
Date:   Thu Jun 20 12:23:03 2024 +0300

    vfs_ceph_new: use low-level APIs for lseek
    
    Implement lseek operation using libcephfs' low-level APIs. Requires
    open ceph Fh* associated with fsp (extension).
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=15686
    
    Signed-off-by: Shachar Sharon <ssharon at redhat.com>
    Reviewed-by: Guenther Deschner <gd at samba.org>
    Reviewed-by: Anoop C S <anoopcs at samba.org>

commit 29bbe0f52d4ffae9dbb070ffc525acf99203444b
Author: Shachar Sharon <ssharon at redhat.com>
Date:   Wed Jun 19 17:52:45 2024 +0300

    vfs_ceph_new: use low-level APIs for read/write
    
    Implement read/write IO operations using libcephfs' low-level APIs.
    Requires open ceph Fh* associated with fsp (extension) to complete both
    pread/pwrite as well as async I/O operations.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=15686
    
    Signed-off-by: Shachar Sharon <ssharon at redhat.com>
    Reviewed-by: Guenther Deschner <gd at samba.org>
    Reviewed-by: Anoop C S <anoopcs at samba.org>

commit 53c9269b219a54236500d22d8a4c7f2ed582faaf
Author: Shachar Sharon <ssharon at redhat.com>
Date:   Wed Jun 26 13:46:54 2024 +0300

    vfs_ceph_new: use low-level APIs for symlink/readlink
    
    Implement unlinkat using libcephfs low-level APIs. For readlink
    operation need to resolve child inode by-lookup and then used the inode
    reference for the actual low-level readlink.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=15686
    
    Signed-off-by: Shachar Sharon <ssharon at redhat.com>
    Reviewed-by: Guenther Deschner <gd at samba.org>
    Reviewed-by: Anoop C S <anoopcs at samba.org>

commit 362a7cf8664270145bff815347e447797cc1a643
Author: Shachar Sharon <ssharon at redhat.com>
Date:   Wed Jun 19 14:27:24 2024 +0300

    vfs_ceph_new: use low-level APIs for unlinkat
    
    Implement unlinkat using libcephfs low-level APIs. Operate using parent
    directory's open file-handle. When flags has AT_REMOVEDIR bit set call
    low-level rmdir; otherwise, do normal unlink.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=15686
    
    Signed-off-by: Shachar Sharon <ssharon at redhat.com>
    Reviewed-by: Guenther Deschner <gd at samba.org>
    Reviewed-by: Anoop C S <anoopcs at samba.org>

commit 20b7d2bfe06beefb5e7f091eb317ad18cb53f8a9
Author: Shachar Sharon <ssharon at redhat.com>
Date:   Wed Jun 19 13:59:53 2024 +0300

    vfs_ceph_new: use low-level APIs for fntimes
    
    Implement fntimes hook using libcephfs' low-level APIs. Convert
    smb_file_time to ceph_statx plus proper field mask on-the-fly upon
    issuing low-level call to libcephfs.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=15686
    
    Signed-off-by: Shachar Sharon <ssharon at redhat.com>
    Reviewed-by: Guenther Deschner <gd at samba.org>
    Reviewed-by: Anoop C S <anoopcs at samba.org>

commit cb14d3630d8c110405c2a43bef15aa31ec4a0fba
Author: Shachar Sharon <ssharon at redhat.com>
Date:   Wed Jun 19 12:48:14 2024 +0300

    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 <ssharon at redhat.com>
    Reviewed-by: Guenther Deschner <gd at samba.org>
    Reviewed-by: Anoop C S <anoopcs at samba.org>

commit 24a3423949e127177c019a0d126c6f7523e61984
Author: Shachar Sharon <ssharon at redhat.com>
Date:   Wed Jul 17 11:41:13 2024 +0300

    vfs_ceph_new: proper error handling to readdir
    
    Error handling in the case of 'ceph_readdir' is done by setting 'errno'
    deep within libcephfs code. In case of error, emit proper debug message
    and re-update errno to avoid possible over-write by logging mechanism.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=15686
    
    Signed-off-by: Shachar Sharon <ssharon at redhat.com>
    Reviewed-by: Guenther Deschner <gd at samba.org>
    Reviewed-by: Anoop C S <anoopcs at samba.org>

commit 99c7179e5da6d201f03b1a04dbe2a6722090783d
Author: Shachar Sharon <ssharon at redhat.com>
Date:   Mon Jun 24 13:33:05 2024 +0300

    vfs_ceph_new: use low-level APIs for readdir ops
    
    Implement readdir and rewinddir operations using libcephfs' low-level
    APIs. Casts the opaque DIR pointer into struct vfs_ceph_dirp (the first
    member of struct vfs_ceph_fh) to resolve the ceph_dir_result pointer
    which libcephfs expects for readdir operations.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=15686
    
    Signed-off-by: Shachar Sharon <ssharon at redhat.com>
    Reviewed-by: Guenther Deschner <gd at samba.org>
    Reviewed-by: Anoop C S <anoopcs at samba.org>

commit bd955af86e71fa6c87648e578890ea6f4d490d4b
Author: Shachar Sharon <ssharon at redhat.com>
Date:   Wed Jun 19 11:55:27 2024 +0300

    vfs_ceph_new: use low-level APIs for mkdirat
    
    Implement 'mkdirat' hook using libcephfs' low-level APIs, via the open
    file-handle reference to parent directory.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=15686
    
    Signed-off-by: Shachar Sharon <ssharon at redhat.com>
    Reviewed-by: Guenther Deschner <gd at samba.org>
    Reviewed-by: Anoop C S <anoopcs at samba.org>

commit a8a7339c6b7a6866399fd6c409228267a585740f
Author: Shachar Sharon <ssharon at redhat.com>
Date:   Tue Jun 18 17:20:59 2024 +0300

    vfs_ceph_new: use low-level APIs for fdopendir
    
    Implement fdopendir using libcephfs low-level API and cached (via fsp)
    open file-handle. Embed the result within cached vfs_ceph_fh so it may
    be used properly by closedir.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=15686
    
    Signed-off-by: Shachar Sharon <ssharon at redhat.com>
    Reviewed-by: Guenther Deschner <gd at samba.org>
    Reviewed-by: Anoop C S <anoopcs at samba.org>

commit 13671cefffb268d84c973583669681318a2ce3bb
Author: Shachar Sharon <ssharon at redhat.com>
Date:   Wed Jun 19 12:35:11 2024 +0300

    vfs_ceph_new: use low-level APIs for fstatat
    
    Use libcephfs' low-level APIs to do lookup-by-name via parent's open
    reference followed by getattr on the inode itself.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=15686
    
    Signed-off-by: Shachar Sharon <ssharon at redhat.com>
    Reviewed-by: Guenther Deschner <gd at samba.org>
    Reviewed-by: Anoop C S <anoopcs at samba.org>

commit f16183f90abba3c2d3d26262926f1454275a9d3f
Author: Shachar Sharon <ssharon at redhat.com>
Date:   Mon Jun 24 11:39:43 2024 +0300

    vfs_ceph_new: use low-level APIs for fstat
    
    Use libcephfs' low-level APIs and apply the same logic as stat, but
    via explicit inode-reference.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=15686
    
    Signed-off-by: Shachar Sharon <ssharon at redhat.com>
    Reviewed-by: Guenther Deschner <gd at samba.org>
    Reviewed-by: Anoop C S <anoopcs at samba.org>

commit 491676846458980944b76d1693726627a9a32503
Author: Shachar Sharon <ssharon at redhat.com>
Date:   Tue Jun 18 15:02:52 2024 +0300

    vfs_ceph_new: use low-level APIs for open/close
    
    Implement openat, close and closedir and hooks using libcephfs'
    low-level APIs. Cache the open Fh* from libcephfs and its related
    meta-data using VFS fsp-extension mechanism.
    
    Upon open-create of new vfs_ceph_fh store the caller credentials
    (ceph's UserPerm*) within the same context object for subsequent calls.
    In addition, provide a "pseudo" fd numbering which is reported back to
    VFS layer and used as debugging hints.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=15686
    
    Signed-off-by: Shachar Sharon <ssharon at redhat.com>
    Reviewed-by: Guenther Deschner <gd at samba.org>
    Reviewed-by: Anoop C S <anoopcs at samba.org>

commit 31085c7efc3572bd6200d3d8e49c1e554cdbfbcc
Author: Shachar Sharon <ssharon at redhat.com>
Date:   Tue Jun 18 12:58:52 2024 +0300

    vfs_ceph_new: ref cephmount_cached entry in handle->data
    
    Allow direct access to ceph-mount cached-entry via 'handle->data'
    private pointer. Required in order to allow more complex cached-state
    with each cephfs mount. Users should now use the local-helper function
    'cmount_of' to access the underlying ceph_mount_info.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=15686
    
    Signed-off-by: Shachar Sharon <ssharon at redhat.com>
    Reviewed-by: Guenther Deschner <gd at samba.org>
    Reviewed-by: Anoop C S <anoopcs at samba.org>

commit beb21324c9a554f50d8d99af2a1b7fe8a17c8ebb
Author: Shachar Sharon <ssharon at redhat.com>
Date:   Mon Jun 17 16:59:05 2024 +0300

    vfs_ceph_new: use low-level APIs for lchown
    
    Use libcephfs' low-level API ceph_ll_setattr to implement VFS lchown_fn
    hook. Use to standard pattern of iget/iput to allow operation by Inode
    reference.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=15686
    
    Signed-off-by: Shachar Sharon <ssharon at redhat.com>
    Reviewed-by: Guenther Deschner <gd at samba.org>
    Reviewed-by: Anoop C S <anoopcs at samba.org>

commit 47224fbdeb55100cf8a7ee75e13b954ab71fc158
Author: Shachar Sharon <ssharon at redhat.com>
Date:   Mon Jun 17 18:02:07 2024 +0300

    vfs_ceph_new: use low-level APIs for statfs
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=15686
    
    Signed-off-by: Shachar Sharon <ssharon at redhat.com>
    Reviewed-by: Guenther Deschner <gd at samba.org>
    Reviewed-by: Anoop C S <anoopcs at samba.org>

commit 93d786b14358db5664e13b1aa43f3f03e7cf0be3
Author: Shachar Sharon <ssharon at redhat.com>
Date:   Mon Jun 17 15:57:42 2024 +0300

    vfs_ceph_new: use low-level APIs for lstat
    
    Use libcephfs' low-level APIs and apply the same logic as stat, but
    using AT_SYMLINK_NOFOLLOW flags.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=15686
    
    Signed-off-by: Shachar Sharon <ssharon at redhat.com>
    Reviewed-by: Guenther Deschner <gd at samba.org>
    Reviewed-by: Anoop C S <anoopcs at samba.org>

commit 1b78d79663c48aa4b6810a875427de85ae49a2e8
Author: Shachar Sharon <ssharon at redhat.com>
Date:   Mon Jun 17 12:11:18 2024 +0300

    vfs_ceph_new: use low-level APIs for stat
    
    Start migrating to libcephfs' low-level APIs, using explicit Inode*
    reference. Implement the VFS 'stat' hook using a ceph_ll_getattr
    function, encapsulated with a pair of iget/iput to hold a
    pinned-to-cache Inode* instance.
    
    Upon calling to libcephfs this new code crates and destroys on-the-fly
    a Ceph UserPerm instance based on the uig, gid and groups from
    'handle->conn->session_info->unix_token'. This logic ensures that the
    correct caller-credentials are passed-on to cephfs (instead of those
    set upon connection-creation in legacy 'vfs_ceph.c').
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=15686
    
    Signed-off-by: Shachar Sharon <ssharon at redhat.com>
    Reviewed-by: Guenther Deschner <gd at samba.org>
    Reviewed-by: Anoop C S <anoopcs at samba.org>

commit 192b0cf8717d79197b985539c9db8ca07a89c570
Author: Shachar Sharon <ssharon at redhat.com>
Date:   Sun Jun 16 14:50:08 2024 +0300

    vfs_ceph_new: use low-level APIs for disk_free
    
    Start using libcephfs low-level APIs: get reference to root inode and
    use it to query statfs. Requires an explicit put-inode to avoid resource
    leakage by libcephfs.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=15686
    
    Signed-off-by: Shachar Sharon <ssharon at redhat.com>
    Reviewed-by: Guenther Deschner <gd at samba.org>
    Reviewed-by: Anoop C S <anoopcs at samba.org>

commit 3720452720b4760509875f0d2a8ed0d104bb1844
Author: Shachar Sharon <ssharon at redhat.com>
Date:   Thu Jun 13 15:54:48 2024 +0300

    vfs_ceph_new: next iteration of samba-to-cephfs bridge
    
    Defined new module 'vfs_ceph_new.c' which serves as a place holder for
    the next development phase of the bridge between samba's VFS layer and
    libcephfs. Begin with a module which is almost identical to existing
    'vfs_ceph.c', except for hooks-names prefix which is 'vfs_ceph_' in
    order to make clear distinction from existing code base. Following
    commits will also switch to low-level APIs.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=15686
    
    Signed-off-by: Shachar Sharon <ssharon at redhat.com>
    Reviewed-by: Guenther Deschner <gd at samba.org>
    Reviewed-by: Anoop C S <anoopcs at samba.org>

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

Summary of changes:
 source3/modules/vfs_ceph_new.c | 3117 ++++++++++++++++++++++++++++++++++++++++
 source3/modules/wscript_build  |   10 +
 source3/wscript                |    1 +
 3 files changed, 3128 insertions(+)
 create mode 100644 source3/modules/vfs_ceph_new.c


Changeset truncated at 500 lines:

diff --git a/source3/modules/vfs_ceph_new.c b/source3/modules/vfs_ceph_new.c
new file mode 100644
index 00000000000..3c82730f87c
--- /dev/null
+++ b/source3/modules/vfs_ceph_new.c
@@ -0,0 +1,3117 @@
+/*
+   Unix SMB/CIFS implementation.
+   Wrap disk only vfs functions to sidestep dodgy compilers.
+   Copyright (C) Tim Potter 1998
+   Copyright (C) Jeremy Allison 2007
+   Copyright (C) Brian Chrisman 2011 <bchrisman at gmail.com>
+   Copyright (C) Richard Sharpe 2011 <realrichardsharpe at gmail.com>
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+/*
+ * This VFS only works with the libcephfs.so user-space client. It is not needed
+ * if you are using the kernel client or the FUSE client.
+ *
+ * Add the following smb.conf parameter to each share that will be hosted on
+ * Ceph:
+ *
+ *   vfs objects = [any others you need go here] ceph_new
+ */
+
+#include "includes.h"
+#include "smbd/smbd.h"
+#include "system/filesys.h"
+#include <dirent.h>
+#include <sys/statvfs.h>
+#include "cephfs/libcephfs.h"
+#include "smbprofile.h"
+#include "modules/posixacl_xattr.h"
+#include "lib/util/tevent_unix.h"
+
+#undef DBGC_CLASS
+#define DBGC_CLASS DBGC_VFS
+
+#ifndef LIBCEPHFS_VERSION
+#define LIBCEPHFS_VERSION(maj, min, extra) ((maj << 16) + (min << 8) + extra)
+#define LIBCEPHFS_VERSION_CODE LIBCEPHFS_VERSION(0, 0, 0)
+#endif
+
+/*
+ * Use %llu whenever we have a 64bit unsigned int, and cast to (long long
+ * unsigned)
+ */
+#define llu(_var) ((long long unsigned)_var)
+
+/*
+ * Note, libcephfs's return code model is to return -errno. Thus we have to
+ * convert to what Samba expects: set errno to non-negative value and return -1.
+ *
+ * Using convenience helper functions to avoid non-hygienic macro.
+ */
+static int status_code(int ret)
+{
+	if (ret < 0) {
+		errno = -ret;
+		return -1;
+	}
+	errno = 0;
+	return ret;
+}
+
+static ssize_t lstatus_code(intmax_t ret)
+{
+	if (ret < 0) {
+		errno = -((int)ret);
+		return -1;
+	}
+	errno = 0;
+	return (ssize_t)ret;
+}
+
+/*
+ * Track unique connections, as virtual mounts, to cephfs file systems.
+ * Individual mount-entries will be set on the handle->data attribute, but
+ * the mounts themselves will be shared so as not to spawn extra mounts
+ * to the same cephfs.
+ *
+ * Individual mounts are IDed by a 'cookie' value that is a string built
+ * from identifying parameters found in smb.conf.
+ */
+
+static struct cephmount_cached {
+	char *cookie;
+	uint32_t count;
+	struct ceph_mount_info *mount;
+	struct cephmount_cached *next, *prev;
+	uint64_t fd_index;
+} *cephmount_cached;
+
+static int cephmount_cache_add(const char *cookie,
+			       struct ceph_mount_info *mount,
+			       struct cephmount_cached **out_entry)
+{
+	struct cephmount_cached *entry = NULL;
+
+	entry = talloc_zero(NULL, struct cephmount_cached);
+	if (entry == NULL) {
+		errno = ENOMEM;
+		return -1;
+	}
+
+	entry->cookie = talloc_strdup(entry, cookie);
+	if (entry->cookie == NULL) {
+		talloc_free(entry);
+		errno = ENOMEM;
+		return -1;
+	}
+
+	entry->mount = mount;
+	entry->count = 1;
+
+	DBG_DEBUG("[CEPH] adding mount cache entry for %s\n", entry->cookie);
+	DLIST_ADD(cephmount_cached, entry);
+
+	*out_entry = entry;
+	return 0;
+}
+
+static struct cephmount_cached *cephmount_cache_update(const char *cookie)
+{
+	struct cephmount_cached *entry = NULL;
+
+	for (entry = cephmount_cached; entry; entry = entry->next) {
+		if (strcmp(entry->cookie, cookie) == 0) {
+			entry->count++;
+			DBG_DEBUG("[CEPH] updated mount cache: count is [%"
+				  PRIu32 "]\n", entry->count);
+			return entry;
+		}
+	}
+
+	errno = ENOENT;
+	return NULL;
+}
+
+static int cephmount_cache_remove(struct cephmount_cached *entry)
+{
+	if (--entry->count) {
+		DBG_DEBUG("[CEPH] updated mount cache: count is [%"
+			  PRIu32 "]\n", entry->count);
+		return entry->count;
+	}
+
+	DBG_DEBUG("[CEPH] removing mount cache entry for %s\n", entry->cookie);
+	DLIST_REMOVE(cephmount_cached, entry);
+	talloc_free(entry);
+	return 0;
+}
+
+static char *cephmount_get_cookie(TALLOC_CTX * mem_ctx, const int snum)
+{
+	const char *conf_file =
+	    lp_parm_const_string(snum, "ceph", "config_file", ".");
+	const char *user_id = lp_parm_const_string(snum, "ceph", "user_id", "");
+	const char *fsname =
+	    lp_parm_const_string(snum, "ceph", "filesystem", "");
+	return talloc_asprintf(mem_ctx, "(%s/%s/%s)", conf_file, user_id,
+			       fsname);
+}
+
+static int cephmount_select_fs(struct ceph_mount_info *mnt, const char *fsname)
+{
+	/*
+	 * ceph_select_filesystem was added in ceph 'nautilus' (v14).
+	 * Earlier versions of libcephfs will lack that API function.
+	 * At the time of this writing (Feb 2023) all versions of ceph
+	 * supported by ceph upstream have this function.
+	 */
+#if defined(HAVE_CEPH_SELECT_FILESYSTEM)
+	DBG_DEBUG("[CEPH] calling: ceph_select_filesystem with %s\n", fsname);
+	return ceph_select_filesystem(mnt, fsname);
+#else
+	DBG_ERR("[CEPH] ceph_select_filesystem not available\n");
+	return -ENOTSUP;
+#endif
+}
+
+static struct ceph_mount_info *cephmount_mount_fs(const int snum)
+{
+	int ret;
+	char buf[256];
+	struct ceph_mount_info *mnt = NULL;
+	/* if config_file and/or user_id are NULL, ceph will use defaults */
+	const char *conf_file =
+	    lp_parm_const_string(snum, "ceph", "config_file", NULL);
+	const char *user_id =
+	    lp_parm_const_string(snum, "ceph", "user_id", NULL);
+	const char *fsname =
+	    lp_parm_const_string(snum, "ceph", "filesystem", NULL);
+
+	DBG_DEBUG("[CEPH] calling: ceph_create\n");
+	ret = ceph_create(&mnt, user_id);
+	if (ret) {
+		errno = -ret;
+		return NULL;
+	}
+
+	DBG_DEBUG("[CEPH] calling: ceph_conf_read_file with %s\n",
+		  (conf_file == NULL ? "default path" : conf_file));
+	ret = ceph_conf_read_file(mnt, conf_file);
+	if (ret) {
+		goto err_cm_release;
+	}
+
+	DBG_DEBUG("[CEPH] calling: ceph_conf_get\n");
+	ret = ceph_conf_get(mnt, "log file", buf, sizeof(buf));
+	if (ret < 0) {
+		goto err_cm_release;
+	}
+
+	/* libcephfs disables POSIX ACL support by default, enable it... */
+	ret = ceph_conf_set(mnt, "client_acl_type", "posix_acl");
+	if (ret < 0) {
+		goto err_cm_release;
+	}
+	/* tell libcephfs to perform local permission checks */
+	ret = ceph_conf_set(mnt, "fuse_default_permissions", "false");
+	if (ret < 0) {
+		goto err_cm_release;
+	}
+	/*
+	 * select a cephfs file system to use:
+	 * In ceph, multiple file system support has been stable since
+	 * 'pacific'. Permit different shares to access different file systems.
+	 */
+	if (fsname != NULL) {
+		ret = cephmount_select_fs(mnt, fsname);
+		if (ret < 0) {
+			goto err_cm_release;
+		}
+	}
+
+	DBG_DEBUG("[CEPH] calling: ceph_mount\n");
+	ret = ceph_mount(mnt, NULL);
+	if (ret >= 0) {
+		goto cm_done;
+	}
+
+      err_cm_release:
+	ceph_release(mnt);
+	mnt = NULL;
+	DBG_DEBUG("[CEPH] Error mounting fs: %s\n", strerror(-ret));
+      cm_done:
+	/*
+	 * Handle the error correctly. Ceph returns -errno.
+	 */
+	if (ret) {
+		errno = -ret;
+	}
+	return mnt;
+}
+
+/* Check for NULL pointer parameters in vfs_ceph_* functions */
+
+/* We don't want to have NULL function pointers lying around.  Someone
+   is sure to try and execute them.  These stubs are used to prevent
+   this possibility. */
+
+static int vfs_ceph_connect(struct vfs_handle_struct *handle,
+			    const char *service, const char *user)
+{
+	int ret = 0;
+	struct cephmount_cached *entry = NULL;
+	struct ceph_mount_info *cmount = NULL;
+	int snum = SNUM(handle->conn);
+	char *cookie = cephmount_get_cookie(handle, snum);
+	if (cookie == NULL) {
+		return -1;
+	}
+
+	entry = cephmount_cache_update(cookie);
+	if (entry != NULL) {
+		goto connect_ok;
+	}
+
+	cmount = cephmount_mount_fs(snum);
+	if (cmount == NULL) {
+		ret = -1;
+		goto connect_fail;
+	}
+	ret = cephmount_cache_add(cookie, cmount, &entry);
+	if (ret != 0) {
+		goto connect_fail;
+	}
+
+connect_ok:
+	handle->data = entry;
+	DBG_WARNING("Connection established with the server: %s\n", cookie);
+
+	/*
+	 * Unless we have an async implementation of getxattrat turn this off.
+	 */
+	lp_do_parameter(SNUM(handle->conn), "smbd async dosmode", "false");
+connect_fail:
+	talloc_free(cookie);
+	return ret;
+}
+
+static struct ceph_mount_info *cmount_of(const struct vfs_handle_struct *handle)
+{
+	const struct cephmount_cached *entry = handle->data;
+
+	return entry->mount;
+}
+
+static void vfs_ceph_disconnect(struct vfs_handle_struct *handle)
+{
+	struct ceph_mount_info *cmount = cmount_of(handle);
+	int ret = 0;
+
+	ret = cephmount_cache_remove(handle->data);
+	if (ret > 0) {
+		DBG_DEBUG("[CEPH] mount cache entry still in use\n");
+		return;
+	}
+
+	ret = ceph_unmount(cmount);
+	if (ret < 0) {
+		DBG_ERR("[CEPH] failed to unmount: %s\n", strerror(-ret));
+	}
+
+	ret = ceph_release(cmount);
+	if (ret < 0) {
+		DBG_ERR("[CEPH] failed to release: %s\n", strerror(-ret));
+	}
+	handle->data = NULL;
+}
+
+/* Ceph user-credentials */
+static struct UserPerm *vfs_ceph_userperm_new(
+	const struct vfs_handle_struct *handle)
+{
+	const struct security_unix_token *unix_token = NULL;
+
+	unix_token = get_current_utok(handle->conn);
+	return ceph_userperm_new(unix_token->uid,
+				 unix_token->gid,
+				 unix_token->ngroups,
+				 unix_token->groups);
+}
+
+static void vfs_ceph_userperm_del(struct UserPerm *uperm)
+{
+	if (uperm != NULL) {
+		ceph_userperm_destroy(uperm);
+	}
+}
+
+/* Ceph's statx to Samba's stat_ex */
+#define SAMBA_STATX_ATTR_MASK (CEPH_STATX_BASIC_STATS | CEPH_STATX_BTIME)
+
+static void smb_stat_from_ceph_statx(SMB_STRUCT_STAT *st,
+				     const struct ceph_statx *stx)
+{
+	ZERO_STRUCTP(st);
+
+	st->st_ex_dev = stx->stx_dev;
+	st->st_ex_rdev = stx->stx_rdev;
+	st->st_ex_ino = stx->stx_ino;
+	st->st_ex_mode = stx->stx_mode;
+	st->st_ex_uid = stx->stx_uid;
+	st->st_ex_gid = stx->stx_gid;
+	st->st_ex_size = stx->stx_size;
+	st->st_ex_nlink = stx->stx_nlink;
+	st->st_ex_atime = stx->stx_atime;
+	st->st_ex_btime = stx->stx_btime;
+	st->st_ex_ctime = stx->stx_ctime;
+	st->st_ex_mtime = stx->stx_mtime;
+	st->st_ex_blksize = stx->stx_blksize;
+	st->st_ex_blocks = stx->stx_blocks;
+}
+
+/* Ceph's inode + ino-number */
+struct vfs_ceph_iref {
+	struct Inode *inode;
+	uint64_t ino; /* for debug printing */
+	bool owner;   /* indicate when actual owner of Inode ref */
+};
+
+/* Ceph DIR pointer wrapper */
+struct vfs_ceph_dirp {
+	struct ceph_dir_result *cdr;
+};
+
+/* Ceph file-handles via fsp-extension */
+struct vfs_ceph_fh {
+	struct vfs_ceph_dirp dirp; /* keep first for up-casting */
+	struct cephmount_cached *cme;
+	struct UserPerm *uperm;
+	struct files_struct *fsp;
+	struct vfs_ceph_iref iref;
+	struct Fh *fh;
+	int fd;
+};
+
+static int cephmount_next_fd(struct cephmount_cached *cme)
+{
+	/*
+	 * Those file-descriptor numbers are reported back to VFS layer
+	 * (debug-hints only). Using numbers within a large range of
+	 * [1000, 1001000], thus the chances of (annoying but harmless)
+	 * collision are low.
+	 */
+	uint64_t next;
+
+	next = (cme->fd_index++ % 1000000) + 1000;
+	return (int)next;
+}
+
+static int vfs_ceph_release_fh(struct vfs_ceph_fh *cfh)
+{
+	int ret = 0;
+
+	if (cfh->fh != NULL) {
+		DBG_DEBUG("[ceph] ceph_ll_close: fd=%d\n", cfh->fd);
+		ret = ceph_ll_close(cfh->cme->mount, cfh->fh);
+		cfh->fh = NULL;
+	}
+	if (cfh->iref.inode != NULL) {
+		DBG_DEBUG("[ceph] ceph_ll_put: ino=%" PRIu64 "\n",
+			  cfh->iref.ino);
+		ceph_ll_put(cfh->cme->mount, cfh->iref.inode);
+		cfh->iref.inode = NULL;
+	}
+	if (cfh->uperm != NULL) {
+		vfs_ceph_userperm_del(cfh->uperm);
+		cfh->uperm = NULL;
+	}
+	cfh->fd = -1;
+
+	return ret;
+}
+
+static void vfs_ceph_fsp_ext_destroy_cb(void *p_data)
+{
+	vfs_ceph_release_fh((struct vfs_ceph_fh *)p_data);
+}
+
+static int vfs_ceph_add_fh(struct vfs_handle_struct *handle,
+			   files_struct *fsp,
+			   struct vfs_ceph_fh **out_cfh)
+{
+	struct cephmount_cached *cme = handle->data;
+	struct UserPerm *uperm = NULL;
+
+	uperm = vfs_ceph_userperm_new(handle);
+	if (uperm == NULL) {
+		return -ENOMEM;
+	}
+
+	*out_cfh = VFS_ADD_FSP_EXTENSION(handle,
+					 fsp,
+					 struct vfs_ceph_fh,
+					 vfs_ceph_fsp_ext_destroy_cb);
+	if (*out_cfh == NULL) {
+		vfs_ceph_userperm_del(uperm);
+		return -ENOMEM;
+	}
+	(*out_cfh)->cme = cme;
+	(*out_cfh)->uperm = uperm;
+	(*out_cfh)->fsp = fsp;
+	(*out_cfh)->fd = -1;
+	return 0;
+}
+
+static void vfs_ceph_remove_fh(struct vfs_handle_struct *handle,
+			       struct files_struct *fsp)
+{
+	VFS_REMOVE_FSP_EXTENSION(handle, fsp);
+}
+
+static int vfs_ceph_fetch_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) ? -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)
+{


-- 
Samba Shared Repository



More information about the samba-cvs mailing list