From eb383c8da53ed433792af0fa5ce66e1668f61103 Mon Sep 17 00:00:00 2001 From: Christopher Hoffman Date: Fri, 16 May 2025 13:19:25 +0000 Subject: [PATCH] client, libcephfs: Add fcopyfile bindings Signed-off-by: Christopher Hoffman --- src/client/Client.cc | 4 ++++ src/client/Client.h | 2 ++ src/include/cephfs/libcephfs.h | 1 + src/libcephfs.cc | 7 +++++++ src/pybind/cephfs/c_cephfs.pxd | 1 + src/pybind/cephfs/cephfs.pyx | 23 +++++++++++++++++++++++ 6 files changed, 38 insertions(+) diff --git a/src/client/Client.cc b/src/client/Client.cc index 15dd8608c73..494ba2c0c20 100644 --- a/src/client/Client.cc +++ b/src/client/Client.cc @@ -18568,6 +18568,10 @@ int Client::get_inode_flags(int fd, int* file_attr_out) { return get_inode_flags(fh->inode.get(), file_attr_out); } +int Client::fcopyfile(const char *spath, const char *dpath, UserPerm& perms, mode_t mode) { + return 0; +} + StandaloneClient::StandaloneClient(Messenger *m, MonClient *mc, boost::asio::io_context& ictx) : Client(m, mc, new Objecter(m->cct, m, mc, ictx)) diff --git a/src/client/Client.h b/src/client/Client.h index 9523571ea8c..5d8b4d54f15 100644 --- a/src/client/Client.h +++ b/src/client/Client.h @@ -349,6 +349,8 @@ public: int get_inode_flags(const Inode* in, int* file_attr_out); int get_inode_flags(int fd, int* file_attr_out); + int fcopyfile(const char *sname, const char *dname, UserPerm& perms, mode_t mode); + int set_fscrypt_policy_v2(int fd, const struct fscrypt_policy_v2& policy); int is_encrypted(int fd, UserPerm& perms, char* enctag); diff --git a/src/include/cephfs/libcephfs.h b/src/include/cephfs/libcephfs.h index 598f5b1a4d3..1e21f864532 100644 --- a/src/include/cephfs/libcephfs.h +++ b/src/include/cephfs/libcephfs.h @@ -2390,6 +2390,7 @@ void ceph_free_snap_info_buffer(struct snap_info *snap_info); */ int ceph_get_perf_counters(struct ceph_mount_info *cmount, char **perf_dump); +int ceph_fcopyfile(struct ceph_mount_info *cmount, const char *spath, const char *dpath, mode_t mode); #ifdef __cplusplus } #endif diff --git a/src/libcephfs.cc b/src/libcephfs.cc index b8fa43abd83..9f508fb83fc 100644 --- a/src/libcephfs.cc +++ b/src/libcephfs.cc @@ -2629,3 +2629,10 @@ extern "C" int get_inode_flags(struct ceph_mount_info *cmount, int fd, int* file return cmount->get_client()->get_inode_flags(fd, file_attr_out); } + +extern "C" int ceph_fcopyfile(struct ceph_mount_info *cmount, const char *spath, const char *dpath, mode_t mode) +{ + if (!cmount->is_mounted()) + return -ENOTCONN; + return cmount->get_client()->fcopyfile(spath, dpath, cmount->default_perms, mode); +} diff --git a/src/pybind/cephfs/c_cephfs.pxd b/src/pybind/cephfs/c_cephfs.pxd index 30e9a246d33..de4cb860fa5 100644 --- a/src/pybind/cephfs/c_cephfs.pxd +++ b/src/pybind/cephfs/c_cephfs.pxd @@ -104,6 +104,7 @@ cdef extern from "cephfs/libcephfs.h" nogil: int ceph_listxattr(ceph_mount_info *cmount, const char *path, char *list, size_t size) int ceph_flistxattr(ceph_mount_info *cmount, int fd, char *list, size_t size) int ceph_llistxattr(ceph_mount_info *cmount, const char *path, char *list, size_t size) + int ceph_fcopyfile(ceph_mount_info *cmount, const char *spath, const char *dpath, mode_t mode) int ceph_write(ceph_mount_info *cmount, int fd, const char *buf, int64_t size, int64_t offset) int ceph_pwritev(ceph_mount_info *cmount, int fd, iovec *iov, int iovcnt, int64_t offset) int ceph_read(ceph_mount_info *cmount, int fd, char *buf, int64_t size, int64_t offset) diff --git a/src/pybind/cephfs/cephfs.pyx b/src/pybind/cephfs/cephfs.pyx index fb81732bea9..6f21c7d807e 100644 --- a/src/pybind/cephfs/cephfs.pyx +++ b/src/pybind/cephfs/cephfs.pyx @@ -1966,6 +1966,29 @@ cdef class LibCephFS(object): return self.listxattr(path, size=size, follow_symlink=False) + def fcopyfile(self, spath, dpath, mode=0): + """ + Copy a file to another file. + + :param spath: the path to the source file. + :param dpath: the path to the destination file. + :param mode: the permissions the file should have once created. + """ + self.require_state("mounted") + + spath = cstr(spath, 'spath') + dpath = cstr(dpath, 'dpath') + + cdef: + char *_spath = spath + char *_dpath = dpath + mode_t _mode = mode + + ret = ceph_fcopyfile(self.cluster, _spath, _dpath, _mode) + + if ret < 0: + raise make_ex(ret, "error in fcopyfile") + def stat(self, path, follow_symlink=True): """ Get a file's extended statistics and attributes. -- 2.39.5