Skip to content

Commit 64e2bd3

Browse files
committed
Merge PR ceph#58419 into main
* refs/pull/58419/head: mds: generate correct path for unlinked snapped files qa: add test for cephx path check on unlinked snapped dir tree mds: add debugging for stray_prior_path Reviewed-by: Milind Changire <[email protected]>
2 parents 925c1f9 + 5ad0df3 commit 64e2bd3

File tree

3 files changed

+56
-5
lines changed

3 files changed

+56
-5
lines changed

qa/tasks/cephfs/test_snapshots.py

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -376,6 +376,32 @@ def _check_snapclient_cache(snaps_dump, cache_dump=None, rank=0):
376376

377377
self.mount_a.run_shell(["rmdir", Raw("d0/d2/dir/.snap/*")])
378378

379+
def test_snapshot_check_access(self):
380+
"""
381+
"""
382+
383+
self.mount_a.run_shell_payload("mkdir -p dir1/dir2")
384+
self.mount_a.umount_wait(require_clean=True)
385+
386+
newid = 'foo'
387+
keyring = self.fs.authorize(newid, ('/dir1', 'rws'))
388+
keyring_path = self.mount_a.client_remote.mktemp(data=keyring)
389+
self.mount_a.remount(client_id=newid, client_keyring_path=keyring_path, cephfs_mntpt='/dir1')
390+
391+
self.mount_a.run_shell_payload("pushd dir2; dd if=/dev/urandom of=file bs=4k count=1;")
392+
self.mount_a.run_shell_payload("mkdir .snap/one")
393+
self.mount_a.run_shell_payload("rm -rf dir2")
394+
# ???
395+
# Session check_access path ~mds0/stray3/10000000001/file
396+
# 2024-07-04T02:05:07.884+0000 7f319ce86640 20 Session check_access: [inode 0x10000000002 [2,2] ~mds0/stray2/10000000001/file ...] caller_uid=1141 caller_gid=1141 caller_gid_list=[1000,1141]
397+
# 2024-07-04T02:05:07.884+0000 7f319ce86640 20 Session check_access path ~mds0/stray2/10000000001/file
398+
# should be
399+
# 2024-07-04T02:11:26.990+0000 7f6b14e71640 20 Session check_access: [inode 0x10000000002 [2,2] ~mds0/stray2/10000000001/file ...] caller_uid=1141 caller_gid=1141 caller_gid_list=[1000,1141]
400+
# 2024-07-04T02:11:26.990+0000 7f6b14e71640 20 Session check_access stray_prior_path /dir1/dir2
401+
# 2024-07-04T02:11:26.990+0000 7f6b14e71640 10 MDSAuthCap is_capable inode(path /dir1/dir2 owner 1141:1141 mode 0100644) by caller 1141:1141 mask 1 new 0:0 cap: MDSAuthCaps[allow rws fsname=cephfs path="/dir1"]
402+
self.mount_a.run_shell_payload("stat .snap/one/dir2/file")
403+
404+
379405
def test_multimds_mksnap(self):
380406
"""
381407
check if snapshot takes effect across authority subtrees

src/mds/Server.cc

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8228,6 +8228,7 @@ void Server::_unlink_local(const MDRequestRef& mdr, CDentry *dn, CDentry *strayd
82288228
{
82298229
std::string t;
82308230
dn->make_path_string(t, true);
8231+
dout(20) << " stray_prior_path = " << t << dendl;
82318232
pi.inode->stray_prior_path = std::move(t);
82328233
}
82338234
pi.inode->version = in->pre_dirty();
@@ -9523,6 +9524,7 @@ void Server::_rename_prepare(const MDRequestRef& mdr,
95239524
{
95249525
std::string t;
95259526
destdn->make_path_string(t, true);
9527+
dout(20) << " stray_prior_path = " << t << dendl;
95269528
tpi->stray_prior_path = std::move(t);
95279529
}
95289530
tpi->nlink--;

src/mds/SessionMap.cc

Lines changed: 28 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1040,12 +1040,35 @@ int Session::check_access(CInode *in, unsigned mask,
10401040
const vector<uint64_t> *caller_gid_list,
10411041
int new_uid, int new_gid)
10421042
{
1043+
dout(20) << __func__ << ": " << *in
1044+
<< " caller_uid=" << caller_uid
1045+
<< " caller_gid=" << caller_gid
1046+
<< " caller_gid_list=" << *caller_gid_list
1047+
<< dendl;
1048+
10431049
string path;
1044-
CInode *diri = NULL;
1045-
if (!in->is_base())
1046-
diri = in->get_projected_parent_dn()->get_dir()->get_inode();
1047-
if (diri && diri->is_stray()){
1048-
path = in->get_projected_inode()->stray_prior_path;
1050+
if (!in->is_base()) {
1051+
auto* dn = in->get_projected_parent_dn();
1052+
auto* pdiri = dn->get_dir()->get_inode();
1053+
if (pdiri) {
1054+
if (pdiri->is_stray()) {
1055+
path = in->get_projected_inode()->stray_prior_path;
1056+
} else if (!pdiri->is_base()) {
1057+
/* is the pdiri in the stray (is this inode in a snapshotted deleted directory?) */
1058+
auto* gpdiri = pdiri->get_projected_parent_dn()->get_dir()->get_inode();
1059+
/* stray_prior_path will not necessarily be part of the inode because
1060+
* it's set on unlink but that happens after the snapshot, naturally.
1061+
* We need to construct it manually.
1062+
*/
1063+
if (gpdiri->is_stray()) {
1064+
/* just check access on the parent dir */
1065+
path = pdiri->get_projected_inode()->stray_prior_path;
1066+
}
1067+
}
1068+
}
1069+
}
1070+
1071+
if (!path.empty()) {
10491072
dout(20) << __func__ << " stray_prior_path " << path << dendl;
10501073
} else {
10511074
in->make_path_string(path, true);

0 commit comments

Comments
 (0)