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 "crimson/os/seastore/seastore_types.h"
14 #include "include/buffer_fwd.h"
15 #include "crimson/osd/exceptions.h"
17 #include "crimson/os/seastore/transaction.h"
18 #include "rbm_device.h"
19 #include "crimson/os/seastore/random_block_manager.h"
21 #include "crimson/common/layout.h"
22 #include "include/buffer.h"
23 #include "include/uuid.h"
24 #include "avlallocator.h"
27 namespace crimson::os::seastore
{
29 using RBMDevice
= random_block_device::RBMDevice
;
30 using RBMDeviceRef
= std::unique_ptr
<RBMDevice
>;
32 device_config_t
get_rbm_ephemeral_device_config(
33 std::size_t index
, std::size_t num_devices
);
35 class BlockRBManager final
: public RandomBlockManager
{
38 * Ondisk layout (TODO)
40 * ---------------------------------------------------------------------------
41 * | rbm_metadata_header_t | metadatas | ... | data blocks |
42 * ---------------------------------------------------------------------------
45 read_ertr::future
<> read(paddr_t addr
, bufferptr
&buffer
) final
;
46 write_ertr::future
<> write(paddr_t addr
, bufferptr
&buf
) final
;
47 open_ertr::future
<> open() final
;
48 close_ertr::future
<> close() final
;
53 * The role of this function is to find out free blocks the transaction requires.
54 * To do so, alloc_extent() looks into both in-memory allocator
55 * and freebitmap blocks.
57 * TODO: multiple allocation
60 paddr_t
alloc_extent(size_t size
) final
; // allocator, return blocks
62 void complete_allocation(paddr_t addr
, size_t size
) final
;
64 size_t get_start_rbm_addr() const {
65 return device
->get_shard_journal_start() + device
->get_journal_size();
67 size_t get_size() const final
{
68 return device
->get_shard_end() - get_start_rbm_addr();
70 extent_len_t
get_block_size() const final
{ return device
->get_block_size(); }
72 BlockRBManager(RBMDevice
* device
, std::string path
, bool detailed
)
73 : device(device
), path(path
) {
74 allocator
.reset(new AvlAllocator(detailed
));
77 write_ertr::future
<> write(rbm_abs_addr addr
, bufferlist
&bl
);
79 device_id_t
get_device_id() const final
{
81 return device
->get_device_id();
84 uint64_t get_free_blocks() const final
{
85 // TODO: return correct free blocks after block allocator is introduced
87 return get_size() / get_block_size();
89 const seastore_meta_t
&get_meta() const final
{
90 return device
->get_meta();
92 RBMDevice
* get_device() {
96 void mark_space_used(paddr_t paddr
, size_t len
) final
{
98 rbm_abs_addr addr
= convert_paddr_to_abs_addr(paddr
);
99 assert(addr
>= get_start_rbm_addr() &&
100 addr
+ len
<= device
->get_shard_end());
101 allocator
->mark_extent_used(addr
, len
);
104 void mark_space_free(paddr_t paddr
, size_t len
) final
{
106 rbm_abs_addr addr
= convert_paddr_to_abs_addr(paddr
);
107 assert(addr
>= get_start_rbm_addr() &&
108 addr
+ len
<= device
->get_shard_end());
109 allocator
->free_extent(addr
, len
);
112 paddr_t
get_start() final
{
113 return convert_abs_addr_to_paddr(
114 get_start_rbm_addr(),
115 device
->get_device_id());
118 rbm_extent_state_t
get_extent_state(paddr_t paddr
, size_t size
) final
{
120 rbm_abs_addr addr
= convert_paddr_to_abs_addr(paddr
);
121 assert(addr
>= get_start_rbm_addr() &&
122 addr
+ size
<= device
->get_shard_end());
123 return allocator
->get_extent_state(addr
, size
);
126 size_t get_journal_size() const final
{
127 return device
->get_journal_size();
132 * this contains the number of bitmap blocks, free blocks and
133 * rbm specific information
135 ExtentAllocatorRef allocator
;
138 int stream_id
; // for multi-stream
140 using BlockRBManagerRef
= std::unique_ptr
<BlockRBManager
>;