]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph-ci.git/commitdiff
client: check client config and snaprealm flag before snapdir lookup
authorDhairya Parmar <dparmar@redhat.com>
Tue, 8 Jul 2025 21:25:36 +0000 (02:55 +0530)
committerDhairya Parmar <dparmar@redhat.com>
Mon, 29 Sep 2025 08:40:47 +0000 (14:10 +0530)
this commit adds a new client config client_respect_subvolume_snapshot_visibility
which acts as knob to have a per-client control over the snapshot visibility and
checks it along with the snaprealm flag while looking up a subvolume inode.

Conficts:
Confict arose due to upstream 7ab995b715968a4d03cf91aa7c6f44e25757a45e not being part of
ceph-9.0-rhel-patches branch. Relevant code removed.

Fixes: https://tracker.ceph.com/issues/71740
Signed-off-by: Dhairya Parmar <dparmar@redhat.com>
(cherry picked from commit 1d20ac737af627667e31a09e2291d6c0e0b40ede)
Resolves: https://jsw.ibm.com/browse/ISCE-1465

src/client/Client.cc
src/client/Client.h
src/client/ClientSnapRealm.h
src/common/options/mds-client.yaml.in

index e3f2b5bc1782bae707016b225508d8886c1e484f..f30efbe5a0094b00ab5cb6b13e90f8049636983a 100644 (file)
@@ -428,6 +428,9 @@ Client::Client(Messenger *m, MonClient *mc, Objecter *objecter_)
   caps_release_delay = cct->_conf.get_val<std::chrono::seconds>(
     "client_caps_release_delay");
 
+  respect_subvolume_snapshot_visibility = cct->_conf.get_val<bool>(
+    "client_respect_subvolume_snapshot_visibility");
+
   if (cct->_conf->client_acl_type == "posix_acl")
     acl_type = POSIX_ACL;
 
