From 5ad0df3beedd1a74c5e1c30becc9048133773ff8 Mon Sep 17 00:00:00 2001 From: Patrick Donnelly Date: Wed, 3 Jul 2024 22:02:30 -0400 Subject: [PATCH] mds: generate correct path for unlinked snapped files A snapped unlinked directory is moved to the stray directory. Files in that directory will not have correct stray_prior_path set because the snapshot was naturally taken before the file is unlinked. Use the parent directory's stray_prior_path for cephx path access controls. Fixes: https://tracker.ceph.com/issues/66828 Signed-off-by: Patrick Donnelly --- src/mds/SessionMap.cc | 27 ++++++++++++++++++++++----- 1 file changed, 22 insertions(+), 5 deletions(-) diff --git a/src/mds/SessionMap.cc b/src/mds/SessionMap.cc index c296b88ec4d..4702d72ee2c 100644 --- a/src/mds/SessionMap.cc +++ b/src/mds/SessionMap.cc @@ -1047,11 +1047,28 @@ int Session::check_access(CInode *in, unsigned mask, << dendl; string path; - CInode *diri = NULL; - if (!in->is_base()) - diri = in->get_projected_parent_dn()->get_dir()->get_inode(); - if (diri && diri->is_stray()){ - path = in->get_projected_inode()->stray_prior_path; + if (!in->is_base()) { + auto* dn = in->get_projected_parent_dn(); + auto* pdiri = dn->get_dir()->get_inode(); + if (pdiri) { + if (pdiri->is_stray()) { + path = in->get_projected_inode()->stray_prior_path; + } else if (!pdiri->is_base()) { + /* is the pdiri in the stray (is this inode in a snapshotted deleted directory?) */ + auto* gpdiri = pdiri->get_projected_parent_dn()->get_dir()->get_inode(); + /* stray_prior_path will not necessarily be part of the inode because + * it's set on unlink but that happens after the snapshot, naturally. + * We need to construct it manually. + */ + if (gpdiri->is_stray()) { + /* just check access on the parent dir */ + path = pdiri->get_projected_inode()->stray_prior_path; + } + } + } + } + + if (!path.empty()) { dout(20) << __func__ << " stray_prior_path " << path << dendl; } else { in->make_path_string(path, true); -- 2.39.5