]>
Commit | Line | Data |
---|---|---|
1e59de90 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 <sys/mman.h> | |
5 | #include <string.h> | |
6 | ||
7 | #include "crimson/os/seastore/logging.h" | |
8 | ||
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" | |
14 | ||
15 | SET_SUBSYS(seastore_device); | |
16 | ||
17 | namespace crimson::os::seastore { | |
18 | ||
19 | device_config_t get_rbm_ephemeral_device_config( | |
20 | std::size_t index, std::size_t num_devices) | |
21 | { | |
22 | assert(num_devices > index); | |
23 | magic_t magic = 0xfffa; | |
24 | auto type = device_type_t::RANDOM_BLOCK_EPHEMERAL; | |
25 | bool is_major_device; | |
26 | secondary_device_set_t secondary_devices; | |
27 | if (index == 0) { | |
28 | is_major_device = true; | |
29 | for (std::size_t secondary_index = index + 1; | |
30 | secondary_index < num_devices; | |
31 | ++secondary_index) { | |
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} | |
35 | }); | |
36 | } | |
37 | } else { // index > 0 | |
38 | is_major_device = false; | |
39 | } | |
40 | ||
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}, | |
45 | meta, | |
46 | secondary_devices}; | |
47 | } | |
48 | ||
49 | paddr_t BlockRBManager::alloc_extent(size_t size) | |
50 | { | |
51 | LOG_PREFIX(BlockRBManager::alloc_extent); | |
52 | assert(allocator); | |
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( | |
58 | extent.get_start(), | |
59 | device->get_device_id()); | |
60 | DEBUG("allocated addr: {}, size: {}, requested size: {}", | |
61 | paddr, extent.get_len(), size); | |
62 | return paddr; | |
63 | } | |
64 | ||
65 | void BlockRBManager::complete_allocation( | |
66 | paddr_t paddr, size_t size) | |
67 | { | |
68 | assert(allocator); | |
69 | rbm_abs_addr addr = convert_paddr_to_abs_addr(paddr); | |
70 | allocator->complete_allocation(addr, size); | |
71 | } | |
72 | ||
73 | BlockRBManager::open_ertr::future<> BlockRBManager::open() | |
74 | { | |
75 | assert(device); | |
76 | assert(device->get_available_size() > 0); | |
77 | assert(device->get_block_size() > 0); | |
78 | auto ool_start = get_start_rbm_addr(); | |
79 | allocator->init( | |
80 | ool_start, | |
aee94f69 | 81 | device->get_shard_end() - |
1e59de90 TL |
82 | ool_start, |
83 | device->get_block_size()); | |
84 | return open_ertr::now(); | |
85 | } | |
86 | ||
87 | BlockRBManager::write_ertr::future<> BlockRBManager::write( | |
88 | paddr_t paddr, | |
89 | bufferptr &bptr) | |
90 | { | |
91 | LOG_PREFIX(BlockRBManager::write); | |
92 | ceph_assert(device); | |
93 | rbm_abs_addr addr = convert_paddr_to_abs_addr(paddr); | |
aee94f69 TL |
94 | rbm_abs_addr start = device->get_shard_start(); |
95 | rbm_abs_addr end = device->get_shard_end(); | |
1e59de90 TL |
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(); | |
100 | } | |
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( | |
104 | addr, | |
105 | std::move(bp)); | |
106 | } | |
107 | ||
108 | BlockRBManager::read_ertr::future<> BlockRBManager::read( | |
109 | paddr_t paddr, | |
110 | bufferptr &bptr) | |
111 | { | |
112 | LOG_PREFIX(BlockRBManager::read); | |
113 | ceph_assert(device); | |
114 | rbm_abs_addr addr = convert_paddr_to_abs_addr(paddr); | |
aee94f69 TL |
115 | rbm_abs_addr start = device->get_shard_start(); |
116 | rbm_abs_addr end = device->get_shard_end(); | |
1e59de90 TL |
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(); | |
121 | } | |
122 | return device->read( | |
123 | addr, | |
124 | bptr); | |
125 | } | |
126 | ||
127 | BlockRBManager::close_ertr::future<> BlockRBManager::close() | |
128 | { | |
129 | ceph_assert(device); | |
130 | allocator->close(); | |
131 | return device->close(); | |
132 | } | |
133 | ||
134 | BlockRBManager::write_ertr::future<> BlockRBManager::write( | |
135 | rbm_abs_addr addr, | |
136 | bufferlist &bl) | |
137 | { | |
138 | LOG_PREFIX(BlockRBManager::write); | |
139 | ceph_assert(device); | |
140 | bufferptr bptr; | |
141 | try { | |
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"); | |
148 | } | |
149 | return device->write( | |
150 | addr, | |
151 | std::move(bptr)); | |
152 | } | |
153 | ||
154 | std::ostream &operator<<(std::ostream &out, const rbm_metadata_header_t &header) | |
155 | { | |
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 | |
aee94f69 TL |
161 | << ", config=" << header.config |
162 | << ", shard_num=" << header.shard_num; | |
163 | for (auto p : header.shard_infos) { | |
164 | out << p; | |
165 | } | |
166 | return out << ")"; | |
167 | } | |
168 | ||
169 | std::ostream &operator<<(std::ostream &out, const rbm_shard_info_t &shard) | |
170 | { | |
171 | out << " rbm_shard_info_t(size=" << shard.size | |
172 | << ", start_offset=" << shard.start_offset; | |
1e59de90 TL |
173 | return out << ")"; |
174 | } | |
175 | ||
176 | } |