mirror of
https://github.com/samba-team/samba.git
synced 2025-02-12 21:58:10 +03:00
vfs_ceph_new: use low-level APIs for xattr ops
Implement extended-attributes operations using libcephfs' low-level APIs. Whenever possible, use the open file-handle from fsp-extension to resolve inode-reference and user-permissions. Otherwise, resolve both on-the-fly. 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> (cherry picked from commit 0a8445e891c64d703d44258b2eef85296265c55f)
This commit is contained in:
parent
e0d2953a84
commit
ec119531a4
@ -999,6 +999,159 @@ static int vfs_ceph_ll_mknod(const struct vfs_handle_struct *handle,
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int vfs_ceph_ll_getxattr(const struct vfs_handle_struct *handle,
|
||||
const struct vfs_ceph_iref *iref,
|
||||
const char *name,
|
||||
void *value,
|
||||
size_t size)
|
||||
{
|
||||
struct UserPerm *uperm = NULL;
|
||||
int ret = -1;
|
||||
|
||||
uperm = vfs_ceph_userperm_new(handle);
|
||||
if (uperm == NULL) {
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
ret = ceph_ll_getxattr(cmount_of(handle),
|
||||
iref->inode,
|
||||
name,
|
||||
value,
|
||||
size,
|
||||
uperm);
|
||||
|
||||
vfs_ceph_userperm_del(uperm);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int vfs_ceph_ll_fgetxattr(const struct vfs_handle_struct *handle,
|
||||
const struct vfs_ceph_fh *cfh,
|
||||
const char *name,
|
||||
void *value,
|
||||
size_t size)
|
||||
{
|
||||
return ceph_ll_getxattr(cmount_of(handle),
|
||||
cfh->iref.inode,
|
||||
name,
|
||||
value,
|
||||
size,
|
||||
cfh->uperm);
|
||||
}
|
||||
|
||||
static int vfs_ceph_ll_setxattr(const struct vfs_handle_struct *handle,
|
||||
const struct vfs_ceph_iref *iref,
|
||||
const char *name,
|
||||
const void *value,
|
||||
size_t size,
|
||||
int flags)
|
||||
{
|
||||
struct UserPerm *uperm = NULL;
|
||||
int ret = -1;
|
||||
|
||||
uperm = vfs_ceph_userperm_new(handle);
|
||||
if (uperm == NULL) {
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
ret = ceph_ll_setxattr(cmount_of(handle),
|
||||
iref->inode,
|
||||
name,
|
||||
value,
|
||||
size,
|
||||
flags,
|
||||
uperm);
|
||||
|
||||
vfs_ceph_userperm_del(uperm);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int vfs_ceph_ll_fsetxattr(const struct vfs_handle_struct *handle,
|
||||
const struct vfs_ceph_fh *cfh,
|
||||
const char *name,
|
||||
const void *value,
|
||||
size_t size,
|
||||
int flags)
|
||||
{
|
||||
return ceph_ll_setxattr(cmount_of(handle),
|
||||
cfh->iref.inode,
|
||||
name,
|
||||
value,
|
||||
size,
|
||||
flags,
|
||||
cfh->uperm);
|
||||
}
|
||||
|
||||
static int vfs_ceph_ll_listxattr(const struct vfs_handle_struct *handle,
|
||||
const struct vfs_ceph_iref *iref,
|
||||
char *list,
|
||||
size_t buf_size,
|
||||
size_t *list_size)
|
||||
{
|
||||
struct UserPerm *uperm = NULL;
|
||||
int ret = -1;
|
||||
|
||||
uperm = vfs_ceph_userperm_new(handle);
|
||||
if (uperm == NULL) {
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
ret = ceph_ll_listxattr(cmount_of(handle),
|
||||
iref->inode,
|
||||
list,
|
||||
buf_size,
|
||||
list_size,
|
||||
uperm);
|
||||
|
||||
vfs_ceph_userperm_del(uperm);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int vfs_ceph_ll_flistxattr(const struct vfs_handle_struct *handle,
|
||||
const struct vfs_ceph_fh *cfh,
|
||||
char *list,
|
||||
size_t buf_size,
|
||||
size_t *list_size)
|
||||
{
|
||||
return ceph_ll_listxattr(cmount_of(handle),
|
||||
cfh->iref.inode,
|
||||
list,
|
||||
buf_size,
|
||||
list_size,
|
||||
cfh->uperm);
|
||||
}
|
||||
|
||||
static int vfs_ceph_ll_removexattr(const struct vfs_handle_struct *handle,
|
||||
const struct vfs_ceph_iref *iref,
|
||||
const char *name)
|
||||
{
|
||||
struct UserPerm *uperm = NULL;
|
||||
int ret = -1;
|
||||
|
||||
uperm = vfs_ceph_userperm_new(handle);
|
||||
if (uperm == NULL) {
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
ret = ceph_ll_removexattr(cmount_of(handle), iref->inode, name, uperm);
|
||||
|
||||
vfs_ceph_userperm_del(uperm);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int vfs_ceph_ll_fremovexattr(const struct vfs_handle_struct *handle,
|
||||
const struct vfs_ceph_fh *cfh,
|
||||
const char *name)
|
||||
{
|
||||
return ceph_ll_removexattr(cmount_of(handle),
|
||||
cfh->iref.inode,
|
||||
name,
|
||||
cfh->uperm);
|
||||
}
|
||||
|
||||
/* Ceph Inode-refernce get/put wrappers */
|
||||
static int vfs_ceph_iget(const struct vfs_handle_struct *handle,
|
||||
uint64_t ino,
|
||||
@ -1093,6 +1246,14 @@ static int vfs_ceph_igetd(struct vfs_handle_struct *handle,
|
||||
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)
|
||||
{
|
||||
@ -2410,25 +2571,35 @@ static ssize_t vfs_ceph_fgetxattr(struct vfs_handle_struct *handle,
|
||||
size_t size)
|
||||
{
|
||||
int ret;
|
||||
|
||||
DBG_DEBUG("[CEPH] fgetxattr(%p, %p, %s, %p, %llu)\n",
|
||||
handle,
|
||||
fsp,
|
||||
name,
|
||||
value,
|
||||
llu(size));
|
||||
|
||||
if (!fsp->fsp_flags.is_pathref) {
|
||||
ret = ceph_fgetxattr(cmount_of(handle),
|
||||
fsp_get_io_fd(fsp),
|
||||
name,
|
||||
value,
|
||||
size);
|
||||
struct vfs_ceph_fh *cfh = NULL;
|
||||
|
||||
ret = vfs_ceph_fetch_io_fh(handle, fsp, &cfh);
|
||||
if (ret != 0) {
|
||||
goto out;
|
||||
}
|
||||
|
||||
ret = vfs_ceph_ll_fgetxattr(handle, cfh, name, value, size);
|
||||
} else {
|
||||
ret = ceph_getxattr(cmount_of(handle),
|
||||
fsp->fsp_name->base_name,
|
||||
name,
|
||||
value,
|
||||
size);
|
||||
struct vfs_ceph_iref iref = {0};
|
||||
|
||||
ret = vfs_ceph_igetf(handle, fsp, &iref);
|
||||
if (ret != 0) {
|
||||
goto out;
|
||||
}
|
||||
|
||||
ret = vfs_ceph_ll_getxattr(handle, &iref, name, value, size);
|
||||
vfs_ceph_iput(handle, &iref);
|
||||
}
|
||||
out:
|
||||
DBG_DEBUG("[CEPH] fgetxattr(...) = %d\n", ret);
|
||||
return lstatus_code(ret);
|
||||
}
|
||||
@ -2438,26 +2609,47 @@ static ssize_t vfs_ceph_flistxattr(struct vfs_handle_struct *handle,
|
||||
char *list,
|
||||
size_t size)
|
||||
{
|
||||
size_t list_size = 0;
|
||||
int ret;
|
||||
|
||||
DBG_DEBUG("[CEPH] flistxattr(%p, %p, %p, %llu)\n",
|
||||
handle, fsp, list, llu(size));
|
||||
|
||||
if (!fsp->fsp_flags.is_pathref) {
|
||||
/*
|
||||
* We can use an io_fd to list xattrs.
|
||||
*/
|
||||
ret = ceph_flistxattr(cmount_of(handle),
|
||||
fsp_get_io_fd(fsp),
|
||||
list,
|
||||
size);
|
||||
struct vfs_ceph_fh *cfh = NULL;
|
||||
|
||||
ret = vfs_ceph_fetch_io_fh(handle, fsp, &cfh);
|
||||
if (ret != 0) {
|
||||
goto out;
|
||||
}
|
||||
|
||||
ret = vfs_ceph_ll_flistxattr(handle,
|
||||
cfh,
|
||||
list,
|
||||
size,
|
||||
&list_size);
|
||||
if (ret != 0) {
|
||||
goto out;
|
||||
}
|
||||
} else {
|
||||
/*
|
||||
* This is no longer a handle based call.
|
||||
*/
|
||||
ret = ceph_listxattr(cmount_of(handle),
|
||||
fsp->fsp_name->base_name,
|
||||
list,
|
||||
size);
|
||||
struct vfs_ceph_iref iref = {0};
|
||||
|
||||
ret = vfs_ceph_igetf(handle, fsp, &iref);
|
||||
if (ret != 0) {
|
||||
goto out;
|
||||
}
|
||||
ret = vfs_ceph_ll_listxattr(handle,
|
||||
&iref,
|
||||
list,
|
||||
size,
|
||||
&list_size);
|
||||
if (ret != 0) {
|
||||
goto out;
|
||||
}
|
||||
vfs_ceph_iput(handle, &iref);
|
||||
}
|
||||
ret = (int)list_size;
|
||||
out:
|
||||
DBG_DEBUG("[CEPH] flistxattr(...) = %d\n", ret);
|
||||
return lstatus_code(ret);
|
||||
}
|
||||
@ -2467,22 +2659,29 @@ static int vfs_ceph_fremovexattr(struct vfs_handle_struct *handle,
|
||||
const char *name)
|
||||
{
|
||||
int ret;
|
||||
|
||||
DBG_DEBUG("[CEPH] fremovexattr(%p, %p, %s)\n", handle, fsp, name);
|
||||
if (!fsp->fsp_flags.is_pathref) {
|
||||
/*
|
||||
* We can use an io_fd to remove xattrs.
|
||||
*/
|
||||
ret = ceph_fremovexattr(cmount_of(handle),
|
||||
fsp_get_io_fd(fsp),
|
||||
name);
|
||||
struct vfs_ceph_fh *cfh = NULL;
|
||||
|
||||
ret = vfs_ceph_fetch_io_fh(handle, fsp, &cfh);
|
||||
if (ret != 0) {
|
||||
goto out;
|
||||
}
|
||||
|
||||
ret = vfs_ceph_ll_fremovexattr(handle, cfh, name);
|
||||
} else {
|
||||
/*
|
||||
* This is no longer a handle based call.
|
||||
*/
|
||||
ret = ceph_removexattr(cmount_of(handle),
|
||||
fsp->fsp_name->base_name,
|
||||
name);
|
||||
struct vfs_ceph_iref iref = {0};
|
||||
|
||||
ret = vfs_ceph_igetf(handle, fsp, &iref);
|
||||
if (ret != 0) {
|
||||
goto out;
|
||||
}
|
||||
|
||||
ret = vfs_ceph_ll_removexattr(handle, &iref, name);
|
||||
vfs_ceph_iput(handle, &iref);
|
||||
}
|
||||
out:
|
||||
DBG_DEBUG("[CEPH] fremovexattr(...) = %d\n", ret);
|
||||
return status_code(ret);
|
||||
}
|
||||
@ -2495,6 +2694,7 @@ static int vfs_ceph_fsetxattr(struct vfs_handle_struct *handle,
|
||||
int flags)
|
||||
{
|
||||
int ret;
|
||||
|
||||
DBG_DEBUG("[CEPH] fsetxattr(%p, %p, %s, %p, %llu, %d)\n",
|
||||
handle,
|
||||
fsp,
|
||||
@ -2502,27 +2702,36 @@ static int vfs_ceph_fsetxattr(struct vfs_handle_struct *handle,
|
||||
value,
|
||||
llu(size),
|
||||
flags);
|
||||
|
||||
if (!fsp->fsp_flags.is_pathref) {
|
||||
/*
|
||||
* We can use an io_fd to set xattrs.
|
||||
*/
|
||||
ret = ceph_fsetxattr(cmount_of(handle),
|
||||
fsp_get_io_fd(fsp),
|
||||
name,
|
||||
value,
|
||||
size,
|
||||
flags);
|
||||
struct vfs_ceph_fh *cfh = NULL;
|
||||
|
||||
ret = vfs_ceph_fetch_io_fh(handle, fsp, &cfh);
|
||||
if (ret != 0) {
|
||||
goto out;
|
||||
}
|
||||
ret = vfs_ceph_ll_fsetxattr(handle,
|
||||
cfh,
|
||||
name,
|
||||
value,
|
||||
size,
|
||||
flags);
|
||||
} else {
|
||||
/*
|
||||
* This is no longer a handle based call.
|
||||
*/
|
||||
ret = ceph_setxattr(cmount_of(handle),
|
||||
fsp->fsp_name->base_name,
|
||||
name,
|
||||
value,
|
||||
size,
|
||||
flags);
|
||||
struct vfs_ceph_iref iref = {0};
|
||||
|
||||
ret = vfs_ceph_igetf(handle, fsp, &iref);
|
||||
if (ret != 0) {
|
||||
goto out;
|
||||
}
|
||||
ret = vfs_ceph_ll_setxattr(handle,
|
||||
&iref,
|
||||
name,
|
||||
value,
|
||||
size,
|
||||
flags);
|
||||
vfs_ceph_iput(handle, &iref);
|
||||
}
|
||||
out:
|
||||
DBG_DEBUG("[CEPH] fsetxattr(...) = %d\n", ret);
|
||||
return status_code(ret);
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user