]> git.apps.os.sepia.ceph.com Git - ceph-ci.git/commitdiff
mds: add ceph.dir.subvolume.snaps.visible vxattr
authorDhairya Parmar <dparmar@redhat.com>
Thu, 3 Jul 2025 11:52:38 +0000 (17:22 +0530)
committerDhairya Parmar <dparmar@redhat.com>
Wed, 17 Sep 2025 13:26:08 +0000 (18:56 +0530)
using SNAPDIR_VISIBILITY flag added in sr_t

Fixes: https://tracker.ceph.com/issues/71740
Signed-off-by: Dhairya Parmar <dparmar@redhat.com>
src/mds/Server.cc
src/mds/Server.h
src/mds/SnapRealm.cc
src/mds/snap.cc
src/mds/snap.h

index fdfd5d3e08ad596ce4eca36183cac4d3a2000eb1..c8f7997ea6474dd8aeff702aa26066192a60e4b5 100644 (file)
@@ -6518,6 +6518,96 @@ void Server::handle_client_setvxattr(const MDRequestRef& mdr, CInode *cur)
     mdr->no_early_reply = true;
     pip = pi.inode.get();
     adjust_realm = true;
+  } else if (name == "ceph.dir.subvolume.snaps.visible"sv) {
+    if (!cur->is_dir()) {
+      respond_to_request(mdr, -EINVAL);
+      return;
+    }
+
+    bool val = true;
+    try {
+      std::string errstr;
+      val = strict_strtob(value, &errstr);
+      if (!errstr.empty()) {
+        dout(10) << "bad vxattr value, unable to parse bool for " << name
+                 << ": " << errstr << dendl;
+        respond_to_request(mdr, -EINVAL);
+        return;
+      }
+    } catch (boost::bad_lexical_cast const& e) {
+      dout(10) << "bad vxattr value, unable to parse bool for " << name
+               << ": " << e.what() << dendl;
+      respond_to_request(mdr, -EINVAL);
+      return;
+    }
+
+    // perform few checks with lightweight rdlock
+    if (!mdr->more()->rdonly_checks) {
+      lov.add_rdlock(&cur->snaplock);
+      if (!mds->locker->acquire_locks(mdr, lov)) {
+        dout(20) << "handle_client_getvxattr could not acquire rdlock on "
+                 << *cur << dendl;
+        return;
+      }
+
+      const auto srnode = cur->get_projected_srnode();
+      if (!srnode) {
+        dout(10) << "no-op since no snaprealm node found for "
+                 << req->get_filepath() << dendl;
+        respond_to_request(mdr, 0);
+        return; 
+      }
+      // check if visibility already matches the desired value
+      if (val == srnode->is_snapdir_visible()) {
+        dout(20) << "snapdir visibility for " << req->get_filepath()
+                 << " is already set to " << std::boolalpha << val << dendl;
+        respond_to_request(mdr, 0);
+        return;
+      }
+      
+      mdr->more()->rdonly_checks = true;
+      dout(20) << "dropping rdlock on " << *cur << dendl;
+      mds->locker->drop_locks(mdr.get());
+    }
+
+    if (!xlock_policylock(mdr, cur, false, true)) {
+      return;
+    }
+
+    /* Repeat rdlocks checks to see if anything changed b/w rdlock release and
+    *  xlock policylock acquisition
+    */ 
+    {
+      const auto srnode = cur->get_projected_srnode();
+      if (!srnode) {
+        dout(10) << "no-op since no snaprealm node found for "
+                 << req->get_filepath() << dendl;
+        respond_to_request(mdr, 0);
+        return; 
+      }
+
+      if (val == srnode->is_snapdir_visible()) {
+        dout(20) << "snapdir visibility for " << req->get_filepath()
+                 << " is already set to " << std::boolalpha << val << dendl;
+        respond_to_request(mdr, 0);
+        return;
+      }
+    }
+
+    adjust_realm = true;
+    auto pi = cur->project_inode(mdr, false, adjust_realm);
+    dout(20) << "setting snapdir visibility to " << std::boolalpha
+               << val << " for " << req->get_filepath() << dendl;
+    if (val) {
+      pi.snapnode->set_snapdir_visibility();
+    } else {
+      pi.snapnode->unset_snapdir_visibility();
+    }
+    pi.snapnode->last_modified = mdr->get_op_stamp();
+    pi.snapnode->change_attr++;
+
+    mdr->no_early_reply = true;
+    pip = pi.inode.get();
   } else if (name == "ceph.dir.pin"sv) {
     if (!cur->is_dir() || cur->is_root()) {
       respond_to_request(mdr, -EINVAL);
@@ -7284,6 +7374,19 @@ void Server::handle_client_getvxattr(const MDRequestRef& mdr)
       // since we only handle ceph vxattrs here
       r = -ENODATA; // no such attribute
     }
+  } else if (xattr_name == "ceph.dir.subvolume.snaps.visible"sv) {
+    if (!cur->is_dir()) {
+      r = -ENOTDIR;
+    } else {
+      const auto srnode = cur->get_projected_srnode();
+      if (!srnode) {
+        dout(10) << "no-op since no snaprealm node found for "
+                 << mdr->client_request->get_filepath() << dendl;
+        r = 0;
+      } else {
+        *css << srnode->is_snapdir_visible();
+      }
+    }
   } else {
     // otherwise respond as invalid request
     // since we only handle ceph vxattrs here
index 234afe0f533b3f1bdda257ac56a7b59cba106d76..51de128d59d3b45eee5944dd7a92e3f246c1e581 100644 (file)
@@ -500,7 +500,8 @@ private:
            xattr_name == "ceph.dir.charmap"sv ||
            xattr_name == "ceph.dir.normalization"sv ||
            xattr_name == "ceph.dir.encoding"sv ||
-           xattr_name == "ceph.dir.casesensitive"sv;
+           xattr_name == "ceph.dir.casesensitive"sv ||
+           xattr_name == "ceph.dir.subvolume.snaps.visible"sv;
   }
 
   static bool is_ceph_dir_vxattr(std::string_view xattr_name) {
@@ -519,7 +520,8 @@ private:
             xattr_name == "ceph.dir.charmap"sv ||
             xattr_name == "ceph.dir.normalization"sv ||
             xattr_name == "ceph.dir.encoding"sv ||
-            xattr_name == "ceph.dir.casesensitive"sv;
+            xattr_name == "ceph.dir.casesensitive"sv ||
+            xattr_name == "ceph.dir.subvolume.snaps.visible"sv;
   }
 
   static bool is_ceph_file_vxattr(std::string_view xattr_name) {
index f4de37e3422a85290092ab60c7155c0193cb87ee..0ed4cb8fae91f757d1dcdd24bb65f92759d4b174 100644 (file)
@@ -57,7 +57,8 @@ ostream& operator<<(ostream& out, const SnapRealm& realm)
   if (realm.srnode.is_parent_global())
     out << " global ";
   out << " last_modified " << realm.srnode.last_modified
-      << " change_attr " << realm.srnode.change_attr;
+      << " change_attr " << realm.srnode.change_attr
+      << " is_snapdir_visible " << realm.srnode.is_snapdir_visible();
   out << " " << &realm << ")";
   return out;
 }
