Skip to content

Commit 5f9eb71

Browse files
committed
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. Fixes: https://tracker.ceph.com/issues/71740 Signed-off-by: Dhairya Parmar <[email protected]>
1 parent 6520c6d commit 5f9eb71

File tree

4 files changed

+44
-4
lines changed

4 files changed

+44
-4
lines changed

src/client/Client.cc

Lines changed: 30 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -431,6 +431,9 @@ Client::Client(Messenger *m, MonClient *mc, Objecter *objecter_)
431431
injected_write_delay_secs = std::chrono::duration<int>(
432432
cct->_conf.get_val<std::chrono::seconds>("client_inject_write_delay_secs")).count();
433433

434+
respect_subvolume_snapshot_visibility = cct->_conf.get_val<bool>(
435+
"client_respect_subvolume_snapshot_visibility");
436+
434437
if (cct->_conf->client_acl_type == "posix_acl")
435438
acl_type = POSIX_ACL;
436439

@@ -5314,21 +5317,25 @@ static bool has_new_snaps(const SnapContext& old_snapc,
53145317
}
53155318

53165319
struct SnapRealmInfoMeta {
5317-
SnapRealmInfoMeta(utime_t last_modified, uint64_t change_attr)
5320+
SnapRealmInfoMeta(utime_t last_modified,
5321+
uint64_t change_attr,
5322+
bool is_snapdir_visible)
53185323
: last_modified(last_modified),
5319-
change_attr(change_attr) {
5320-
}
5324+
change_attr(change_attr),
5325+
is_snapdir_visible(is_snapdir_visible) {}
53215326

53225327
utime_t last_modified;
53235328
uint64_t change_attr;
5329+
bool is_snapdir_visible;
53245330
};
53255331

