The branch, v4-21-test has been updated
       via  40d2b73f24b vfs_ceph_new: Do not resolve by inode number
       via  d9151f66cc3 vfs_ceph_new: Handle absolute path in vfs_ceph_ll_walk
       via  6b997c180f5 vfs_ceph_new: Remove unused code in cephmount_mount_fs()
       via  08f2d5abca6 vfs_ceph_new: Remove redundant re-intialization to NULL
       via  101c2999830 vfs_ceph_new: use libcephfs nonblocking API for 
async-io ops
       via  f04ad3933b5 vfs_ceph_new: Remove unused symbol for ceph_readdir
       via  2900b44971e source3/wscript: Introduce auto mode to build ceph vfs 
modules
       via  d7ac6062d61 s3:utils: Remove call of ads_startup() from 
net_ads_keytab_create()
       via  92253a4708b s3:libads: Make sure that REALM is always added to 
keytab principals
       via  c0e3cabdb70 lib:krb5_wrap: Add smb_krb5_parse_name_flags()
      from  b7843d0f422 vfs_shadow_copy2: Use VFS interface to derive mount 
point

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


- Log -----------------------------------------------------------------
commit 40d2b73f24b2a780d3bf278f177206a0a107fdb1
Author: Anoop C S <[email protected]>
Date:   Tue Feb 25 17:40:13 2025 +0530

    vfs_ceph_new: Do not resolve by inode number
    
    CephFS snapshots within snap directory shares the same inode number from
    its parent. Until unless we resolve by name we may incorrectly point at
    an inode which is not a snapshot directory. Therefore to be functionally
    correct we avoid resolving by inode number but proper name.
    
    For example:
    
    path (ino = 3)
      |
      --- dir (ino = 4)
      |
      --- .snap (ino = 3)
            |
            --- snap1 (ino = 3)
                  |
                  --- dir (ino = 4)
    
    In this case an attempt to resolve 'snap1' by inode number 3 results in
    pointing at 'path' which is not the desired outcome.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=15818
    
    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): Fri Mar  7 18:20:47 UTC 2025 on atb-devel-224
    
    (cherry picked from commit a96f0542c8317a7dd0470b32350de6893fd98723)
    
    Autobuild-User(v4-21-test): Jule Anger <[email protected]>
    Autobuild-Date(v4-21-test): Thu Mar 13 16:58:39 UTC 2025 on atb-devel-224

commit d9151f66cc39be0653618ac299c2a9b2e587ef28
Author: Anoop C S <[email protected]>
Date:   Mon Feb 24 14:00:56 2025 +0530

    vfs_ceph_new: Handle absolute path in vfs_ceph_ll_walk
    
    It can very well be the case that the incoming path is absolute in
    nature which breaks the assumption inside vfs_ceph_ll_walk that it
    is within the current working directory. Instead perform a check to
    see whether the path includes current working directory path in its
    components and accordingly trim it to make it relative in nature.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=15818
    
    Signed-off-by: Anoop C S <[email protected]>
    Reviewed-by: Guenther Deschner <[email protected]>
    (cherry picked from commit 9341d7fb466c95ea5aa0643049ce2a1f4183b9d0)

commit 6b997c180f52740014724f2351683f409e74cfff
Author: Anoop C S <[email protected]>
Date:   Mon Feb 24 12:09:06 2025 +0530

    vfs_ceph_new: Remove unused code in cephmount_mount_fs()
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=15818
    
    Signed-off-by: Anoop C S <[email protected]>
    Reviewed-by: Guenther Deschner <[email protected]>
    (cherry picked from commit ee1c3e1db9a2d12ba6d9dd24faccf0020b1daf0d)

commit 08f2d5abca6b44c5cae1e476a591495ce76a3179
Author: Anoop C S <[email protected]>
Date:   Mon Feb 24 11:54:45 2025 +0530

    vfs_ceph_new: Remove redundant re-intialization to NULL
    
    TALLOC_FREE() by default re-initializes the pointer to NULL after
    corresponding memory is freed.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=15818
    
    Signed-off-by: Anoop C S <[email protected]>
    Reviewed-by: Guenther Deschner <[email protected]>
    (cherry picked from commit c5ddd94a08503a52914ce351ebf1083178e8c8bc)