index ca316d084a2d59723001d5a5dcdcfa81c9f91407..b3cd1fc3d0d68d21dbf36a66a7386e1c7a7a0adb 100644 (file)
@@ -194,6 +194,7 @@ void sr_t::dump(Formatter *f) const
   f->dump_unsigned("last_destroyed", last_destroyed);
   f->dump_stream("last_modified") << last_modified;
   f->dump_unsigned("change_attr", change_attr);
+  f->dump_unsigned("is_snapdir_visible", is_snapdir_visible());
   f->dump_unsigned("current_parent_since", current_parent_since);
 
   f->open_array_section("snaps");
@@ -247,3 +248,11 @@ std::list<sr_t> sr_t::generate_test_instances()
   return ls;
 }
 
+void sr_t::print(std::ostream& out) const {
+  out << "sr_t(seq=" << seq
+      << " created=" << created
+      << " last_created=" << last_created
+      << " last_destroyed=" << last_destroyed
+      << " flags=" << flags << ")";
+}
+
index 539e20c68392afe5eb201af938b554a300e8f32a..73980611fd2d115ad7af93ef73b78b15e7a640e3 100644 (file)
@@ -88,10 +88,15 @@ struct sr_t {
   void clear_subvolume() { flags &= ~SUBVOLUME; }
   bool is_subvolume() const { return flags & SUBVOLUME; }
 
+  void set_snapdir_visibility() { flags |= SNAPDIR_VISIBILITY; }
+  void unset_snapdir_visibility() { flags &= ~SNAPDIR_VISIBILITY; }
+  bool is_snapdir_visible() const { return flags & SNAPDIR_VISIBILITY; }
+
   void encode(ceph::buffer::list &bl) const;
   void decode(ceph::buffer::list::const_iterator &bl);
   void dump(ceph::Formatter *f) const;
   static std::list<sr_t> generate_test_instances();
+  void print(std::ostream&) const;
 
   snapid_t seq = 0;                     // basically, a version/seq # for changes to _this_ realm.
   snapid_t created = 0;                 // when this realm was created.
@@ -106,11 +111,13 @@ struct sr_t {
   uint64_t change_attr = 0;             // tracks changes to snap
                                         // realm attrs.
 
-  __u32 flags = 0;
   enum {
     PARENT_GLOBAL      = 1 << 0,
     SUBVOLUME          = 1 << 1,
+    SNAPDIR_VISIBILITY = 1 << 2,
   };
+
+  __u32 flags = SNAPDIR_VISIBILITY; // snapdir visibility is always on by default
 };
 WRITE_CLASS_ENCODER(sr_t)