1
0
mirror of https://github.com/samba-team/samba.git synced 2025-03-01 04:58:35 +03:00

vfs_ceph_new: switch to ceph_readdir_r

Prefer a safe version of ceph_readdir, where the directory entry struct
is allocated by the caller. Use a dynamic-allocated 'struct dirent'
which is associated with a directory vfs_ceph_fh (optional), which is
allocated on-the-fly upon start of READDIR and released at the end or
CLOSEDIR (or unlikely readdir error).

BUG: https://bugzilla.samba.org/show_bug.cgi?id=15703

Signed-off-by: Shachar Sharon <ssharon@redhat.com>
Reviewed-by: John Mulligan <jmulligan@redhat.com>
Reviewed-by: Anoop C S <anoopcs@samba.org>

Autobuild-User(master): Anoop C S <anoopcs@samba.org>
Autobuild-Date(master): Fri Oct 25 10:29:44 UTC 2024 on atb-devel-224
This commit is contained in:
Shachar Sharon 2024-09-03 16:54:03 +03:00 committed by Anoop C S
parent 0e08e63ae8
commit ce459ddbcd

View File

@ -157,6 +157,7 @@ struct vfs_ceph_config {
CEPH_FN(ceph_version);
CEPH_FN(ceph_readdir);
CEPH_FN(ceph_rewinddir);
CEPH_FN(ceph_readdir_r);
};
/*
@ -405,6 +406,7 @@ static bool vfs_cephfs_load_lib(struct vfs_ceph_config *config)
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);
config->libhandle = libhandle;
@ -625,6 +627,7 @@ struct vfs_ceph_fh {
struct vfs_ceph_config *config;
struct vfs_ceph_iref iref;
struct Fh *fh;
struct dirent *de;
int fd;
};
@ -642,6 +645,22 @@ static int cephmount_next_fd(struct cephmount_cached *cme)
return (int)next;
}
static struct dirent *vfs_ceph_get_fh_dirent(struct vfs_ceph_fh *cfh)
{
if (cfh->de == NULL) {
cfh->de = talloc_zero_size(cfh->fsp, sizeof(*(cfh->de)));
}
return cfh->de;
}
static void vfs_ceph_put_fh_dirent(struct vfs_ceph_fh *cfh)
{
if (cfh->de != NULL) {
TALLOC_FREE(cfh->de);
cfh->de = NULL;
}
}
static int vfs_ceph_release_fh(struct vfs_ceph_fh *cfh)
{
int ret = 0;
@ -661,6 +680,7 @@ static int vfs_ceph_release_fh(struct vfs_ceph_fh *cfh)
vfs_ceph_userperm_del(cfh->config, cfh->uperm);
cfh->uperm = NULL;
}
vfs_ceph_put_fh_dirent(cfh);
cfh->fd = -1;
return ret;
@ -1167,18 +1187,20 @@ static int vfs_ceph_ll_opendir(const struct vfs_handle_struct *handle,
cfh->uperm);
}
static struct dirent *vfs_ceph_ll_readdir(const struct vfs_handle_struct *hndl,
const struct vfs_ceph_fh *dircfh)
static int vfs_ceph_ll_readdir(const struct vfs_handle_struct *hndl,
const struct vfs_ceph_fh *dircfh)
{
struct vfs_ceph_config *config = NULL;
SMB_VFS_HANDLE_GET_DATA(hndl, config, struct vfs_ceph_config,
return NULL);
return -ENOMEM);
DBG_DEBUG("[ceph] ceph_readdir: ino=%" PRIu64 " fd=%d\n",
dircfh->iref.ino, dircfh->fd);
return config->ceph_readdir_fn(config->mount, dircfh->dirp.cdr);
return config->ceph_readdir_r_fn(config->mount,
dircfh->dirp.cdr,
dircfh->de);
}
static void vfs_ceph_ll_rewinddir(const struct vfs_handle_struct *handle,
@ -1960,21 +1982,35 @@ static struct dirent *vfs_ceph_readdir(struct vfs_handle_struct *handle,
struct files_struct *dirfsp,
DIR *dirp)
{
const struct vfs_ceph_fh *dircfh = (const struct vfs_ceph_fh *)dirp;
struct vfs_ceph_fh *dircfh = (struct vfs_ceph_fh *)dirp;
struct dirent *result = NULL;
int saved_errno = errno;
int ret = -1;
DBG_DEBUG("[CEPH] readdir(%p, %p)\n", handle, dirp);
errno = 0;
result = vfs_ceph_ll_readdir(handle, dircfh);
if ((result == NULL) && (errno != 0)) {
saved_errno = errno;
DBG_DEBUG("[CEPH] readdir(...) = %d\n", errno);
} else {
DBG_DEBUG("[CEPH] readdir(...) = %p\n", result);
result = vfs_ceph_get_fh_dirent(dircfh);
if (result == NULL) {
/* Memory allocation failure */
return NULL;
}
/* The low-level call uses 'dircfh->de' which is now 'result' */
ret = vfs_ceph_ll_readdir(handle, dircfh);
if (ret < 0) {
/* Error case */
DBG_DEBUG("[CEPH] readdir(...) = %d\n", ret);
vfs_ceph_put_fh_dirent(dircfh);
result = NULL;
saved_errno = ret;
} else if (ret == 0) {
/* End of directory stream */
vfs_ceph_put_fh_dirent(dircfh);
result = NULL;
} else {
/* Normal case */
DBG_DEBUG("[CEPH] readdir(...) = %p\n", result);
}
errno = saved_errno;
return result;
}