From 409525b530adafa75a534bf16caac791bc12b3a6 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 (cherry picked from commit 9bbfdadd1f590fdea2fa055906f9184c7f81d676) Conflicts: src/mds/Server.cc: trivial comment change --- 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 17861b8fd60ac..274ce0401c013 100644 --- a/src/mds/Server.cc +++ b/src/mds/Server.cc @@ -4677,6 +4677,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; +} + /* This function takes responsibility for the passed mdr*/ void Server::handle_client_openc(const MDRequestRef& mdr) { @@ -4707,6 +4724,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); @@ -7331,6 +7352,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); @@ -7428,6 +7454,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); @@ -7528,6 +7559,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); @@ -8947,6 +8983,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 468f321c4ae7f..ac78058c73ae3 100644 --- a/src/mds/Server.h +++ b/src/mds/Server.h @@ -244,6 +244,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