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