From 377b38bb33d76a7973fed05cda8f3146403209bf Mon Sep 17 00:00:00 2001 From: Xavi Hernandez Date: Wed, 5 Nov 2025 10:36:27 +0100 Subject: [PATCH] libcephfs_proxy: create internal ceph_dir_result structure Signed-off-by: Xavi Hernandez --- src/libcephfs_proxy/libcephfs_proxy.c | 46 ++++++++++++++++++++++++--- 1 file changed, 41 insertions(+), 5 deletions(-) diff --git a/src/libcephfs_proxy/libcephfs_proxy.c b/src/libcephfs_proxy/libcephfs_proxy.c index ae435527391..186e15f0252 100644 --- a/src/libcephfs_proxy/libcephfs_proxy.c +++ b/src/libcephfs_proxy/libcephfs_proxy.c @@ -8,6 +8,8 @@ #include "proxy_requests.h" #include "proxy_async.h" +#define PROXY_READDIR_BUFFER 65536 + /* We override the definition of UserPerm structure to contain internal user * credentials. This is already a black box for libcephfs users, so this won't * be noticed. */ @@ -29,6 +31,18 @@ struct ceph_mount_info { uint64_t cmount; }; +/* We override the definition of the ceph_dir_result structure to support + * batched reads. This is already a black box for libcephfs users, so this + * won't be noticed.*/ +struct ceph_dir_result { + struct dirent *current; + uint64_t dirp; + uint32_t size; + uint32_t count; + bool eod; + struct dirent entries[]; +}; + /* The global_cmount is used to stablish an initial connection to serve requests * not related to a real cmount, like ceph_version or ceph_userperm_new. */ static struct ceph_mount_info global_cmount = { @@ -599,8 +613,21 @@ __public int ceph_ll_opendir(struct ceph_mount_info *cmount, struct Inode *in, const UserPerm *perms) { CEPH_REQ(ceph_ll_opendir, req, 1, ans, 0); + struct ceph_dir_result *dirp; + uint32_t size; int32_t err; + size = sizeof(struct ceph_dir_result) + PROXY_READDIR_BUFFER; + dirp = proxy_malloc(size); + if (dirp == NULL) { + return -ENOMEM; + } + + dirp->current = NULL; + dirp->size = PROXY_READDIR_BUFFER; + dirp->count = 0; + dirp->eod = false; + PROTO_VERSION(&cmount->neg, req, PROXY_PROTOCOL_V1); req.inode = ptr_value(in); @@ -609,7 +636,10 @@ __public int ceph_ll_opendir(struct ceph_mount_info *cmount, struct Inode *in, err = CEPH_PROCESS(cmount, LIBCEPHFSD_OP_LL_OPENDIR, req, ans); if (err >= 0) { - *dirpp = value_ptr(ans.dir); + dirp->dirp = ans.dir; + *dirpp = dirp; + } else { + proxy_free(dirp); } return err; @@ -659,10 +689,16 @@ __public int ceph_ll_releasedir(struct ceph_mount_info *cmount, struct ceph_dir_result *dir) { CEPH_REQ(ceph_ll_releasedir, req, 0, ans, 0); + int32_t err; - req.dir = ptr_value(dir); + req.dir = dir->dirp; - return CEPH_PROCESS(cmount, LIBCEPHFSD_OP_LL_RELEASEDIR, req, ans); + err = CEPH_PROCESS(cmount, LIBCEPHFSD_OP_LL_RELEASEDIR, req, ans); + if (err >= 0) { + proxy_free(dir); + } + + return err; } __public int ceph_ll_removexattr(struct ceph_mount_info *cmount, @@ -705,7 +741,7 @@ __public void ceph_rewinddir(struct ceph_mount_info *cmount, { CEPH_REQ(ceph_rewinddir, req, 0, ans, 0); - req.dir = ptr_value(dirp); + req.dir = dirp->dirp; CEPH_PROCESS(cmount, LIBCEPHFSD_OP_REWINDDIR, req, ans); } @@ -880,7 +916,7 @@ __public int ceph_readdir_r(struct ceph_mount_info *cmount, CEPH_REQ(ceph_readdir, req, 0, ans, 1); - req.dir = ptr_value(dirp); + req.dir = dirp->dirp; CEPH_BUFF_ADD(ans, de, sizeof(struct dirent)); -- 2.47.3