]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
mds: check client features for charmap
authorPatrick Donnelly <pdonnell@ibm.com>
Wed, 23 Oct 2024 18:49:49 +0000 (14:49 -0400)
committerPatrick Donnelly <pdonnell@ibm.com>
Mon, 17 Mar 2025 19:43:18 +0000 (15:43 -0400)
Signed-off-by: Patrick Donnelly <pdonnell@ibm.com>
Fixes: https://tracker.ceph.com/issues/66373
(cherry picked from commit 9bbfdadd1f590fdea2fa055906f9184c7f81d676)

Conflicts:
src/mds/Server.cc: trivial comment change

src/mds/Server.cc
src/mds/Server.h

index 17861b8fd60ac0b2f7844522b6544cd6f930f1a0..274ce0401c01383785e3818dadb855d1457f540c 100644 (file)
@@ -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;
index 468f321c4ae7f66c5b2a9b1f2842f4fa86f08860..ac78058c73ae32c3f14d7a7b8d933aaf03deb185 100644 (file)
@@ -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.