From 9bbfdadd1f590fdea2fa055906f9184c7f81d676 Mon Sep 17 00:00:00 2001 From: Patrick Donnelly Date: Wed, 23 Oct 2024 14:49:49 -0400 Subject: [PATCH] mds: check client features for charmap Signed-off-by: Patrick Donnelly Fixes: https://tracker.ceph.com/issues/66373 --- src/mds/Server.cc | 40 ++++++++++++++++++++++++++++++++++++++++ src/mds/Server.h | 2 ++ 2 files changed, 42 insertions(+) diff --git a/src/mds/Server.cc b/src/mds/Server.cc index a410b999102..bc6ecabe5cc 100644 --- a/src/mds/Server.cc +++ b/src/mds/Server.cc @@ -4730,6 +4730,23 @@ bool Server::is_valid_layout(file_layout_t *layout) return true; } +bool Server::can_handle_charmap(const MDRequestRef& mdr, CDentry* dn) +{ + CDir *dir = dn->get_dir(); + CInode *diri = dir->get_inode(); + if (auto* csp = diri->get_charmap()) { + dout(20) << __func__ << ": with " << *csp << dendl; + auto& client_metadata = mdr->session->info.client_metadata; + bool allowed = client_metadata.features.test(CEPHFS_FEATURE_CHARMAP); + if (!allowed) { + dout(5) << " client cannot handle charmap" << dendl; + respond_to_request(mdr, -EPERM); + return false; + } + } + return true; +} + void Server::handle_client_openc(const MDRequestRef& mdr) { const cref_t &req = mdr->client_request; @@ -4759,6 +4776,10 @@ void Server::handle_client_openc(const MDRequestRef& mdr) ceph_assert(dnl->is_null()); + if (!can_handle_charmap(mdr, dn)) { + return; + } + if (req->get_alternate_name().size() > alternate_name_max) { dout(10) << " alternate_name longer than " << alternate_name_max << dendl; respond_to_request(mdr, -ENAMETOOLONG); @@ -7382,6 +7403,11 @@ void Server::handle_client_mkdir(const MDRequestRef& mdr) return; ceph_assert(dn->get_projected_linkage()->is_null()); + + if (!can_handle_charmap(mdr, dn)) { + return; + } + if (req->get_alternate_name().size() > alternate_name_max) { dout(10) << " alternate_name longer than " << alternate_name_max << dendl; respond_to_request(mdr, -ENAMETOOLONG); @@ -7479,6 +7505,11 @@ void Server::handle_client_symlink(const MDRequestRef& mdr) return; ceph_assert(dn->get_projected_linkage()->is_null()); + + if (!can_handle_charmap(mdr, dn)) { + return; + } + if (req->get_alternate_name().size() > alternate_name_max) { dout(10) << " alternate_name longer than " << alternate_name_max << dendl; respond_to_request(mdr, -ENAMETOOLONG); @@ -7579,6 +7610,11 @@ void Server::handle_client_link(const MDRequestRef& mdr) } ceph_assert(destdn->get_projected_linkage()->is_null()); + + if (!can_handle_charmap(mdr, destdn)) { + return; + } + if (req->get_alternate_name().size() > alternate_name_max) { dout(10) << " alternate_name longer than " << alternate_name_max << dendl; respond_to_request(mdr, -ENAMETOOLONG); @@ -8996,6 +9032,10 @@ void Server::handle_client_rename(const MDRequestRef& mdr) CInode *srci = srcdnl->get_inode(); dout(10) << " srci " << *srci << dendl; + if (!can_handle_charmap(mdr, destdn)) { + return; + } + // -- some sanity checks -- if (destdn == srcdn) { dout(7) << "rename src=dest, noop" << dendl; diff --git a/src/mds/Server.h b/src/mds/Server.h index 351d6711b8a..96df059ff74 100644 --- a/src/mds/Server.h +++ b/src/mds/Server.h @@ -245,6 +245,8 @@ public: // check layout bool is_valid_layout(file_layout_t *layout); + bool can_handle_charmap(const MDRequestRef& mdr, CDentry* dn); + // open void handle_client_open(const MDRequestRef& mdr); void handle_client_openc(const MDRequestRef& mdr); // O_CREAT variant. -- 2.39.5