]> git.proxmox.com Git - ceph.git/blobdiff - ceph/src/mds/CDentry.cc
update ceph source to reef 18.1.2
[ceph.git] / ceph / src / mds / CDentry.cc
index 3a9aa5ef4f53b550a3351b287b68ab4758b49c39..55f2191346fa558c07f8c68711fe37111c8cc96f 100644 (file)
@@ -17,6 +17,7 @@
 #include "CDentry.h"
 #include "CInode.h"
 #include "CDir.h"
+#include "SnapClient.h"
 
 #include "MDSRank.h"
 #include "MDCache.h"
@@ -225,6 +226,22 @@ void CDentry::mark_new()
   state_set(STATE_NEW);
 }
 
+void CDentry::mark_auth()
+{
+  if (!is_auth()) {
+    state_set(STATE_AUTH);
+    dir->adjust_dentry_lru(this);
+  }
+}
+
+void CDentry::clear_auth()
+{
+  if (is_auth()) {
+    state_clear(STATE_AUTH);
+    dir->adjust_dentry_lru(this);
+  }
+}
+
 void CDentry::make_path_string(string& s, bool projected) const
 {
   if (dir) {
@@ -646,4 +663,62 @@ std::string CDentry::linkage_t::get_remote_d_type_string() const
   }
 }
 
+bool CDentry::scrub(snapid_t next_seq)
+{
+  dout(20) << "scrubbing " << *this << " next_seq = " << next_seq << dendl;
+
+  /* attempt to locate damage in first of CDentry, see:
+   * https://tracker.ceph.com/issues/56140
+   */
+  /* skip projected dentries as first/last may have placeholder values */
+  if (!is_projected()) {
+    CDir* dir = get_dir();
+
+    if (first > next_seq) {
+      derr << __func__ << ": first > next_seq (" << next_seq << ") " << *this << dendl;
+      dir->go_bad_dentry(last, get_name());
+      return true;
+    } else if (first > last) {
+      derr << __func__ << ": first > last " << *this << dendl;
+      dir->go_bad_dentry(last, get_name());
+      return true;
+    }
+
+    auto&& realm = dir->get_inode()->find_snaprealm();
+    if (realm) {
+      auto&& snaps = realm->get_snaps();
+      auto it = snaps.lower_bound(first);
+      bool stale = last != CEPH_NOSNAP && (it == snaps.end() || *it > last);
+      if (stale) {
+        dout(20) << "is stale" << dendl;
+        /* TODO: maybe trim? */
+      }
+    }
+  }
+  return false;
+}
+
+bool CDentry::check_corruption(bool load)
+{
+  auto&& snapclient = dir->mdcache->mds->snapclient;
+  auto next_snap = snapclient->get_last_seq()+1;
+  if (first > last || (snapclient->is_server_ready() && first > next_snap)) {
+    if (load) {
+      dout(1) << "loaded already corrupt dentry: " << *this << dendl;
+      corrupt_first_loaded = true;
+    } else {
+      derr << "newly corrupt dentry to be committed: " << *this << dendl;
+    }
+    if (g_conf().get_val<bool>("mds_go_bad_corrupt_dentry")) {
+      dir->go_bad_dentry(last, get_name());
+    }
+    if (!load && g_conf().get_val<bool>("mds_abort_on_newly_corrupt_dentry")) {
+      dir->mdcache->mds->clog->error() << "MDS abort because newly corrupt dentry to be committed: " << *this;
+      ceph_abort("detected newly corrupt dentry"); /* avoid writing out newly corrupted dn */
+    }
+    return true;
+  }
+  return false;
+}
+
 MEMPOOL_DEFINE_OBJECT_FACTORY(CDentry, co_dentry, mds_co);