commit 101c2999830fd83662fa98bb4a7646121cd18040
Author: Shachar Sharon <[email protected]>
Date:   Tue Oct 1 12:09:40 2024 +0300

    vfs_ceph_new: use libcephfs nonblocking API for async-io ops
    
    Use libcephfs non-blocking API (ceph_ll_nonblocking_readv_writev[1]) in
    combination with smb VFS async hooks ({pread,pwrite,fsync}_send/_recv).
    Fills libcephfs' struct ceph_ll_io_info with single iovec and
    submit/complete the operation asynchronously on libcephfs side, with
    corresponding tevent schedule-immediate upon completion on smbd side.
    
    Control nonblocking/normal I/O mode via config parameter. The common
    parts of async I/O (with/without HAVE_CEPH_ASYNCIO) are united.
    Specifically, use same struct vfs_ceph_aio_state and common code via
    helper function for all async I/O hooks. When HAVE_CEPH_ASYNCIO
    is True _and_ config option 'asyncio = yes' use libcephfs asynchronous
    I/O API. Otherwise, fake async operation using normal blocking APIs.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=15810
    
    [1] 
https://github.com/ceph/ceph/commit/b4e39f3eccd6734f1ed13c700c136e3aef1777f8
    
    Signed-off-by: Shachar Sharon <[email protected]>
    Reviewed-by: Ralph Boehme <[email protected]>
    Reviewed-by: Volker Lendecke <[email protected]>
    Reviewed-by: Guenther Deschner <[email protected]>
    
    Autobuild-User(master): Günther Deschner <[email protected]>
    Autobuild-Date(master): Tue Mar  4 16:53:21 UTC 2025 on atb-devel-224
    
    (cherry picked from commit 4ae9224138449fe7b8dd1e8ce8141aedd014efc4)

commit f04ad3933b5b1504ee24125f842593de6e27a698
Author: Anoop C S <[email protected]>
Date:   Mon Oct 28 11:13:10 2024 +0530

    vfs_ceph_new: Remove unused symbol for ceph_readdir
    
    ce459ddbcd0f32252858a7640f6871057eb14645 recently switched the readdir
    implementation to use ceph_readdir_r(). Thus ceph_readdir() is
    unnecessarily loaded which is no longer used.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=15810
    
    Signed-off-by: Anoop C S <[email protected]>
    Reviewed-by: John Mulligan <[email protected]>
    
    Autobuild-User(master): Anoop C S <[email protected]>
    Autobuild-Date(master): Sun Nov  3 11:07:23 UTC 2024 on atb-devel-224
    
    (cherry picked from commit e3d35ca69446606b557f20e5faec2e76354eaaa4)

commit 2900b44971eae1d3c5bd7b50c661202598f7e339
Author: Anoop C S <[email protected]>
Date:   Mon Aug 5 18:51:49 2024 +0530

    source3/wscript: Introduce auto mode to build ceph vfs modules
    
    Use 'auto' mode as the default for building ceph vfs modules so that an
    explicit --enable-cephfs can reliably fail in the absence of required
    dependencies.
    
    ref: https://lists.samba.org/archive/samba/2024-August/249569.html
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=15810
    
    Signed-off-by: Anoop C S <[email protected]>
    Reviewed-by: Guenther Deschner <[email protected]>
    
    Autobuild-User(master): Anoop C S <[email protected]>
    Autobuild-Date(master): Tue Aug 27 06:18:51 UTC 2024 on atb-devel-224
    
    (cherry picked from commit 232ab02faf9615c55c362c60e06381ea02421794)

