1 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2 // vim: ts=8 sw=2 smarttab
6 #include <boost/intrusive_ptr.hpp>
7 #include <boost/smart_ptr/intrusive_ref_counter.hpp>
8 #include <seastar/core/future.hh>
10 #include "crimson/os/seastore/segment_manager.h"
12 #include "crimson/os/seastore/segment_manager/ephemeral.h"
14 namespace crimson::os::seastore::segment_manager
{
16 class EphemeralSegmentManager
;
17 using EphemeralSegmentManagerRef
= std::unique_ptr
<EphemeralSegmentManager
>;
19 struct ephemeral_config_t
{
21 size_t block_size
= 0;
22 size_t segment_size
= 0;
24 void validate() const {
25 ceph_assert_always(size
> 0);
26 ceph_assert_always(size
<= DEVICE_OFF_MAX
);
27 ceph_assert_always(segment_size
> 0);
28 ceph_assert_always(segment_size
<= SEGMENT_OFF_MAX
);
29 ceph_assert_always(size
/ segment_size
> 0);
30 ceph_assert_always(size
/ segment_size
<= DEVICE_SEGMENT_ID_MAX
);
34 constexpr ephemeral_config_t DEFAULT_TEST_EPHEMERAL
= {
40 std::ostream
&operator<<(std::ostream
&, const ephemeral_config_t
&);
42 EphemeralSegmentManagerRef
create_test_ephemeral();
44 device_config_t
get_ephemeral_device_config(
46 std::size_t num_main_devices
,
47 std::size_t num_cold_devices
);
49 class EphemeralSegment final
: public Segment
{
50 friend class EphemeralSegmentManager
;
51 EphemeralSegmentManager
&manager
;
52 const segment_id_t id
;
53 segment_off_t write_pointer
= 0;
55 EphemeralSegment(EphemeralSegmentManager
&manager
, segment_id_t id
);
57 segment_id_t
get_segment_id() const final
{ return id
; }
58 segment_off_t
get_write_capacity() const final
;
59 segment_off_t
get_write_ptr() const final
{ return write_pointer
; }
60 close_ertr::future
<> close() final
;
61 write_ertr::future
<> write(segment_off_t offset
, ceph::bufferlist bl
) final
;
62 write_ertr::future
<> advance_wp(segment_off_t offset
) final
;
64 ~EphemeralSegment() {}
67 class EphemeralSegmentManager final
: public SegmentManager
{
68 friend class EphemeralSegment
;
69 using segment_state_t
= Segment::segment_state_t
;
71 const ephemeral_config_t config
;
72 std::optional
<device_config_t
> device_config
;
74 device_type_t
get_device_type() const final
{
75 assert(device_config
);
76 return device_config
->spec
.dtype
;
79 size_t get_offset(paddr_t addr
) {
80 auto& seg_addr
= addr
.as_seg_paddr();
81 return (seg_addr
.get_segment_id().device_segment_id() * config
.segment_size
) +
82 seg_addr
.get_segment_off();
85 std::vector
<segment_state_t
> segment_state
;
87 char *buffer
= nullptr;
89 Segment::close_ertr::future
<> segment_close(segment_id_t id
);
92 EphemeralSegmentManager(
93 ephemeral_config_t config
)
98 ~EphemeralSegmentManager();
100 close_ertr::future
<> close() final
{
101 return close_ertr::now();
104 device_id_t
get_device_id() const final
{
105 assert(device_config
);
106 return device_config
->spec
.id
;
109 mount_ret
mount() final
{
110 return mount_ertr::now();
113 mkfs_ret
mkfs(device_config_t
) final
;
115 open_ertr::future
<SegmentRef
> open(segment_id_t id
) final
;
117 release_ertr::future
<> release(segment_id_t id
) final
;
119 read_ertr::future
<> read(
122 ceph::bufferptr
&out
) final
;
124 size_t get_available_size() const final
{
127 extent_len_t
get_block_size() const final
{
128 return config
.block_size
;
130 segment_off_t
get_segment_size() const final
{
131 return config
.segment_size
;
134 const seastore_meta_t
&get_meta() const final
{
135 assert(device_config
);
136 return device_config
->meta
;
139 secondary_device_set_t
& get_secondary_devices() final
{
140 assert(device_config
);
141 return device_config
->secondary_devices
;
144 magic_t
get_magic() const final
{
145 return device_config
->spec
.magic
;
148 using init_ertr
= crimson::errorator
<
149 crimson::ct_error::enospc
,
150 crimson::ct_error::invarg
>;
151 init_ertr::future
<> init();
155 // public so tests can bypass segment interface when simpler
156 Segment::write_ertr::future
<> segment_write(
159 bool ignore_check
=false);
164 #if FMT_VERSION >= 90000
165 template <> struct fmt::formatter
<crimson::os::seastore::segment_manager::ephemeral_config_t
> : fmt::ostream_formatter
{};