]> git.proxmox.com Git - ceph.git/blame - ceph/src/crimson/os/seastore/lba_manager/btree/btree_range_pin.cc
import quincy beta 17.1.0
[ceph.git] / ceph / src / crimson / os / seastore / lba_manager / btree / btree_range_pin.cc
CommitLineData
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
8namespace {
9 seastar::logger& logger() {
20effc67 10 return crimson::get_logger(ceph_subsys_seastore_lba);
f67539c2
TL
11 }
12}
13
14namespace crimson::os::seastore::lba_manager::btree {
15
16void 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
31btree_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
42void 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
47void 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
62btree_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
80const 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
100void 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
108void 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
145void btree_pin_set_t::retire(btree_range_pin_t &pin)
146{
147 pin.drop_ref();
148 remove_pin(pin, false);
149}
150
151void 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}