]>
Commit | Line | Data |
---|---|---|
f67539c2 TL |
1 | // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- |
2 | // vim: ts=8 sw=2 smarttab | |
3 | ||
4 | #include "crimson/common/log.h" | |
5 | ||
6 | #include "crimson/os/seastore/lba_manager/btree/btree_range_pin.h" | |
7 | ||
8 | namespace { | |
9 | seastar::logger& logger() { | |
20effc67 | 10 | return crimson::get_logger(ceph_subsys_seastore_lba); |
f67539c2 TL |
11 | } |
12 | } | |
13 | ||
14 | namespace crimson::os::seastore::lba_manager::btree { | |
15 | ||
16 | void btree_range_pin_t::take_pin(btree_range_pin_t &other) | |
17 | { | |
20effc67 TL |
18 | ceph_assert(other.extent); |
19 | if (other.pins) { | |
20 | other.pins->replace_pin(*this, other); | |
21 | pins = other.pins; | |
22 | other.pins = nullptr; | |
23 | ||
24 | if (other.has_ref()) { | |
25 | other.drop_ref(); | |
26 | acquire_ref(); | |
27 | } | |
f67539c2 TL |
28 | } |
29 | } | |
30 | ||
31 | btree_range_pin_t::~btree_range_pin_t() | |
32 | { | |
20effc67 TL |
33 | ceph_assert(!pins == !is_linked()); |
34 | ceph_assert(!ref); | |
f67539c2 TL |
35 | if (pins) { |
36 | logger().debug("{}: removing {}", __func__, *this); | |
37 | pins->remove_pin(*this, true); | |
38 | } | |
39 | extent = nullptr; | |
40 | } | |
41 | ||
42 | void btree_pin_set_t::replace_pin(btree_range_pin_t &to, btree_range_pin_t &from) | |
43 | { | |
44 | pins.replace_node(pins.iterator_to(from), to); | |
45 | } | |
46 | ||
47 | void btree_pin_set_t::remove_pin(btree_range_pin_t &pin, bool do_check_parent) | |
48 | { | |
49 | logger().debug("{}: {}", __func__, pin); | |
20effc67 TL |
50 | ceph_assert(pin.is_linked()); |
51 | ceph_assert(pin.pins); | |
52 | ceph_assert(!pin.ref); | |
f67539c2 TL |
53 | |
54 | pins.erase(pin); | |
55 | pin.pins = nullptr; | |
56 | ||
57 | if (do_check_parent) { | |
58 | check_parent(pin); | |
59 | } | |
60 | } | |
61 | ||
62 | btree_range_pin_t *btree_pin_set_t::maybe_get_parent( | |
63 | const lba_node_meta_t &meta) | |
64 | { | |
65 | auto cmeta = meta; | |
66 | cmeta.depth++; | |
67 | auto iter = pins.upper_bound(cmeta, btree_range_pin_t::meta_cmp_t()); | |
68 | if (iter == pins.begin()) { | |
69 | return nullptr; | |
70 | } else { | |
71 | --iter; | |
72 | if (iter->range.is_parent_of(meta)) { | |
73 | return &*iter; | |
74 | } else { | |
75 | return nullptr; | |
76 | } | |
77 | } | |
78 | } | |
79 | ||
80 | const btree_range_pin_t *btree_pin_set_t::maybe_get_first_child( | |
81 | const lba_node_meta_t &meta) const | |
82 | { | |
83 | if (meta.depth == 0) { | |
84 | return nullptr; | |
85 | } | |
86 | ||
87 | auto cmeta = meta; | |
88 | cmeta.depth--; | |
89 | ||
90 | auto iter = pins.lower_bound(cmeta, btree_range_pin_t::meta_cmp_t()); | |
91 | if (iter == pins.end()) { | |
92 | return nullptr; | |
93 | } else if (meta.is_parent_of(iter->range)) { | |
94 | return &*iter; | |
95 | } else { | |
96 | return nullptr; | |
97 | } | |
98 | } | |
99 | ||
100 | void btree_pin_set_t::release_if_no_children(btree_range_pin_t &pin) | |
101 | { | |
20effc67 | 102 | ceph_assert(pin.is_linked()); |
f67539c2 TL |
103 | if (maybe_get_first_child(pin.range) == nullptr) { |
104 | pin.drop_ref(); | |
105 | } | |
106 | } | |
107 | ||
108 | void btree_pin_set_t::add_pin(btree_range_pin_t &pin) | |
109 | { | |
20effc67 TL |
110 | ceph_assert(!pin.is_linked()); |
111 | ceph_assert(!pin.pins); | |
112 | ceph_assert(!pin.ref); | |
f67539c2 TL |
113 | |
114 | auto [prev, inserted] = pins.insert(pin); | |
115 | if (!inserted) { | |
20effc67 TL |
116 | logger().error( |
117 | "{}: unable to add {} ({}), found {} ({})", | |
118 | __func__, | |
119 | pin, | |
120 | *(pin.extent), | |
121 | *prev, | |
122 | *(prev->extent)); | |
123 | ceph_assert(0 == "impossible"); | |
f67539c2 TL |
124 | return; |
125 | } | |
126 | pin.pins = this; | |
127 | if (!pin.is_root()) { | |
128 | auto *parent = maybe_get_parent(pin.range); | |
20effc67 | 129 | ceph_assert(parent); |
f67539c2 TL |
130 | if (!parent->has_ref()) { |
131 | logger().debug("{}: acquiring parent {}", __func__, | |
132 | static_cast<void*>(parent)); | |
133 | parent->acquire_ref(); | |
134 | } else { | |
135 | logger().debug("{}: parent has ref {}", __func__, | |
136 | static_cast<void*>(parent)); | |
137 | } | |
138 | } | |
139 | if (maybe_get_first_child(pin.range) != nullptr) { | |
140 | logger().debug("{}: acquiring self {}", __func__, pin); | |
141 | pin.acquire_ref(); | |
142 | } | |
143 | } | |
144 | ||
145 | void btree_pin_set_t::retire(btree_range_pin_t &pin) | |
146 | { | |
147 | pin.drop_ref(); | |
148 | remove_pin(pin, false); | |
149 | } | |
150 | ||
151 | void btree_pin_set_t::check_parent(btree_range_pin_t &pin) | |
152 | { | |
153 | auto parent = maybe_get_parent(pin.range); | |
154 | if (parent) { | |
155 | logger().debug("{}: releasing parent {}", __func__, *parent); | |
156 | release_if_no_children(*parent); | |
157 | } | |
158 | } | |
159 | ||
160 | } |