summaryrefslogtreecommitdiffstats
path: root/src/mds/MDSCacheObject.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/mds/MDSCacheObject.cc')
-rw-r--r--src/mds/MDSCacheObject.cc137
1 files changed, 137 insertions, 0 deletions
diff --git a/src/mds/MDSCacheObject.cc b/src/mds/MDSCacheObject.cc
new file mode 100644
index 000000000..626623a81
--- /dev/null
+++ b/src/mds/MDSCacheObject.cc
@@ -0,0 +1,137 @@
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+
+#include "MDSCacheObject.h"
+#include "MDSContext.h"
+#include "common/Formatter.h"
+
+std::string_view MDSCacheObject::generic_pin_name(int p) const {
+ switch (p) {
+ case PIN_REPLICATED: return "replicated";
+ case PIN_DIRTY: return "dirty";
+ case PIN_LOCK: return "lock";
+ case PIN_REQUEST: return "request";
+ case PIN_WAITER: return "waiter";
+ case PIN_DIRTYSCATTERED: return "dirtyscattered";
+ case PIN_AUTHPIN: return "authpin";
+ case PIN_PTRWAITER: return "ptrwaiter";
+ case PIN_TEMPEXPORTING: return "tempexporting";
+ case PIN_CLIENTLEASE: return "clientlease";
+ case PIN_DISCOVERBASE: return "discoverbase";
+ case PIN_SCRUBQUEUE: return "scrubqueue";
+ default: ceph_abort(); return std::string_view();
+ }
+}
+
+void MDSCacheObject::finish_waiting(uint64_t mask, int result) {
+ MDSContext::vec finished;
+ take_waiting(mask, finished);
+ finish_contexts(g_ceph_context, finished, result);
+}
+
+void MDSCacheObject::dump(ceph::Formatter *f) const
+{
+ f->dump_bool("is_auth", is_auth());
+
+ // Fields only meaningful for auth
+ f->open_object_section("auth_state");
+ {
+ f->open_object_section("replicas");
+ for (const auto &it : get_replicas()) {
+ CachedStackStringStream css;
+ *css << it.first;
+ f->dump_int(css->strv(), it.second);
+ }
+ f->close_section();
+ }
+ f->close_section(); // auth_state
+
+ // Fields only meaningful for replica
+ f->open_object_section("replica_state");
+ {
+ f->open_array_section("authority");
+ f->dump_int("first", authority().first);
+ f->dump_int("second", authority().second);
+ f->close_section();
+ f->dump_unsigned("replica_nonce", get_replica_nonce());
+ }
+ f->close_section(); // replica_state
+
+ f->dump_int("auth_pins", auth_pins);
+ f->dump_bool("is_frozen", is_frozen());
+ f->dump_bool("is_freezing", is_freezing());
+
+#ifdef MDS_REF_SET
+ f->open_object_section("pins");
+ for(const auto& p : ref_map) {
+ f->dump_int(pin_name(p.first), p.second);
+ }
+ f->close_section();
+#endif
+ f->dump_int("nref", ref);
+}
+
+/*
+ * Use this in subclasses when printing their specialized
+ * states too.
+ */
+void MDSCacheObject::dump_states(ceph::Formatter *f) const
+{
+ if (state_test(STATE_AUTH)) f->dump_string("state", "auth");
+ if (state_test(STATE_DIRTY)) f->dump_string("state", "dirty");
+ if (state_test(STATE_NOTIFYREF)) f->dump_string("state", "notifyref");
+ if (state_test(STATE_REJOINING)) f->dump_string("state", "rejoining");
+ if (state_test(STATE_REJOINUNDEF))
+ f->dump_string("state", "rejoinundef");
+}
+
+bool MDSCacheObject::is_waiter_for(uint64_t mask, uint64_t min) {
+ if (!min) {
+ min = mask;
+ while (min & (min-1)) // if more than one bit is set
+ min &= min-1; // clear LSB
+ }
+ for (auto p = waiting.lower_bound(min); p != waiting.end(); ++p) {
+ if (p->first & mask) return true;
+ if (p->first > mask) return false;
+ }
+ return false;
+}
+
+void MDSCacheObject::take_waiting(uint64_t mask, MDSContext::vec& ls) {
+ if (waiting.empty()) return;
+
+ // process ordered waiters in the same order that they were added.
+ std::map<uint64_t, MDSContext*> ordered_waiters;
+
+ for (auto it = waiting.begin(); it != waiting.end(); ) {
+ if (it->first & mask) {
+ if (it->second.first > 0) {
+ ordered_waiters.insert(it->second);
+ } else {
+ ls.push_back(it->second.second);
+ }
+// pdout(10,g_conf()->debug_mds) << (mdsco_db_line_prefix(this))
+// << "take_waiting mask " << hex << mask << dec << " took " << it->second
+// << " tag " << hex << it->first << dec
+// << " on " << *this
+// << dendl;
+ waiting.erase(it++);
+ } else {
+// pdout(10,g_conf()->debug_mds) << "take_waiting mask " << hex << mask << dec << " SKIPPING " << it->second
+// << " tag " << hex << it->first << dec
+// << " on " << *this
+// << dendl;
+ ++it;
+ }
+ }
+ for (auto it = ordered_waiters.begin(); it != ordered_waiters.end(); ++it) {
+ ls.push_back(it->second);
+ }
+ if (waiting.empty()) {
+ put(PIN_WAITER);
+ waiting.clear();
+ }
+}
+
+uint64_t MDSCacheObject::last_wait_seq = 0;