1 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2 // vim: ts=8 sw=2 smarttab
8 #include <boost/intrusive_ptr.hpp>
9 #include <boost/smart_ptr/intrusive_ref_counter.hpp>
10 #include <seastar/core/future.hh>
12 #include "include/ceph_assert.h"
13 #include "include/buffer_fwd.h"
14 #include "include/interval_set.h"
15 #include "common/interval_map.h"
16 #include "crimson/osd/exceptions.h"
18 #include "crimson/os/seastore/seastore_types.h"
19 #include "crimson/os/seastore/lba_manager.h"
20 #include "crimson/os/seastore/cache.h"
21 #include "crimson/os/seastore/segment_manager.h"
23 #include "crimson/os/seastore/lba_manager/btree/lba_btree_node.h"
25 namespace crimson::os::seastore::lba_manager::btree
{
30 * Uses a wandering btree to track two things:
31 * 1) lba state including laddr_t -> paddr_t mapping
32 * 2) reverse paddr_t -> laddr_t mapping for gc (TODO)
34 * Generally, any transaction will involve
35 * 1) deltas against lba tree nodes
36 * 2) new lba tree nodes
37 * - Note, there must necessarily be a delta linking
38 * these new nodes into the tree -- might be a
39 * bootstrap_state_t delta if new root
41 * get_mappings, alloc_extent_*, etc populate a Transaction
42 * which then gets submitted
44 class BtreeLBAManager
: public LBAManager
{
47 SegmentManager
&segment_manager
,
51 Transaction
&t
) final
;
53 get_mapping_ret
get_mapping(
55 laddr_t offset
, extent_len_t length
) final
;
57 get_mappings_ret
get_mappings(
59 laddr_list_t
&&list
) final
;
61 alloc_extent_ret
alloc_extent(
67 set_extent_ret
set_extent(
69 laddr_t off
, extent_len_t len
, paddr_t addr
) final
;
71 ref_ret
decref_extent(
74 return update_refcount(t
, addr
, -1);
77 ref_ret
incref_extent(
80 return update_refcount(t
, addr
, 1);
83 complete_transaction_ret
complete_transaction(
84 Transaction
&t
) final
;
86 init_cached_extent_ret
init_cached_extent(
88 CachedExtentRef e
) final
;
90 scan_mappings_ret
scan_mappings(
94 scan_mappings_func_t
&&f
) final
;
96 scan_mapped_space_ret
scan_mapped_space(
98 scan_mapped_space_func_t
&&f
) final
;
100 rewrite_extent_ret
rewrite_extent(
102 CachedExtentRef extent
);
104 get_physical_extent_if_live_ret
get_physical_extent_if_live(
109 segment_off_t len
) final
;
111 void add_pin(LBAPin
&pin
) final
{
112 auto *bpin
= reinterpret_cast<BtreeLBAPin
*>(&pin
);
113 pin_set
.add_pin(bpin
->pin
);
114 bpin
->parent
= nullptr;
118 SegmentManager
&segment_manager
;
121 btree_pin_set_t pin_set
;
123 op_context_t
get_context(Transaction
&t
) {
124 return op_context_t
{cache
, pin_set
, t
};
127 static btree_range_pin_t
&get_pin(CachedExtent
&e
);
133 * Get a reference to the root LBANode.
135 using get_root_ertr
= Cache::get_extent_ertr
;
136 using get_root_ret
= get_root_ertr::future
<LBANodeRef
>;
137 get_root_ret
get_root(Transaction
&);
142 * Insert a lba mapping into the tree
144 using insert_mapping_ertr
= crimson::errorator
<
145 crimson::ct_error::input_output_error
>;
146 using insert_mapping_ret
= insert_mapping_ertr::future
<LBAPinRef
>;
147 insert_mapping_ret
insert_mapping(
148 Transaction
&t
, ///< [in,out] transaction
149 LBANodeRef root
, ///< [in] root node
150 laddr_t laddr
, ///< [in] logical addr to insert
151 lba_map_val_t val
///< [in] mapping to insert
157 * Updates refcount, returns resulting refcount
159 using update_refcount_ret
= ref_ret
;
160 update_refcount_ret
update_refcount(
168 * Updates mapping, removes if f returns nullopt
170 using update_mapping_ertr
= ref_ertr
;
171 using update_mapping_ret
= ref_ertr::future
<lba_map_val_t
>;
172 using update_func_t
= LBANode::mutate_func_t
;
173 update_mapping_ret
update_mapping(
178 using update_internal_mapping_ertr
= LBANode::mutate_internal_address_ertr
;
179 using update_internal_mapping_ret
= LBANode::mutate_internal_address_ret
;
180 update_internal_mapping_ret
update_internal_mapping(
186 using BtreeLBAManagerRef
= std::unique_ptr
<BtreeLBAManager
>;