summaryrefslogtreecommitdiffstats
path: root/src/mds/inode_backtrace.cc
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-27 18:24:20 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-27 18:24:20 +0000
commit483eb2f56657e8e7f419ab1a4fab8dce9ade8609 (patch)
treee5d88d25d870d5dedacb6bbdbe2a966086a0a5cf /src/mds/inode_backtrace.cc
parentInitial commit. (diff)
downloadceph-483eb2f56657e8e7f419ab1a4fab8dce9ade8609.tar.xz
ceph-483eb2f56657e8e7f419ab1a4fab8dce9ade8609.zip
Adding upstream version 14.2.21.upstream/14.2.21upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'src/mds/inode_backtrace.cc')
-rw-r--r--src/mds/inode_backtrace.cc163
1 files changed, 163 insertions, 0 deletions
diff --git a/src/mds/inode_backtrace.cc b/src/mds/inode_backtrace.cc
new file mode 100644
index 00000000..50e986a1
--- /dev/null
+++ b/src/mds/inode_backtrace.cc
@@ -0,0 +1,163 @@
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+
+#include "inode_backtrace.h"
+
+#include "common/Formatter.h"
+
+/* inode_backpointer_t */
+
+void inode_backpointer_t::encode(bufferlist& bl) const
+{
+ ENCODE_START(2, 2, bl);
+ encode(dirino, bl);
+ encode(dname, bl);
+ encode(version, bl);
+ ENCODE_FINISH(bl);
+}
+
+void inode_backpointer_t::decode(bufferlist::const_iterator& bl)
+{
+ DECODE_START_LEGACY_COMPAT_LEN(2, 2, 2, bl);
+ decode(dirino, bl);
+ decode(dname, bl);
+ decode(version, bl);
+ DECODE_FINISH(bl);
+}
+
+void inode_backpointer_t::decode_old(bufferlist::const_iterator& bl)
+{
+ using ceph::decode;
+ decode(dirino, bl);
+ decode(dname, bl);
+ decode(version, bl);
+}
+
+void inode_backpointer_t::dump(Formatter *f) const
+{
+ f->dump_unsigned("dirino", dirino);
+ f->dump_string("dname", dname);
+ f->dump_unsigned("version", version);
+}
+
+void inode_backpointer_t::generate_test_instances(list<inode_backpointer_t*>& ls)
+{
+ ls.push_back(new inode_backpointer_t);
+ ls.push_back(new inode_backpointer_t);
+ ls.back()->dirino = 1;
+ ls.back()->dname = "foo";
+ ls.back()->version = 123;
+}
+
+
+/*
+ * inode_backtrace_t
+ */
+
+void inode_backtrace_t::encode(bufferlist& bl) const
+{
+ ENCODE_START(5, 4, bl);
+ encode(ino, bl);
+ encode(ancestors, bl);
+ encode(pool, bl);
+ encode(old_pools, bl);
+ ENCODE_FINISH(bl);
+}
+
+void inode_backtrace_t::decode(bufferlist::const_iterator& bl)
+{
+ DECODE_START_LEGACY_COMPAT_LEN(5, 4, 4, bl);
+ if (struct_v < 3)
+ return; // sorry, the old data was crap
+ decode(ino, bl);
+ if (struct_v >= 4) {
+ decode(ancestors, bl);
+ } else {
+ __u32 n;
+ decode(n, bl);
+ while (n--) {
+ ancestors.push_back(inode_backpointer_t());
+ ancestors.back().decode_old(bl);
+ }
+ }
+ if (struct_v >= 5) {
+ decode(pool, bl);
+ decode(old_pools, bl);
+ }
+ DECODE_FINISH(bl);
+}
+
+void inode_backtrace_t::dump(Formatter *f) const
+{
+ f->dump_unsigned("ino", ino);
+ f->open_array_section("ancestors");
+ for (vector<inode_backpointer_t>::const_iterator p = ancestors.begin(); p != ancestors.end(); ++p) {
+ f->open_object_section("backpointer");
+ p->dump(f);
+ f->close_section();
+ }
+ f->close_section();
+ f->dump_int("pool", pool);
+ f->open_array_section("old_pools");
+ for (set<int64_t>::iterator p = old_pools.begin(); p != old_pools.end(); ++p) {
+ f->dump_int("old_pool", *p);
+ }
+ f->close_section();
+}
+
+void inode_backtrace_t::generate_test_instances(list<inode_backtrace_t*>& ls)
+{
+ ls.push_back(new inode_backtrace_t);
+ ls.push_back(new inode_backtrace_t);
+ ls.back()->ino = 1;
+ ls.back()->ancestors.push_back(inode_backpointer_t());
+ ls.back()->ancestors.back().dirino = 123;
+ ls.back()->ancestors.back().dname = "bar";
+ ls.back()->ancestors.back().version = 456;
+ ls.back()->pool = 0;
+ ls.back()->old_pools.insert(10);
+ ls.back()->old_pools.insert(7);
+}
+
+int inode_backtrace_t::compare(const inode_backtrace_t& other,
+ bool *equivalent, bool *divergent) const
+{
+ int min_size = std::min(ancestors.size(),other.ancestors.size());
+ *equivalent = true;
+ *divergent = false;
+ if (min_size == 0)
+ return 0;
+ int comparator = 0;
+ if (ancestors[0].version > other.ancestors[0].version)
+ comparator = 1;
+ else if (ancestors[0].version < other.ancestors[0].version)
+ comparator = -1;
+ if (ancestors[0].dirino != other.ancestors[0].dirino ||
+ ancestors[0].dname != other.ancestors[0].dname)
+ *divergent = true;
+ for (int i = 1; i < min_size; ++i) {
+ if (*divergent) {
+ /**
+ * we already know the dentries and versions are
+ * incompatible; no point checking farther
+ */
+ break;
+ }
+ if (ancestors[i].dirino != other.ancestors[i].dirino ||
+ ancestors[i].dname != other.ancestors[i].dname) {
+ *equivalent = false;
+ return comparator;
+ } else if (ancestors[i].version > other.ancestors[i].version) {
+ if (comparator < 0)
+ *divergent = true;
+ comparator = 1;
+ } else if (ancestors[i].version < other.ancestors[i].version) {
+ if (comparator > 0)
+ *divergent = true;
+ comparator = -1;
+ }
+ }
+ if (*divergent)
+ *equivalent = false;
+ return comparator;
+}