mirror of
https://github.com/samba-team/samba.git
synced 2025-08-04 08:22:08 +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:
committed by
Günther Deschner
parent
362a7cf866
commit
53c9269b21
@ -848,6 +848,47 @@ static int vfs_ceph_ll_unlinkat(const struct vfs_handle_struct *handle,
|
|||||||
dircfh->uperm);
|
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 */
|
/* Ceph Inode-refernce get/put wrappers */
|
||||||
static int vfs_ceph_iget(const struct vfs_handle_struct *handle,
|
static int vfs_ceph_iget(const struct vfs_handle_struct *handle,
|
||||||
uint64_t ino,
|
uint64_t ino,
|
||||||
@ -1979,43 +2020,32 @@ static int vfs_ceph_symlinkat(struct vfs_handle_struct *handle,
|
|||||||
struct files_struct *dirfsp,
|
struct files_struct *dirfsp,
|
||||||
const struct smb_filename *new_smb_fname)
|
const struct smb_filename *new_smb_fname)
|
||||||
{
|
{
|
||||||
|
struct vfs_ceph_iref iref = {0};
|
||||||
|
struct vfs_ceph_fh *dircfh = NULL;
|
||||||
int result = -1;
|
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,
|
handle,
|
||||||
link_target->base_name,
|
link_target->base_name,
|
||||||
dirfd,
|
|
||||||
new_smb_fname->base_name);
|
new_smb_fname->base_name);
|
||||||
|
|
||||||
result = ceph_symlinkat(cmount_of(handle),
|
result = vfs_ceph_fetch_fh(handle, dirfsp, &dircfh);
|
||||||
link_target->base_name,
|
if (result != 0) {
|
||||||
dirfd,
|
goto out;
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
DBG_DEBUG("[CEPH] symlink(%p, %s, %s)\n", handle,
|
result = vfs_ceph_ll_symlinkat(handle,
|
||||||
link_target->base_name,
|
dircfh,
|
||||||
full_fname->base_name);
|
new_smb_fname->base_name,
|
||||||
|
link_target->base_name,
|
||||||
result = ceph_symlink(cmount_of(handle),
|
&iref);
|
||||||
link_target->base_name,
|
if (result != 0) {
|
||||||
full_fname->base_name);
|
goto out;
|
||||||
TALLOC_FREE(full_fname);
|
}
|
||||||
DBG_DEBUG("[CEPH] symlink(...) = %d\n", result);
|
vfs_ceph_iput(handle, &iref);
|
||||||
|
out:
|
||||||
|
DBG_DEBUG("[CEPH] symlinkat(...) = %d\n", result);
|
||||||
return status_code(result);
|
return status_code(result);
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int vfs_ceph_readlinkat(struct vfs_handle_struct *handle,
|
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)
|
size_t bufsiz)
|
||||||
{
|
{
|
||||||
int result = -1;
|
int result = -1;
|
||||||
#ifdef HAVE_CEPH_READLINKAT
|
struct vfs_ceph_iref iref = {0};
|
||||||
int dirfd = fsp_get_pathref_fd(dirfsp);
|
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,
|
handle,
|
||||||
dirfd,
|
|
||||||
smb_fname->base_name,
|
smb_fname->base_name,
|
||||||
buf,
|
buf,
|
||||||
llu(bufsiz));
|
llu(bufsiz));
|
||||||
|
|
||||||
result = ceph_readlinkat(cmount_of(handle),
|
result = vfs_ceph_fetch_fh(handle, dirfsp, &dircfh);
|
||||||
dirfd,
|
if (result != 0) {
|
||||||
smb_fname->base_name,
|
goto out;
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
DBG_DEBUG("[CEPH] readlink(%p, %s, %p, %llu)\n", handle,
|
result = vfs_ceph_ll_lookupat(handle,
|
||||||
full_fname->base_name, buf, llu(bufsiz));
|
dircfh,
|
||||||
|
smb_fname->base_name,
|
||||||
|
&iref);
|
||||||
|
if (result != 0) {
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
result = ceph_readlink(cmount_of(handle),
|
result = vfs_ceph_ll_readlinkat(handle, dircfh, &iref, buf, bufsiz);
|
||||||
full_fname->base_name,
|
vfs_ceph_iput(handle, &iref);
|
||||||
buf,
|
out:
|
||||||
bufsiz);
|
DBG_DEBUG("[CEPH] readlinkat(...) = %d\n", result);
|
||||||
TALLOC_FREE(full_fname);
|
|
||||||
DBG_DEBUG("[CEPH] readlink(...) = %d\n", result);
|
|
||||||
return status_code(result);
|
return status_code(result);
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int vfs_ceph_linkat(struct vfs_handle_struct *handle,
|
static int vfs_ceph_linkat(struct vfs_handle_struct *handle,
|
||||||
|
Reference in New Issue
Block a user