53265332
static std::pair<SnapRealmInfo, std::optional<SnapRealmInfoMeta>> get_snap_realm_info(
53275333
MetaSession *session, bufferlist::const_iterator &p) {
53285334
if (session->mds_features.test(CEPHFS_FEATURE_NEW_SNAPREALM_INFO)) {
53295335
SnapRealmInfoNew ninfo;
53305336
decode(ninfo, p);
5331-
return std::make_pair(ninfo.info, SnapRealmInfoMeta(ninfo.last_modified, ninfo.change_attr));
5337+
return std::make_pair(ninfo.info, SnapRealmInfoMeta(ninfo.last_modified,
5338+
ninfo.change_attr, ninfo.flags & SnapRealmInfoNew::SNAPDIR_VISIBILITY));
53325339
} else {
53335340
SnapRealmInfo info;
53345341
decode(info, p);
@@ -5386,6 +5393,7 @@ void Client::update_snap_trace(MetaSession *session, const bufferlist& bl, SnapR
53865393
if (realm_info_meta) {
53875394
realm->last_modified = (*realm_info_meta).last_modified;
53885395
realm->change_attr = (*realm_info_meta).change_attr;
5396+
realm->is_snapdir_visible = (*realm_info_meta).is_snapdir_visible;
53895397
}
53905398
realm->my_snaps = info.my_snaps;
53915399
invalidate = true;
@@ -7602,6 +7610,11 @@ int Client::_lookup(const InodeRef& dir, const std::string& name, std::string& a
76027610

76037611
if (dname == cct->_conf->client_snapdir &&
76047612
dir->snapid == CEPH_NOSNAP) {
7613+
if (respect_subvolume_snapshot_visibility &&
7614+
!dir->snaprealm->is_snapdir_visible) {
7615+
r = -EPERM;
7616+
goto done;
7617+
}
76057618
*target = open_snapdir(dir);
76067619
goto done;
76077620
}
@@ -13336,6 +13349,10 @@ int Client::mksnap(const char *relpath, const char *name, const UserPerm& perm,
1333613349
if (int rc = path_walk(cwd, filepath(relpath), &wdr, perm, {}); rc < 0) {
1333713350
return rc;
1333813351
}
13352+
if (respect_subvolume_snapshot_visibility &&
13353+
!wdr.target->snaprealm->is_snapdir_visible) {
13354+
return -EPERM;
13355+
}
1333913356
auto snapdir = open_snapdir(wdr.target);
1334013357
if (int rc = path_walk(std::move(snapdir), filepath(name), &wdr, perm, {.require_target = false}); rc < 0) {
1334113358
return rc;
@@ -13354,6 +13371,10 @@ int Client::rmsnap(const char *relpath, const char *name, const UserPerm& perms,
1335413371
if (int rc = path_walk(cwd, filepath(relpath), &in, perms, {}); rc < 0) {
1335513372
return rc;
1335613373
}
13374+
if (respect_subvolume_snapshot_visibility &&
13375+
!in->snaprealm->is_snapdir_visible) {
13376+
return -EPERM;
13377+
}
1335713378
auto snapdir = open_snapdir(in.get());
1335813379
return _rmdir(snapdir.get(), name, perms, check_perms);
1335913380
}
@@ -17659,6 +17680,7 @@ std::vector<std::string> Client::get_tracked_keys() const noexcept
1765917680
"client_oc_size",
1766017681
"client_oc_target_dirty",
1766117682
"client_permissions",
17683+
"client_respect_subvolume_snapshot_visibility",
1766217684
"fuse_default_permissions"
1766317685
});
1766417686
static_assert(std::is_sorted(begin(as_sv), end(as_sv)));
@@ -17717,6 +17739,10 @@ void Client::handle_conf_change(const ConfigProxy& conf,
1771717739
injected_write_delay_secs = std::chrono::duration<int>(
1771817740
cct->_conf.get_val<std::chrono::seconds>("client_inject_write_delay_secs")).count();
1771917741
}
17742+
if (changed.count("client_respect_subvolume_snapshot_visibility")) {
17743+
respect_subvolume_snapshot_visibility = cct->_conf.get_val<bool>(
17744+
"client_respect_subvolume_snapshot_visibility");
17745+
}
1772017746
}
1772117747

1772217748
void intrusive_ptr_add_ref(Inode *in)

src/client/Client.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2058,6 +2058,7 @@ class Client : public Dispatcher, public md_config_obs_t {
20582058
bool is_fuse = false;
20592059
bool client_permissions;
20602060
bool fuse_default_permissions;
2061+
bool respect_subvolume_snapshot_visibility;
20612062

20622063
std::locale m_locale;
20632064
};

src/client/ClientSnapRealm.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ struct SnapRealm {
2929
std::set<SnapRealm*> pchildren;
3030
utime_t last_modified;
3131
uint64_t change_attr;
32+
bool is_snapdir_visible = true;
3233

3334
private:
3435
SnapContext cached_snap_context; // my_snaps + parent snaps + past_parent_snaps
@@ -62,6 +63,7 @@ inline std::ostream& operator<<(std::ostream& out, const SnapRealm& r) {
6263
<< " cached_snapc=" << r.cached_snap_context
6364
<< " last_modified=" << r.last_modified
6465
<< " change_attr=" << r.change_attr
66+
<< " is_snapdir_visible=" << r.is_snapdir_visible
6567
<< ")";
6668
}
6769

src/common/options/mds-client.yaml.in

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -589,6 +589,17 @@ options:
589589
- mds_client
590590
flags:
591591
- runtime
592+
- name: client_respect_subvolume_snapshot_visibility
593+
type: bool
594+
level: advanced
595+
desc: Respect subvolume snapshot visibility
596+
long_desc: Option to decide whether to respect the is_snapdir_visible flag
597+
set in each subvolume's snaprealm
598+
default: false
599+
services:
600+
- mds_client
601+
flags:
602+
- runtime
592603
- name: client_file_blockdiff_max_concurrent_object_scans
593604
type: uint
594605
level: advanced

0 commit comments

Comments
 (0)