The branch, v4-22-test has been updated
       via  bf440caab97 vfs_ceph_new: Do not resolve by inode number
       via  d26177dcaeb vfs_ceph_new: Handle absolute path in vfs_ceph_ll_walk
       via  8b38092890d vfs_ceph_new: Remove unused code in cephmount_mount_fs()
       via  4e9eb916024 vfs_ceph_new: Remove redundant re-intialization to NULL
       via  6ca80fb612b vfs_ceph_new: use libcephfs nonblocking API for 
async-io ops
       via  f8f85cf8533 s3:utils: Remove call of ads_startup() from 
net_ads_keytab_create()
       via  83c60df6e8d s3:libads: Make sure that REALM is always added to 
keytab principals
       via  3849e7abe6d lib:krb5_wrap: Add smb_krb5_parse_name_flags()
      from  0e864939620 VERSION: Bump version up to Samba 4.22.1...

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


- Log -----------------------------------------------------------------
commit bf440caab97778ae6ce312d4905585abe277884c
Author: Anoop C S <anoo...@samba.org>
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 <anoo...@samba.org>
    Reviewed-by: Guenther Deschner <g...@samba.org>
    
    Autobuild-User(master): Günther Deschner <g...@samba.org>
    Autobuild-Date(master): Fri Mar  7 18:20:47 UTC 2025 on atb-devel-224
    
    (cherry picked from commit a96f0542c8317a7dd0470b32350de6893fd98723)
    
    Autobuild-User(v4-22-test): Jule Anger <jan...@samba.org>
    Autobuild-Date(v4-22-test): Thu Mar 13 17:06:25 UTC 2025 on atb-devel-224

commit d26177dcaeb757e01a480ebd7a7a9dd7528ddbad
Author: Anoop C S <anoo...@samba.org>
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 <anoo...@samba.org>
    Reviewed-by: Guenther Deschner <g...@samba.org>
    (cherry picked from commit 9341d7fb466c95ea5aa0643049ce2a1f4183b9d0)

commit 8b38092890dc18183ed3190e6731f4a21d341d9e
Author: Anoop C S <anoo...@samba.org>
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 <anoo...@samba.org>
    Reviewed-by: Guenther Deschner <g...@samba.org>
    (cherry picked from commit ee1c3e1db9a2d12ba6d9dd24faccf0020b1daf0d)

commit 4e9eb916024a61fdebb3aedd10e972ac957cc8c1
Author: Anoop C S <anoo...@samba.org>
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 <anoo...@samba.org>
    Reviewed-by: Guenther Deschner <g...@samba.org>
    (cherry picked from commit c5ddd94a08503a52914ce351ebf1083178e8c8bc)

commit 6ca80fb612b461c21897ee5e868395da381276dc
Author: Shachar Sharon <ssha...@redhat.com>
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 <ssha...@redhat.com>
    Reviewed-by: Ralph Boehme <s...@samba.org>
    Reviewed-by: Volker Lendecke <v...@samba.org>
    Reviewed-by: Guenther Deschner <g...@samba.org>
    
    Autobuild-User(master): Günther Deschner <g...@samba.org>
    Autobuild-Date(master): Tue Mar  4 16:53:21 UTC 2025 on atb-devel-224
    
    (cherry picked from commit 4ae9224138449fe7b8dd1e8ce8141aedd014efc4)

commit f8f85cf8533824e0c3fae7e4cac363c692f249c5
Author: Pavel Filipenský <pfilipen...@samba.org>
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ý <pfilipen...@samba.org>
    Reviewed-by: Andreas Schneider <a...@samba.org>
    
    Autobuild-User(master): Pavel Filipensky <pfilipen...@samba.org>
    Autobuild-Date(master): Mon Mar 10 11:09:29 UTC 2025 on atb-devel-224
    
    (cherry picked from commit 5cadaf91bc96cd2a8e0f6bcbd8a212e86b714180)

commit 83c60df6e8dd604c4954e1b444b8d2332dbff62b
Author: Pavel Filipenský <pfilipen...@samba.org>
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 <noel.po...@suse.com>
    
    Signed-off-by: Pavel Filipenský <pfilipen...@samba.org>
    Reviewed-by: Stefan Metzmacher <me...@samba.org>
    Reviewed-by: Alexander Bokovoy <a...@samba.org>
    
    Autobuild-User(master): Pavel Filipensky <pfilipen...@samba.org>
    Autobuild-Date(master): Sun Mar  9 00:25:08 UTC 2025 on atb-devel-224
    
    (cherry picked from commit c72554260c950d0ef7652955a59f0f68a026f4f2)

commit 3849e7abe6d7b1724ae6ab285e25c22086525d3f
Author: Pavel Filipenský <pfilipen...@samba.org>
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ý <pfilipen...@samba.org>
    Reviewed-by: Stefan Metzmacher <me...@samba.org>
    Reviewed-by: Alexander Bokovoy <a...@samba.org>
    (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   | 577 ++++++++++++++++++++++++++-------------
 source3/utils/net_ads.c          |  11 -
 source3/wscript                  |   4 +
 6 files changed, 451 insertions(+), 204 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 173307f7c88..a562359e121 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 cae8317b1c8..05c2a72d57f 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);
@@ -157,6 +159,9 @@ struct vfs_ceph_config {
        CEPH_FN(ceph_version);
        CEPH_FN(ceph_rewinddir);
        CEPH_FN(ceph_readdir_r);
+#if HAVE_CEPH_ASYNCIO
+       CEPH_FN(ceph_ll_nonblocking_readv_writev);
+#endif
 };
 
 /*
@@ -274,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 */
 
@@ -294,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,
@@ -396,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);
@@ -443,6 +440,9 @@ static bool vfs_cephfs_load_lib(struct vfs_ceph_config 
*config)
        CHECK_CEPH_FN(libhandle, ceph_version);
        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;
 
@@ -698,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)
@@ -798,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,
@@ -823,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);
@@ -1795,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)
@@ -1883,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)
 {
@@ -1966,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;
        }
@@ -2272,17 +2246,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);
@@ -2298,22 +2283,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) {
+               /*
+                * The job thread is still running, we need to protect the
+                * memory used by the job completion function.
+                */
+               (void)talloc_reparent(req, NULL, state);
+               state->orphaned = true;


-- 
Samba Shared Repository

Reply via email to