From 2583b0e8829d584c5040edfb8ecc720e332c3995 Mon Sep 17 00:00:00 2001 From: Shachar Sharon Date: Thu, 20 Jun 2024 14:58:34 +0300 Subject: [PATCH] vfs_ceph_new: use low-level APIs for ftruncate/fallocate Implement ftruncate/fallocate operations using libcephfs' low-level APIs. Requires open ceph Fh* associated with fsp (extension). BUG: https://bugzilla.samba.org/show_bug.cgi?id=15686 Signed-off-by: Shachar Sharon Reviewed-by: Guenther Deschner Reviewed-by: Anoop C S (cherry picked from commit b536bf1fa87fb794e2992ab5368f41fdba80e3ad) --- source3/modules/vfs_ceph_new.c | 61 ++++++++++++++++++++++++++-------- 1 file changed, 47 insertions(+), 14 deletions(-) diff --git a/source3/modules/vfs_ceph_new.c b/source3/modules/vfs_ceph_new.c index 68e514599ab..1d4f6ff1ad4 100644 --- a/source3/modules/vfs_ceph_new.c +++ b/source3/modules/vfs_ceph_new.c @@ -922,6 +922,28 @@ static int vfs_ceph_ll_fsync(const struct vfs_handle_struct *handle, return ceph_ll_fsync(cmount_of(handle), cfh->fh, syncdataonly); } +static int vfs_ceph_ll_ftruncate(struct vfs_handle_struct *handle, + const struct vfs_ceph_fh *cfh, + int64_t size) +{ + struct ceph_statx stx = {.stx_size = (uint64_t)size}; + + return ceph_ll_setattr(cmount_of(handle), + cfh->iref.inode, + &stx, + CEPH_SETATTR_SIZE, + cfh->uperm); +} + +static int vfs_ceph_ll_fallocate(const struct vfs_handle_struct *handle, + const struct vfs_ceph_fh *cfh, + int mode, + int64_t off, + int64_t len) +{ + return ceph_ll_fallocate(cmount_of(handle), cfh->fh, mode, off, len); +} + /* Ceph Inode-refernce get/put wrappers */ static int vfs_ceph_iget(const struct vfs_handle_struct *handle, uint64_t ino, @@ -1940,6 +1962,7 @@ static int strict_allocate_ftruncate(struct vfs_handle_struct *handle, int result; NTSTATUS status; SMB_STRUCT_STAT *pst; + struct vfs_ceph_fh *cfh = NULL; status = vfs_stat_fsp(fsp); if (!NT_STATUS_IS_OK(status)) { @@ -1955,20 +1978,21 @@ static int strict_allocate_ftruncate(struct vfs_handle_struct *handle, if (pst->st_ex_size == len) return 0; + result = vfs_ceph_fetch_io_fh(handle, fsp, &cfh); + if (result != 0) { + return status_code(result); + } + /* Shrink - just ftruncate. */ if (pst->st_ex_size > len) { - result = ceph_ftruncate(cmount_of(handle), - fsp_get_io_fd(fsp), - len); + result = vfs_ceph_ll_ftruncate(handle, cfh, len); return status_code(result); } space_to_write = len - pst->st_ex_size; - result = ceph_fallocate(cmount_of(handle), - fsp_get_io_fd(fsp), - 0, - pst->st_ex_size, - space_to_write); + result = vfs_ceph_ll_fallocate( + handle, cfh, 0, pst->st_ex_size, space_to_write); + return status_code(result); } @@ -1976,6 +2000,7 @@ static int vfs_ceph_ftruncate(struct vfs_handle_struct *handle, files_struct *fsp, off_t len) { + struct vfs_ceph_fh *cfh = NULL; int result = -1; DBG_DEBUG("[CEPH] ftruncate(%p, %p, %llu\n", handle, fsp, llu(len)); @@ -1984,7 +2009,12 @@ static int vfs_ceph_ftruncate(struct vfs_handle_struct *handle, return strict_allocate_ftruncate(handle, fsp, len); } - result = ceph_ftruncate(cmount_of(handle), fsp_get_io_fd(fsp), len); + result = vfs_ceph_fetch_io_fh(handle, fsp, &cfh); + if (result != 0) { + goto out; + } + result = vfs_ceph_ll_ftruncate(handle, cfh, len); +out: return status_code(result); } @@ -1994,16 +2024,19 @@ static int vfs_ceph_fallocate(struct vfs_handle_struct *handle, off_t offset, off_t len) { + struct vfs_ceph_fh *cfh = NULL; int result; DBG_DEBUG("[CEPH] fallocate(%p, %p, %u, %llu, %llu\n", handle, fsp, mode, llu(offset), llu(len)); + result = vfs_ceph_fetch_io_fh(handle, fsp, &cfh); + if (result != 0) { + goto out; + } + /* unsupported mode flags are rejected by libcephfs */ - result = ceph_fallocate(cmount_of(handle), - fsp_get_io_fd(fsp), - mode, - offset, - len); + result = vfs_ceph_ll_fallocate(handle, cfh, mode, offset, len); +out: DBG_DEBUG("[CEPH] fallocate(...) = %d\n", result); return status_code(result); }