@@ -5386,13 +5389,16 @@ static bool has_new_snaps(const SnapContext& old_snapc,
 }
 
 struct SnapRealmInfoMeta {
-  SnapRealmInfoMeta(utime_t last_modified, uint64_t change_attr)
+  SnapRealmInfoMeta(utime_t last_modified,
+                    uint64_t change_attr,
+                    bool is_snapdir_visible)
     : last_modified(last_modified),
-      change_attr(change_attr) {
-  }
+      change_attr(change_attr),
+      is_snapdir_visible(is_snapdir_visible) {}
 
   utime_t last_modified;
   uint64_t change_attr;
+  bool is_snapdir_visible;
 };
 
 static std::pair<SnapRealmInfo, std::optional<SnapRealmInfoMeta>> get_snap_realm_info(
@@ -5400,7 +5406,8 @@ static std::pair<SnapRealmInfo, std::optional<SnapRealmInfoMeta>> get_snap_realm
   if (session->mds_features.test(CEPHFS_FEATURE_NEW_SNAPREALM_INFO)) {
     SnapRealmInfoNew ninfo;
     decode(ninfo, p);
-    return std::make_pair(ninfo.info, SnapRealmInfoMeta(ninfo.last_modified, ninfo.change_attr));
+    return std::make_pair(ninfo.info, SnapRealmInfoMeta(ninfo.last_modified,
+                          ninfo.change_attr, ninfo.flags & SnapRealmInfoNew::SNAPDIR_VISIBILITY));
   } else {
     SnapRealmInfo info;
     decode(info, p);
@@ -5458,6 +5465,7 @@ void Client::update_snap_trace(MetaSession *session, const bufferlist& bl, SnapR
       if (realm_info_meta) {
         realm->last_modified = (*realm_info_meta).last_modified;
         realm->change_attr = (*realm_info_meta).change_attr;
+        realm->is_snapdir_visible = (*realm_info_meta).is_snapdir_visible;
       }
       realm->my_snaps = info.my_snaps;
       invalidate = true;
@@ -7674,12 +7682,14 @@ int Client::_lookup(const InodeRef& dir, const std::string& name, std::string& a
     goto done;
   }
 
-  if (dname == cct->_conf->client_snapdir) {
-    if (dir->snapid == CEPH_NOSNAP) {
-      *target = open_snapdir(dir);
-    } else {
+  if (dname == cct->_conf->client_snapdir &&
+      dir->snapid == CEPH_NOSNAP) {
+    if (respect_subvolume_snapshot_visibility &&
+        !dir->snaprealm->is_snapdir_visible) {
       r = -EPERM;
+      goto done;
     }
+    *target = open_snapdir(dir);
     goto done;
   }
 
@@ -13964,6 +13974,10 @@ int Client::mksnap(const char *relpath, const char *name, const UserPerm& perm,
   if (int rc = path_walk(cwd, filepath(relpath), &wdr, perm, {}); rc < 0) {
     return rc;
   }
+  if (respect_subvolume_snapshot_visibility &&
+      !wdr.target->snaprealm->is_snapdir_visible) {
+      return -EPERM;
+  }
   auto snapdir = open_snapdir(wdr.target);
   if (int rc = path_walk(std::move(snapdir), filepath(name), &wdr, perm, {.require_target = false}); rc < 0) {
     return rc;
@@ -13982,6 +13996,10 @@ int Client::rmsnap(const char *relpath, const char *name, const UserPerm& perms,
   if (int rc = path_walk(cwd, filepath(relpath), &in, perms, {}); rc < 0) {
     return rc;
   }
+  if (respect_subvolume_snapshot_visibility &&
+      !in->snaprealm->is_snapdir_visible) {
+      return -EPERM;
+  }
   auto snapdir = open_snapdir(in.get());
   return _rmdir(snapdir.get(), name, perms, check_perms);
 }
@@ -18556,6 +18574,7 @@ std::vector<std::string> Client::get_tracked_keys() const noexcept
     "client_oc_size",
     "client_oc_target_dirty",
     "client_permissions",
+    "client_respect_subvolume_snapshot_visibility",
     "fuse_default_permissions"
   });
   static_assert(std::is_sorted(begin(as_sv), end(as_sv)));
@@ -18610,6 +18629,10 @@ void Client::handle_conf_change(const ConfigProxy& conf,
     mount_timeout = cct->_conf.get_val<std::chrono::seconds>(
       "client_mount_timeout");
   }
+  if (changed.count("client_respect_subvolume_snapshot_visibility")) {
+    respect_subvolume_snapshot_visibility = cct->_conf.get_val<bool>(
+      "client_respect_subvolume_snapshot_visibility");
+  }
 }
 
 void intrusive_ptr_add_ref(Inode *in)
index 4c67116082f566d970d056ec9bf2c50f08b0c64c..6d181c62e5e7d34a14740cff974263fa33172ba1 100644 (file)
@@ -2363,6 +2363,7 @@ private:
   bool is_fuse = false;
   bool client_permissions;
   bool fuse_default_permissions;
+  bool respect_subvolume_snapshot_visibility;
 
   std::locale m_locale;
 };
index 17f45dbc9011eaa8889ff03c26546cf22676b5e6..2fcaf7bfedcae255af7935feb8e87517ef68c29a 100644 (file)
@@ -25,6 +25,7 @@ struct SnapRealm {
   std::set<SnapRealm*> pchildren;
   utime_t last_modified;
   uint64_t change_attr;
+  bool is_snapdir_visible = true;
 
 private:
   SnapContext cached_snap_context;  // my_snaps + parent snaps + past_parent_snaps
@@ -58,6 +59,7 @@ inline std::ostream& operator<<(std::ostream& out, const SnapRealm& r) {
             << " cached_snapc=" << r.cached_snap_context
             << " last_modified=" << r.last_modified
             << " change_attr=" << r.change_attr
+             << " is_snapdir_visible=" << r.is_snapdir_visible
             << ")";
 }
 
index 3223cc4e6dea2209d7554e481f668d0edd94ab6a..902dd341668f540c02f7c0956ccfd4fac8b8237f 100644 (file)
@@ -589,6 +589,17 @@ options:
   - mds_client
   flags:
   - runtime
+- name: client_respect_subvolume_snapshot_visibility
+  type: bool
+  level: advanced
+  desc: Respect subvolume snapshot visibility
+  long_desc: Option to decide whether to respect the is_snapdir_visible flag
+    set in each subvolume's snaprealm
+  default: false
+  services:
+  - mds_client
+  flags:
+  - runtime
 - name: client_file_blockdiff_max_concurrent_object_scans
   type: uint
   level: advanced