From: Dhairya Parmar Date: Tue, 8 Jul 2025 21:25:36 +0000 (+0530) Subject: client: check client config and snaprealm flag before snapdir lookup X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=22fd58185de8138b9432bb18425a5fd09a66beb1;p=ceph-ci.git client: check client config and snaprealm flag before snapdir lookup 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 (cherry picked from commit 1d20ac737af627667e31a09e2291d6c0e0b40ede) Resolves: https://jsw.ibm.com/browse/ISCE-1465 --- diff --git a/src/client/Client.cc b/src/client/Client.cc index e3f2b5bc178..f30efbe5a00 100644 --- a/src/client/Client.cc +++ b/src/client/Client.cc @@ -428,6 +428,9 @@ Client::Client(Messenger *m, MonClient *mc, Objecter *objecter_) caps_release_delay = cct->_conf.get_val( "client_caps_release_delay"); + respect_subvolume_snapshot_visibility = cct->_conf.get_val( + "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> get_snap_realm_info( @@ -5400,7 +5406,8 @@ static std::pair> 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 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( "client_mount_timeout"); } + if (changed.count("client_respect_subvolume_snapshot_visibility")) { + respect_subvolume_snapshot_visibility = cct->_conf.get_val( + "client_respect_subvolume_snapshot_visibility"); + } } void intrusive_ptr_add_ref(Inode *in) diff --git a/src/client/Client.h b/src/client/Client.h index 4c67116082f..6d181c62e5e 100644 --- a/src/client/Client.h +++ b/src/client/Client.h @@ -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; }; diff --git a/src/client/ClientSnapRealm.h b/src/client/ClientSnapRealm.h index 17f45dbc901..2fcaf7bfedc 100644 --- a/src/client/ClientSnapRealm.h +++ b/src/client/ClientSnapRealm.h @@ -25,6 +25,7 @@ struct SnapRealm { std::set 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 << ")"; } diff --git a/src/common/options/mds-client.yaml.in b/src/common/options/mds-client.yaml.in index 3223cc4e6de..902dd341668 100644 --- a/src/common/options/mds-client.yaml.in +++ b/src/common/options/mds-client.yaml.in @@ -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