From: Rishabh Dave Date: Thu, 27 Nov 2025 14:10:27 +0000 (+0530) Subject: client: add client code to allow snap metadata mutations X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=bf5080c08cd86fe39976ebd5310506d7059dbfc6;p=ceph.git client: add client code to allow snap metadata mutations Fixes: https://tracker.ceph.com/issues/66293 Signed-off-by: Rishabh Dave --- diff --git a/ceph.spec.in b/ceph.spec.in index b0fba106c2ce..7bb56a985a83 100644 --- a/ceph.spec.in +++ b/ceph.spec.in @@ -2996,6 +2996,7 @@ fi %{_includedir}/cephfs/dump.h %{_includedir}/cephfs/json.h %{_includedir}/cephfs/keys_and_values.h +%{_includedir}/cephfs/snap_types.h %{_libdir}/libcephfs.so %{_libdir}/libcephfs_proxy.so %{_libdir}/pkgconfig/cephfs.pc diff --git a/src/client/Client.cc b/src/client/Client.cc index 3e0135a024fc..3a2041a87537 100644 --- a/src/client/Client.cc +++ b/src/client/Client.cc @@ -14245,6 +14245,56 @@ int Client::rmsnap(const char *relpath, const char *name, const UserPerm& perms, return _rmdir(snapdir.get(), name, perms, check_perms); } +int Client::do_snap_md_op(const char* path, const string& md_key, + const string& md_val, const unsigned int op_flag, + const UserPerm &perms) +{ + if (op_flag != CEPH_SNAP_MD_OP_CREATE && + op_flag != (CEPH_SNAP_MD_OP_CREATE | CEPH_SNAP_MD_OP_EXCL) && + op_flag != CEPH_SNAP_MD_OP_REMOVE) { + return -EINVAL; + } + + RWRef_t mref_reader(mount_state, CLIENT_MOUNTING); + if (!mref_reader.is_state_satisfied()) + return -ENOTCONN; + + std::scoped_lock l(client_lock); + + walk_dentry_result wdr; + if (int rc = path_walk(cwd, filepath(path), &wdr, perms, {}); rc < 0) { + return rc; + } + + if (wdr.target->snapid == CEPH_NOSNAP) { + return -EINVAL; + } + + MetaRequest *req = new MetaRequest(CEPH_MDS_OP_SNAP_METADATA); + req->set_filepath(wdr.getpath()); + req->set_inode(wdr.diri); + req->set_dentry(wdr.dn); + req->dentry_drop = CEPH_CAP_FILE_SHARED; + req->dentry_unless = CEPH_CAP_FILE_EXCL; + + bufferlist bl; + encode(md_key, bl); + encode(md_val, bl); + encode(op_flag, bl); + req->set_data(bl); + + ldout(cct, 10) << __func__ << ": making request" << dendl; + int res = make_request(req, perms, &wdr.target); + ldout(cct, 10) << __func__ << ": result is " << res << dendl; + + trim_cache(); + + ldout(cct, 8) << __func__ << "(" << wdr.getpath() << ", " << perms + << ") = " << res << dendl; + + return res; +} + // ============================= // expose caps diff --git a/src/client/Client.h b/src/client/Client.h index 42459f40a599..99c33fe534cf 100644 --- a/src/client/Client.h +++ b/src/client/Client.h @@ -633,6 +633,9 @@ public: int mksnap(const char *path, const char *name, const UserPerm& perm, mode_t mode=0, const std::map &metadata={}); int rmsnap(const char *path, const char *name, const UserPerm& perm, bool check_perms=false); + int do_snap_md_op(const char* path, const std::string& md_key, + const std::string& md_val, const unsigned int op_flag, + const UserPerm &perms); // cephx mds auth caps checking int mds_check_access(std::string& path, const UserPerm& perms, int mask); diff --git a/src/include/ceph_fs.h b/src/include/ceph_fs.h index 9c0b67004cc2..b3aca9075068 100644 --- a/src/include/ceph_fs.h +++ b/src/include/ceph_fs.h @@ -15,6 +15,7 @@ #include "msgr.h" #include "rados.h" #include "include/buffer.h" // for ceph::buffer::list +#include "include/cephfs/snap_types.h" /* * The data structures defined here are shared between Linux kernel and diff --git a/src/include/cephfs/snap_types.h b/src/include/cephfs/snap_types.h new file mode 100644 index 000000000000..755b3e6f5620 --- /dev/null +++ b/src/include/cephfs/snap_types.h @@ -0,0 +1,25 @@ +// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:nil -*- +// vim: ts=8 sw=2 sts=2 expandtab + +/* + * snap_types.h - Contains types associated with CephFS snapshots that needs + * to be imported in Cython (Python bindings). Placing these types in ceph_fs.h + * (where it was initially place) causes an Cython import error. + * + * LGPL-2.1 or LGPL-3.0 + */ + + +/* + * snapshot metadata operations + * + * XXX: DON'T FORGET to update cephfs.pyx if any changes are made to this enum. + */ +enum { + // allows both, snap MD create and update + CEPH_SNAP_MD_OP_CREATE = (1 << 0), + // when passed with CREATE, allows only snap MD create and rejects + // update + CEPH_SNAP_MD_OP_EXCL = (1 << 1), + CEPH_SNAP_MD_OP_REMOVE = (1 << 2), +};