1
0
mirror of https://github.com/samba-team/samba.git synced 2025-08-02 00:22:11 +03:00

vfs_ceph_new: use low-level APIs for symlink/readlink

Implement unlinkat using libcephfs low-level APIs. For readlink
operation need to resolve child inode by-lookup and then used the inode
reference for the actual low-level readlink.

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

Signed-off-by: Shachar Sharon <ssharon@redhat.com>
Reviewed-by: Guenther Deschner <gd@samba.org>
Reviewed-by: Anoop C S <anoopcs@samba.org>
This commit is contained in:
Shachar Sharon
2024-06-26 13:46:54 +03:00
committed by Günther Deschner
parent 362a7cf866
commit 53c9269b21

View File

@ -848,6 +848,47 @@ static int vfs_ceph_ll_unlinkat(const struct vfs_handle_struct *handle,
dircfh->uperm);
}
static int vfs_ceph_ll_symlinkat(const struct vfs_handle_struct *handle,
const struct vfs_ceph_fh *dircfh,
const char *name,
const char *value,
struct vfs_ceph_iref *out_iref)
{
struct ceph_statx stx = {.stx_ino = 0};
struct Inode *inode = NULL;
int ret = -1;
ret = ceph_ll_symlink(cmount_of(handle),
dircfh->iref.inode,
name,
value,
&inode,
&stx,
CEPH_STATX_INO,
0,
dircfh->uperm);
if (ret != 0) {
return ret;
}
out_iref->inode = inode;
out_iref->ino = stx.stx_ino;
out_iref->owner = true;
return 0;
}
static int vfs_ceph_ll_readlinkat(const struct vfs_handle_struct *handle,
const struct vfs_ceph_fh *dircfh,
const struct vfs_ceph_iref *iref,
char *buf,
size_t bsz)
{
return ceph_ll_readlink(cmount_of(handle),
iref->inode,
buf,
bsz,
dircfh->uperm);
}
/* Ceph Inode-refernce get/put wrappers */
static int vfs_ceph_iget(const struct vfs_handle_struct *handle,
uint64_t ino,
@ -1979,43 +2020,32 @@ static int vfs_ceph_symlinkat(struct vfs_handle_struct *handle,
struct files_struct *dirfsp,
const struct smb_filename *new_smb_fname)
{
struct vfs_ceph_iref iref = {0};
struct vfs_ceph_fh *dircfh = NULL;
int result = -1;
#ifdef HAVE_CEPH_SYMLINKAT
int dirfd = fsp_get_pathref_fd(dirfsp);
DBG_DEBUG("[CEPH] symlinkat(%p, %s, %d, %s)\n",
DBG_DEBUG("[CEPH] symlinkat(%p, %s, %s)\n",
handle,
link_target->base_name,
dirfd,
new_smb_fname->base_name);
result = ceph_symlinkat(cmount_of(handle),
link_target->base_name,
dirfd,
new_smb_fname->base_name);
DBG_DEBUG("[CEPH] symlinkat(...) = %d\n", result);
return status_code(result);
#else
struct smb_filename *full_fname = NULL;
full_fname = full_path_from_dirfsp_atname(talloc_tos(),
dirfsp,
new_smb_fname);
if (full_fname == NULL) {
return -1;
result = vfs_ceph_fetch_fh(handle, dirfsp, &dircfh);
if (result != 0) {
goto out;
}
DBG_DEBUG("[CEPH] symlink(%p, %s, %s)\n", handle,
link_target->base_name,
full_fname->base_name);
result = ceph_symlink(cmount_of(handle),
link_target->base_name,
full_fname->base_name);
TALLOC_FREE(full_fname);
DBG_DEBUG("[CEPH] symlink(...) = %d\n", result);
result = vfs_ceph_ll_symlinkat(handle,
dircfh,
new_smb_fname->base_name,
link_target->base_name,
&iref);
if (result != 0) {
goto out;
}
vfs_ceph_iput(handle, &iref);
out:
DBG_DEBUG("[CEPH] symlinkat(...) = %d\n", result);
return status_code(result);
#endif
}
static int vfs_ceph_readlinkat(struct vfs_handle_struct *handle,
@ -2025,45 +2055,33 @@ static int vfs_ceph_readlinkat(struct vfs_handle_struct *handle,
size_t bufsiz)
{
int result = -1;
#ifdef HAVE_CEPH_READLINKAT
int dirfd = fsp_get_pathref_fd(dirfsp);
struct vfs_ceph_iref iref = {0};
struct vfs_ceph_fh *dircfh = NULL;
DBG_DEBUG("[CEPH] readlinkat(%p, %d, %s, %p, %llu)\n",
DBG_DEBUG("[CEPH] readlinkat(%p, %s, %p, %llu)\n",
handle,
dirfd,
smb_fname->base_name,
buf,
llu(bufsiz));
result = ceph_readlinkat(cmount_of(handle),
dirfd,
smb_fname->base_name,
buf,
bufsiz);
DBG_DEBUG("[CEPH] readlinkat(...) = %d\n", result);
return status_code(result);
#else
struct smb_filename *full_fname = NULL;
full_fname = full_path_from_dirfsp_atname(talloc_tos(),
dirfsp,
smb_fname);
if (full_fname == NULL) {
return -1;
result = vfs_ceph_fetch_fh(handle, dirfsp, &dircfh);
if (result != 0) {
goto out;
}
DBG_DEBUG("[CEPH] readlink(%p, %s, %p, %llu)\n", handle,
full_fname->base_name, buf, llu(bufsiz));
result = vfs_ceph_ll_lookupat(handle,
dircfh,
smb_fname->base_name,
&iref);
if (result != 0) {
goto out;
}
result = ceph_readlink(cmount_of(handle),
full_fname->base_name,
buf,
bufsiz);
TALLOC_FREE(full_fname);
DBG_DEBUG("[CEPH] readlink(...) = %d\n", result);
result = vfs_ceph_ll_readlinkat(handle, dircfh, &iref, buf, bufsiz);
vfs_ceph_iput(handle, &iref);
out:
DBG_DEBUG("[CEPH] readlinkat(...) = %d\n", result);
return status_code(result);
#endif
}
static int vfs_ceph_linkat(struct vfs_handle_struct *handle,