1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
|
// -*- 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(waitmask_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(waitmask_t mask) {
for ([[maybe_unused]] auto& [seq, waiter] : waiting) {
if ((waiter.mask & mask).any()) {
return true;
}
}
return false;
}
void MDSCacheObject::take_waiting(waitmask_t mask, MDSContext::vec& ls) {
if (waiting.empty()) {
return;
}
for (auto it = waiting.begin(); it != waiting.end(); ) {
auto& waiter = it->second;
if ((waiter.mask & mask).any()) {
ls.push_back(waiter.c);
it = waiting.erase(it);
} else {
++it;
}
}
if (waiting.empty()) {
put(PIN_WAITER);
waiting.clear(); // free internal map
}
}
uint64_t MDSCacheObject::last_wait_seq = 0;
|