commit d7ac6062d61b7d620860dd7e97691edf1c2acd36
Author: Pavel Filipenský <[email protected]>
Date:   Thu Mar 6 15:24:05 2025 +0100

    s3:utils: Remove call of ads_startup() from net_ads_keytab_create()
    
    Calling ads_startup() is not needed in net_ads_keytab_create.  Keytab
    creation code in sync_pw2keytabs() decides if it needs to talk to DC or
    not and connects to AD accordingly.
    
    Fixing this, makes the bug below easier to reproduce using
    'net ads keytab create'.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=15727
    
    Signed-off-by: Pavel Filipenský <[email protected]>
    Reviewed-by: Andreas Schneider <[email protected]>
    
    Autobuild-User(master): Pavel Filipensky <[email protected]>
    Autobuild-Date(master): Mon Mar 10 11:09:29 UTC 2025 on atb-devel-224
    
    (cherry picked from commit 5cadaf91bc96cd2a8e0f6bcbd8a212e86b714180)

commit 92253a4708b0b0b529df9aa1c97242babce2165c
Author: Pavel Filipenský <[email protected]>
Date:   Fri Mar 7 10:32:40 2025 +0100

    s3:libads: Make sure that REALM is always added to keytab principals
    
    The code responsible for adding SPNs to keytab should always set the
    REALM part.  Current code is not adding it for e.g. SPNs synced from AD.
    
    If REALM is missing, krb5_parse_name() will succeed (and add the REALM)
    only if the krb5.conf contains libdefaults section with
    default_realm set and will fail otherwise. E.g.:
    
    [libdefaults]
        default_realm = SOMETESTDOMAIN1.MY.COM
    
    When calling 'net ads join' we get the following error if SPN is missing
    REALM and krb5.conf does not provide the default_realm:
    
    pw2kt_process_add_info: Failed to parse principal:
    RestrictedKrbHost/$MACHINE_NAME
    Failed to join domain: failed to create kerberos keytab
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=15727
    
    Pair-Programmed-With: Noel Power <[email protected]>
    
    Signed-off-by: Pavel Filipenský <[email protected]>
    Reviewed-by: Stefan Metzmacher <[email protected]>
    Reviewed-by: Alexander Bokovoy <[email protected]>
    
    Autobuild-User(master): Pavel Filipensky <[email protected]>
    Autobuild-Date(master): Sun Mar  9 00:25:08 UTC 2025 on atb-devel-224
    
    (cherry picked from commit c72554260c950d0ef7652955a59f0f68a026f4f2)

commit c0e3cabdb70fe8950813dc083b159cbe72571996
Author: Pavel Filipenský <[email protected]>
Date:   Thu Mar 6 23:20:53 2025 +0100

    lib:krb5_wrap: Add smb_krb5_parse_name_flags()
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=15727
    
    Signed-off-by: Pavel Filipenský <[email protected]>
    Reviewed-by: Stefan Metzmacher <[email protected]>
    Reviewed-by: Alexander Bokovoy <[email protected]>
    (cherry picked from commit cf34645050df64d6b8c4fa45394c3feebe691e79)

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

Summary of changes:
 lib/krb5_wrap/krb5_samba.c       |  39 ++-
 lib/krb5_wrap/krb5_samba.h       |   5 +
 source3/libads/kerberos_keytab.c |  19 +-
 source3/modules/vfs_ceph_new.c   | 579 ++++++++++++++++++++++++++-------------
 source3/utils/net_ads.c          |  11 -
 source3/wscript                  |  24 +-
 6 files changed, 466 insertions(+), 211 deletions(-)


Changeset truncated at 500 lines:

diff --git a/lib/krb5_wrap/krb5_samba.c b/lib/krb5_wrap/krb5_samba.c
index 451616c79e5..0a4a7ea986f 100644
--- a/lib/krb5_wrap/krb5_samba.c
+++ b/lib/krb5_wrap/krb5_samba.c
@@ -836,6 +836,29 @@ krb5_error_code smb_krb5_get_allowed_etypes(krb5_context 
context,
 krb5_error_code smb_krb5_parse_name(krb5_context context,
                                    const char *name,
                                    krb5_principal *principal)
+{
+       return smb_krb5_parse_name_flags(context, name, 0, principal);
+}
+
+/**
+ * @brief Convert a string principal name to a Kerberos principal.
+ *
+ * @param[in]  context  The library context
+ *
+ * @param[in]  name     The principal as a unix charset string.
+ *
+ * @param[in]  flags    Flags for krb5_parse_name_flags()
+ *
+ * @param[out] principal The newly allocated principal.
+ *
+ * Use krb5_free_principal() to free a principal when it is no longer needed.
+ *
+ * @return 0 on success, a Kerberos error code otherwise.
+ */
+krb5_error_code smb_krb5_parse_name_flags(krb5_context context,
+                                         const char *name,
+                                         int flags,
+                                         krb5_principal *principal)
 {
        krb5_error_code ret;
        char *utf8_name;
@@ -843,17 +866,19 @@ krb5_error_code smb_krb5_parse_name(krb5_context context,
        TALLOC_CTX *frame = talloc_stackframe();
 
        if (!push_utf8_talloc(frame, &utf8_name, name, &converted_size)) {
-               talloc_free(frame);
+               TALLOC_FREE(frame);
                return ENOMEM;
        }
+       TALLOC_FREE(frame);
 
-       ret = krb5_parse_name(context, utf8_name, principal);
-       if (ret == KRB5_PARSE_MALFORMED) {
-               ret = krb5_parse_name_flags(context, utf8_name,
-                                           KRB5_PRINCIPAL_PARSE_ENTERPRISE,
-                                           principal);
+       ret = krb5_parse_name_flags(context, utf8_name, flags, principal);
+       if (ret != KRB5_PARSE_MALFORMED) {
+               return ret;
        }
-       TALLOC_FREE(frame);
+
+       flags |= KRB5_PRINCIPAL_PARSE_ENTERPRISE;
+       ret = krb5_parse_name_flags(context, utf8_name, flags, principal);
+
        return ret;
 }
 
diff --git a/lib/krb5_wrap/krb5_samba.h b/lib/krb5_wrap/krb5_samba.h
index 0acf567371c..9da8a2b4806 100644
--- a/lib/krb5_wrap/krb5_samba.h
+++ b/lib/krb5_wrap/krb5_samba.h
@@ -186,6 +186,11 @@ krb5_error_code smb_krb5_parse_name(krb5_context context,
                                const char *name, /* in unix charset */
                                 krb5_principal *principal);
 
+krb5_error_code smb_krb5_parse_name_flags(krb5_context context,
+                                         const char *name, /* unix charset */
+                                         int flags,
+                                         krb5_principal *principal);
+
 krb5_error_code smb_krb5_unparse_name(TALLOC_CTX *mem_ctx,
                                      krb5_context context,
                                      krb5_const_principal principal,
diff --git a/source3/libads/kerberos_keytab.c b/source3/libads/kerberos_keytab.c
index 5913db299ad..49a892e5a55 100644
--- a/source3/libads/kerberos_keytab.c
+++ b/source3/libads/kerberos_keytab.c
@@ -364,12 +364,29 @@ static krb5_error_code pw2kt_process_add_info(struct 
pw2kt_keytab_state *state2,
        krb5_principal princ = NULL;
        krb5_principal *a = NULL;
        size_t len;
+       const char *realm = NULL;
 
-       ret = smb_krb5_parse_name(state2->context, princs, &princ);
+       ret = smb_krb5_parse_name_flags(state2->context,
+                                       princs,
+                                       KRB5_PRINCIPAL_PARSE_NO_DEF_REALM,
+                                       &princ);
        if (ret != 0) {
                DBG_ERR("Failed to parse principal: %s\n", princs);
                return ret;
        }
+       /* Add realm part if missing (e.g. SPNs synced from DC) */
+       realm = smb_krb5_principal_get_realm(state2, state2->context, princ);
+       if (realm == NULL || *realm == 0) {
+               ret = smb_krb5_principal_set_realm(state2->context,
+                                                  princ,
+                                                  lp_realm());
+               if (ret != 0) {
+                       DBG_ERR("Failed to add realm to principal: %s\n",
+                               princs);
+                       return ret;
+               }
+       }
+
        len = talloc_array_length(state2->princ_array);
        a = talloc_realloc(state2,
                           state2->princ_array,
diff --git a/source3/modules/vfs_ceph_new.c b/source3/modules/vfs_ceph_new.c
index 1cb04f1f9ee..8b051e0f226 100644
--- a/source3/modules/vfs_ceph_new.c
+++ b/source3/modules/vfs_ceph_new.c
@@ -102,6 +102,9 @@ static const struct enum_list enum_vfs_cephfs_proxy_vals[] 
= {
 #define CEPH_FN(_name) typeof(_name) *_name ## _fn
 
 struct vfs_ceph_config {
+#if HAVE_CEPH_ASYNCIO
+       struct tevent_threaded_context *tctx;
+#endif
        const char *conf_file;
        const char *user_id;
        const char *fsname;
@@ -110,7 +113,6 @@ struct vfs_ceph_config {
        enum vfs_cephfs_proxy_mode proxy;
        void *libhandle;
 
-       CEPH_FN(ceph_ll_lookup_inode);
        CEPH_FN(ceph_ll_walk);
        CEPH_FN(ceph_ll_getattr);
        CEPH_FN(ceph_ll_setattr);
@@ -155,9 +157,11 @@ struct vfs_ceph_config {
        CEPH_FN(ceph_userperm_destroy);
        CEPH_FN(ceph_userperm_new);
        CEPH_FN(ceph_version);
-       CEPH_FN(ceph_readdir);
        CEPH_FN(ceph_rewinddir);
        CEPH_FN(ceph_readdir_r);
+#if HAVE_CEPH_ASYNCIO
+       CEPH_FN(ceph_ll_nonblocking_readv_writev);
+#endif
 };
 
 /*
@@ -275,7 +279,6 @@ static struct ceph_mount_info *cephmount_mount_fs(
        struct vfs_ceph_config *config)
 {
        int ret;
-       char buf[256];
        struct ceph_mount_info *mnt = NULL;
        /* if config_file and/or user_id are NULL, ceph will use defaults */
 
@@ -295,12 +298,6 @@ static struct ceph_mount_info *cephmount_mount_fs(
                goto out;
        }
 
-       DBG_DEBUG("[CEPH] calling ceph_conf_get: option='%s'\n", "log_file");
-       ret = config->ceph_conf_get_fn(mnt, "log_file", buf, sizeof(buf));
-       if (ret < 0) {
-               goto out;
-       }
-
        /* libcephfs disables POSIX ACL support by default, enable it... */
        ret = cephmount_update_conf(config,
                                    mnt,
@@ -397,7 +394,6 @@ static bool vfs_cephfs_load_lib(struct vfs_ceph_config 
*config)
                break;
        }
 
-       CHECK_CEPH_FN(libhandle, ceph_ll_lookup_inode);
        CHECK_CEPH_FN(libhandle, ceph_ll_walk);
        CHECK_CEPH_FN(libhandle, ceph_ll_getattr);
        CHECK_CEPH_FN(libhandle, ceph_ll_setattr);
@@ -442,9 +438,11 @@ static bool vfs_cephfs_load_lib(struct vfs_ceph_config 
*config)
        CHECK_CEPH_FN(libhandle, ceph_userperm_destroy);
        CHECK_CEPH_FN(libhandle, ceph_userperm_new);
        CHECK_CEPH_FN(libhandle, ceph_version);
-       CHECK_CEPH_FN(libhandle, ceph_readdir);
        CHECK_CEPH_FN(libhandle, ceph_rewinddir);
        CHECK_CEPH_FN(libhandle, ceph_readdir_r);
+#if HAVE_CEPH_ASYNCIO
+       CHECK_CEPH_FN(libhandle, ceph_ll_nonblocking_readv_writev);
+#endif
 
        config->libhandle = libhandle;
 
@@ -700,10 +698,7 @@ static struct dirent *vfs_ceph_get_fh_dirent(struct 
vfs_ceph_fh *cfh)
 
 static void vfs_ceph_put_fh_dirent(struct vfs_ceph_fh *cfh)
 {
-       if (cfh->de != NULL) {
-               TALLOC_FREE(cfh->de);
-               cfh->de = NULL;
-       }
+       TALLOC_FREE(cfh->de);
 }
 
 static int vfs_ceph_release_fh(struct vfs_ceph_fh *cfh)
@@ -800,21 +795,6 @@ static void vfs_ceph_assign_fh_fd(struct vfs_ceph_fh *cfh)
 
 /* Ceph low-level wrappers */
 
-static int vfs_ceph_ll_lookup_inode(const struct vfs_handle_struct *handle,
-                                   uint64_t inoval,
-                                   Inode **pout)
-{
-       struct inodeno_t ino = {.val = inoval};
-       struct vfs_ceph_config *config = NULL;
-
-       SMB_VFS_HANDLE_GET_DATA(handle, config, struct vfs_ceph_config,
-                               return -ENOMEM);
-
-       DBG_DEBUG("[CEPH] ceph_ll_lookup_inode: ino=%" PRIu64 "\n", inoval);
-
-       return config->ceph_ll_lookup_inode_fn(config->mount, ino, pout);
-}
-
 static int vfs_ceph_ll_walk(const struct vfs_handle_struct *handle,
                            const char *name,
                            struct Inode **pin,
@@ -825,10 +805,31 @@ static int vfs_ceph_ll_walk(const struct 
vfs_handle_struct *handle,
        struct UserPerm *uperm = NULL;
        int ret = -1;
        struct vfs_ceph_config *config = NULL;
+       const char *cwd = NULL;
+       size_t cwdlen;
 
        SMB_VFS_HANDLE_GET_DATA(handle, config, struct vfs_ceph_config,
                                return -ENOMEM);
 
+       cwd = config->ceph_getcwd_fn(config->mount);
+       cwdlen = strlen(cwd);
+
+       /*
+        * ceph_ll_walk() always operate on "name" relative to current working
+        * directory even if it starts with a '/' i.e, absolute path is never
+        * honoured. But why?? For now stick to the current behaviour and ensure
+        * that the "name" is always relative when it contains current working
+        * directory path with an exception to "/".
+        */
+       if ((strcmp(cwd, "/") != 0) &&
+           (strncmp(name, cwd, cwdlen) == 0)) {
+               if (name[cwdlen] == '/') {
+                       name += cwdlen + 1;
+               } else if (name[cwdlen] == '\0') {
+                       name = ".";
+               }
+       }
+
        DBG_DEBUG("[CEPH] ceph_ll_walk: name=%s\n", name);
 
        uperm = vfs_ceph_userperm_new(config, handle->conn);
@@ -1797,76 +1798,56 @@ static int vfs_ceph_ll_fremovexattr(const struct 
vfs_handle_struct *handle,
                                              cfh->uperm);
 }
 
+#if HAVE_CEPH_ASYNCIO
+static int64_t vfs_ceph_ll_nonblocking_readv_writev(
+       const struct vfs_handle_struct *handle,
+       const struct vfs_ceph_fh *cfh,
+       struct ceph_ll_io_info *io_info)
+{
+       struct vfs_ceph_config *config = NULL;
+
+       SMB_VFS_HANDLE_GET_DATA(handle,
+                               config,
+                               struct vfs_ceph_config,
+                               return -EINVAL);
+
+       DBG_DEBUG("[CEPH] ceph_ll_nonblocking_readv_writev: ino=%" PRIu64
+                 " fd=%d off=%jd\n",
+                 cfh->iref.ino,
+                 cfh->fd,
+                 io_info->off);
+
+       return config->ceph_ll_nonblocking_readv_writev_fn(config->mount,
+                                                          io_info);
+}
+#endif
+
 /* Ceph Inode-refernce get/put wrappers */
 static int vfs_ceph_iget(const struct vfs_handle_struct *handle,
-                        uint64_t ino,
                         const char *name,
                         unsigned int flags,
                         struct vfs_ceph_iref *iref)
 {
        struct Inode *inode = NULL;
        int ret = -1;
+       struct ceph_statx stx = {.stx_ino = 0};
 
-       if (ino > CEPH_INO_ROOT) {
-               /* get-by-ino */
-               ret = vfs_ceph_ll_lookup_inode(handle, ino, &inode);
-               if (ret != 0) {
-                       return ret;
-               }
-       } else {
-               /* get-by-path */
-               struct ceph_statx stx = {.stx_ino = 0};
-
-               ret = vfs_ceph_ll_walk(handle,
-                                      name,
-                                      &inode,
-                                      &stx,
-                                      CEPH_STATX_INO,
-                                      flags);
-               if (ret != 0) {
-                       return ret;
-               }
-               ino = stx.stx_ino;
+       ret = vfs_ceph_ll_walk(handle,
+                              name,
+                              &inode,
+                              &stx,
+                              CEPH_STATX_INO,
+                              flags);
+       if (ret != 0) {
+               return ret;
        }
        iref->inode = inode;
-       iref->ino = ino;
+       iref->ino = stx.stx_ino;
        iref->owner = true;
        DBG_DEBUG("[CEPH] iget: %s ino=%" PRIu64 "\n", name, iref->ino);
        return 0;
 }
 
-static int vfs_ceph_iget_by_fname(const struct vfs_handle_struct *handle,
-                                 const struct smb_filename *smb_fname,
-                                 struct vfs_ceph_iref *iref)
-{
-       const char *name = smb_fname->base_name;
-       const char *cwd = NULL;
-       int ret = -1;
-       struct vfs_ceph_config *config = NULL;
-
-       SMB_VFS_HANDLE_GET_DATA(handle, config, struct vfs_ceph_config,
-                               return -ENOMEM);
-
-       cwd = config->ceph_getcwd_fn(config->mount);
-       if (!strcmp(name, cwd)) {
-               ret = vfs_ceph_iget(handle, 0, "./", 0, iref);
-       } else {
-               ret = vfs_ceph_iget(handle, 0, name, 0, iref);
-       }
-       return ret;
-}
-
-static int vfs_ceph_igetl(const struct vfs_handle_struct *handle,
-                         const struct smb_filename *smb_fname,
-                         struct vfs_ceph_iref *iref)
-{
-       return vfs_ceph_iget(handle,
-                            0,
-                            smb_fname->base_name,
-                            AT_SYMLINK_NOFOLLOW,
-                            iref);
-}
-
 static int vfs_ceph_igetd(struct vfs_handle_struct *handle,
                          const struct files_struct *dirfsp,
                          struct vfs_ceph_iref *iref)
@@ -1885,25 +1866,16 @@ static int vfs_ceph_igetd(struct vfs_handle_struct 
*handle,
 
        /* case-2: resolve by current work-dir */
        if (fsp_get_pathref_fd(dirfsp) == AT_FDCWD) {
-               return vfs_ceph_iget(handle, 0, ".", 0, iref);
+               return vfs_ceph_iget(handle, ".", 0, iref);
        }
 
        /* case-3: resolve by parent dir and name */
        return vfs_ceph_iget(handle,
-                            dirfsp->file_id.inode,
                             dirfsp->fsp_name->base_name,
                             AT_SYMLINK_NOFOLLOW,
                             iref);
 }
 
-static int vfs_ceph_igetf(struct vfs_handle_struct *handle,
-                         const struct files_struct *fsp,
-                         struct vfs_ceph_iref *iref)
-{
-       return vfs_ceph_iget(
-               handle, fsp->file_id.inode, fsp->fsp_name->base_name, 0, iref);
-}
-
 static void vfs_ceph_iput(const struct vfs_handle_struct *handle,
                          struct vfs_ceph_iref *iref)
 {
@@ -1968,7 +1940,7 @@ static int vfs_ceph_statvfs(struct vfs_handle_struct 
*handle,
        struct vfs_ceph_iref iref = {0};
        int ret;
 
-       ret = vfs_ceph_iget_by_fname(handle, smb_fname, &iref);
+       ret = vfs_ceph_iget(handle, smb_fname->base_name, 0, &iref);
        if (ret != 0) {
                goto out;
        }
@@ -2273,17 +2245,28 @@ out:
 }
 
 struct vfs_ceph_aio_state {
+       struct vfs_ceph_config *config;
+       struct vfs_ceph_fh *cfh;
+#if HAVE_CEPH_ASYNCIO
+       struct tevent_req *req;
+       bool orphaned;
+       struct tevent_immediate *im;
+       void *data;
+       size_t len;
+       off_t off;
+       bool write;
+       bool fsync;
+
+       struct ceph_ll_io_info io_info;
+       struct iovec iov;
+#endif
        struct timespec start_time;
        struct timespec finish_time;
+       ssize_t result;
        struct vfs_aio_state vfs_aio_state;
        SMBPROFILE_BYTES_ASYNC_STATE(profile_bytes);
 };
 
-struct vfs_ceph_pread_state {
-       ssize_t bytes_read;
-       struct vfs_ceph_aio_state ceph_aio_state;
-};
-
 static void vfs_ceph_aio_start(struct vfs_ceph_aio_state *state)
 {
        SMBPROFILE_BYTES_ASYNC_SET_BUSY(state->profile_bytes);
@@ -2299,22 +2282,218 @@ static void vfs_ceph_aio_finish(struct 
vfs_ceph_aio_state *state,
        if (result < 0) {
                state->vfs_aio_state.error = (int)result;
        }
+
+       state->result = result;
        SMBPROFILE_BYTES_ASYNC_SET_IDLE(state->profile_bytes);
 }
 
-/*
- * Fake up an async ceph read by calling the synchronous API.
- */
+#if HAVE_CEPH_ASYNCIO
+
+static void vfs_ceph_aio_done(struct tevent_context *ev,
+                             struct tevent_immediate *im,
+                             void *private_data);
+
+static int vfs_ceph_require_tctx(struct vfs_ceph_aio_state *state,
+                                struct tevent_context *ev)
+{
+       struct vfs_ceph_config *config = state->config;
+
+       if (config->tctx != NULL) {
+               return 0;
+       }
+
+       config->tctx = tevent_threaded_context_create(config, ev);
+       if (config->tctx == NULL) {
+               return -ENOMEM;
+       }
+
+       return 0;
+}
+
+static void vfs_ceph_aio_complete(struct ceph_ll_io_info *io_info)
+{
+       struct vfs_ceph_aio_state *state = io_info->priv;
+
+       if (state->orphaned) {
+               return;
+       }
+
+       DBG_DEBUG("[CEPH] aio_complete: ino=%" PRIu64
+                 " fd=%d off=%jd len=%ju result=%jd\n",
+                 state->cfh->iref.ino,
+                 state->cfh->fd,
+                 state->off,
+                 state->len,
+                 state->io_info.result);
+
+       tevent_threaded_schedule_immediate(state->config->tctx,
+                                          state->im,
+                                          vfs_ceph_aio_done,
+                                          state->req);
+}
+
+static void vfs_ceph_aio_cleanup(struct tevent_req *req,
+                                enum tevent_req_state req_state)
+{
+       struct vfs_ceph_aio_state *state = tevent_req_data(
+               req, struct vfs_ceph_aio_state);
+
+       if (req_state == TEVENT_REQ_IN_PROGRESS) {


-- 
Samba Shared Repository

Reply via email to