]> 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>
Thu, 27 Feb 2025 18:41:55 +0000 (13:41 -0500)
Signed-off-by: Patrick Donnelly <pdonnell@ibm.com>
Fixes: https://tracker.ceph.com/issues/66373
src/mds/Server.cc
src/mds/Server.h

index a410b999102c095ca5c33f981cfa610433563512..bc6ecabe5cce602127e15ce4ac106e752a0fe0c0 100644 (file)
@@ -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<MClientRequest> &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;
index 351d6711b8a2b9b9611910a567fc5017a51c0589..96df059ff74da551975f30dc665fbb29b6feee78 100644 (file)
@@ -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.