1 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2 // vim: ts=8 sw=2 smarttab
7 #include "crimson/os/seastore/logging.h"
9 #include "include/buffer.h"
10 #include "rbm_device.h"
11 #include "include/interval_set.h"
12 #include "include/intarith.h"
13 #include "block_rb_manager.h"
15 SET_SUBSYS(seastore_device
);
17 namespace crimson::os::seastore
{
19 device_config_t
get_rbm_ephemeral_device_config(
20 std::size_t index
, std::size_t num_devices
)
22 assert(num_devices
> index
);
23 magic_t magic
= 0xfffa;
24 auto type
= device_type_t::RANDOM_BLOCK_EPHEMERAL
;
26 secondary_device_set_t secondary_devices
;
28 is_major_device
= true;
29 for (std::size_t secondary_index
= index
+ 1;
30 secondary_index
< num_devices
;
32 device_id_t secondary_id
= static_cast<device_id_t
>(secondary_index
);
33 secondary_devices
.insert({
34 secondary_index
, device_spec_t
{magic
, type
, secondary_id
}
38 is_major_device
= false;
41 device_id_t id
= static_cast<device_id_t
>(DEVICE_ID_RANDOM_BLOCK_MIN
+ index
);
42 seastore_meta_t meta
= {};
43 return {is_major_device
,
44 device_spec_t
{magic
, type
, id
},
49 paddr_t
BlockRBManager::alloc_extent(size_t size
)
51 LOG_PREFIX(BlockRBManager::alloc_extent
);
53 auto alloc
= allocator
->alloc_extent(size
);
54 ceph_assert((*alloc
).num_intervals() == 1);
55 auto extent
= (*alloc
).begin();
56 ceph_assert(size
== extent
.get_len());
57 paddr_t paddr
= convert_abs_addr_to_paddr(
59 device
->get_device_id());
60 DEBUG("allocated addr: {}, size: {}, requested size: {}",
61 paddr
, extent
.get_len(), size
);
65 void BlockRBManager::complete_allocation(
66 paddr_t paddr
, size_t size
)
69 rbm_abs_addr addr
= convert_paddr_to_abs_addr(paddr
);
70 allocator
->complete_allocation(addr
, size
);
73 BlockRBManager::open_ertr::future
<> BlockRBManager::open()
76 assert(device
->get_available_size() > 0);
77 assert(device
->get_block_size() > 0);
78 auto ool_start
= get_start_rbm_addr();
81 device
->get_available_size() -
83 device
->get_block_size());
84 return open_ertr::now();
87 BlockRBManager::write_ertr::future
<> BlockRBManager::write(
91 LOG_PREFIX(BlockRBManager::write
);
93 rbm_abs_addr addr
= convert_paddr_to_abs_addr(paddr
);
94 rbm_abs_addr start
= 0;
95 rbm_abs_addr end
= device
->get_available_size();
96 if (addr
< start
|| addr
+ bptr
.length() > end
) {
97 ERROR("out of range: start {}, end {}, addr {}, length {}",
98 start
, end
, addr
, bptr
.length());
99 return crimson::ct_error::erange::make();
101 bufferptr bp
= bufferptr(ceph::buffer::create_page_aligned(bptr
.length()));
102 bp
.copy_in(0, bptr
.length(), bptr
.c_str());
103 return device
->write(
108 BlockRBManager::read_ertr::future
<> BlockRBManager::read(
112 LOG_PREFIX(BlockRBManager::read
);
114 rbm_abs_addr addr
= convert_paddr_to_abs_addr(paddr
);
115 rbm_abs_addr start
= 0;
116 rbm_abs_addr end
= device
->get_available_size();
117 if (addr
< start
|| addr
+ bptr
.length() > end
) {
118 ERROR("out of range: start {}, end {}, addr {}, length {}",
119 start
, end
, addr
, bptr
.length());
120 return crimson::ct_error::erange::make();
127 BlockRBManager::close_ertr::future
<> BlockRBManager::close()
131 return device
->close();
134 BlockRBManager::write_ertr::future
<> BlockRBManager::write(
138 LOG_PREFIX(BlockRBManager::write
);
142 bptr
= bufferptr(ceph::buffer::create_page_aligned(bl
.length()));
143 auto iter
= bl
.cbegin();
144 iter
.copy(bl
.length(), bptr
.c_str());
145 } catch (const std::exception
&e
) {
146 DEBUG("write: exception creating aligned buffer {}", e
);
147 ceph_assert(0 == "unhandled exception");
149 return device
->write(
154 std::ostream
&operator<<(std::ostream
&out
, const rbm_metadata_header_t
&header
)
156 out
<< " rbm_metadata_header_t(size=" << header
.size
157 << ", block_size=" << header
.block_size
158 << ", feature=" << header
.feature
159 << ", journal_size=" << header
.journal_size
160 << ", crc=" << header
.crc
161 << ", config=" << header
.config
;