]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
mds: generate correct path for unlinked snapped files 58419/head
authorPatrick Donnelly <pdonnell@redhat.com>
Thu, 4 Jul 2024 02:02:30 +0000 (22:02 -0400)
committerPatrick Donnelly <pdonnell@redhat.com>
Thu, 4 Jul 2024 02:18:22 +0000 (22:18 -0400)
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 <pdonnell@redhat.com>
src/mds/SessionMap.cc

index c296b88ec4df5cc829524a51c06921edd2e1ab1f..4702d72ee2c4b048af07c536f017845e9e874254 100644 (file)
@@ -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);