#include <boost/intrusive_ptr.hpp>
#include <boost/smart_ptr/intrusive_ref_counter.hpp>
+#include <boost/iterator/counting_iterator.hpp>
#include <seastar/core/future.hh>
#include "include/ceph_assert.h"
#include "crimson/os/seastore/seastore_types.h"
#include "include/buffer_fwd.h"
+#include "crimson/common/config_proxy.h"
#include "crimson/osd/exceptions.h"
namespace crimson::os::seastore {
+using magic_t = uint64_t;
+
+struct device_spec_t{
+ magic_t magic;
+ device_type_t dtype;
+ device_id_t id;
+ DENC(device_spec_t, v, p) {
+ DENC_START(1, 1, p);
+ denc(v.magic, p);
+ denc(v.dtype, p);
+ denc(v.id, p);
+ DENC_FINISH(p);
+ }
+};
+
+std::ostream& operator<<(std::ostream&, const device_spec_t&);
+
+using secondary_device_set_t =
+ std::map<device_id_t, device_spec_t>;
+
+struct block_sm_superblock_t {
+ size_t size = 0;
+ size_t segment_size = 0;
+ size_t block_size = 0;
+
+ size_t segments = 0;
+ uint64_t tracker_offset = 0;
+ uint64_t first_segment_offset = 0;
+
+ bool major_dev = false;
+ magic_t magic = 0;
+ device_type_t dtype = device_type_t::NONE;
+ device_id_t device_id = DEVICE_ID_NULL;
+
+ seastore_meta_t meta;
+
+ secondary_device_set_t secondary_devices;
+ DENC(block_sm_superblock_t, v, p) {
+ DENC_START(1, 1, p);
+ denc(v.size, p);
+ denc(v.segment_size, p);
+ denc(v.block_size, p);
+ denc(v.segments, p);
+ denc(v.tracker_offset, p);
+ denc(v.first_segment_offset, p);
+ denc(v.meta, p);
+ denc(v.major_dev, p);
+ denc(v.magic, p);
+ denc(v.dtype, p);
+ denc(v.device_id, p);
+ if (v.major_dev) {
+ denc(v.secondary_devices, p);
+ }
+ DENC_FINISH(p);
+ }
+
+ void validate() const {
+ ceph_assert(block_size > 0);
+ ceph_assert(segment_size > 0 &&
+ segment_size % block_size == 0);
+ ceph_assert(size > segment_size &&
+ size % block_size == 0);
+ ceph_assert(segments > 0);
+ ceph_assert(tracker_offset > 0 &&
+ tracker_offset % block_size == 0);
+ ceph_assert(first_segment_offset > tracker_offset &&
+ first_segment_offset % block_size == 0);
+ ceph_assert(magic != 0);
+ ceph_assert(dtype == device_type_t::SEGMENTED);
+ ceph_assert(device_id <= DEVICE_ID_MAX_VALID);
+ for (const auto& [k, v] : secondary_devices) {
+ ceph_assert(k != device_id);
+ ceph_assert(k <= DEVICE_ID_MAX_VALID);
+ ceph_assert(k == v.id);
+ ceph_assert(v.magic != 0);
+ ceph_assert(v.dtype > device_type_t::NONE);
+ ceph_assert(v.dtype < device_type_t::NUM_TYPES);
+ }
+ }
+};
+
+std::ostream& operator<<(std::ostream&, const block_sm_superblock_t&);
+
+struct segment_manager_config_t {
+ bool major_dev = false;
+ magic_t magic = 0;
+ device_type_t dtype = device_type_t::NONE;
+ device_id_t device_id = DEVICE_ID_NULL;
+ seastore_meta_t meta;
+ secondary_device_set_t secondary_devices;
+};
+
+std::ostream& operator<<(std::ostream&, const segment_manager_config_t&);
+
class Segment : public boost::intrusive_ref_counter<
Segment,
boost::thread_unsafe_counter>{
};
using SegmentRef = boost::intrusive_ptr<Segment>;
+std::ostream& operator<<(std::ostream& out, Segment::segment_state_t);
+
constexpr size_t PADDR_SIZE = sizeof(paddr_t);
+class SegmentManager;
+
+using SegmentManagerRef = std::unique_ptr<SegmentManager>;
class SegmentManager {
public:
+ using access_ertr = crimson::errorator<
+ crimson::ct_error::input_output_error,
+ crimson::ct_error::permission_denied,
+ crimson::ct_error::enoent>;
+
+ using mount_ertr = access_ertr;
+ using mount_ret = access_ertr::future<>;
+ virtual mount_ret mount() = 0;
+
+ using close_ertr = crimson::errorator<
+ crimson::ct_error::input_output_error
+ >;
+ virtual close_ertr::future<> close() = 0;
+
+ using mkfs_ertr = access_ertr;
+ using mkfs_ret = mkfs_ertr::future<>;
+ virtual mkfs_ret mkfs(segment_manager_config_t meta) = 0;
+
using open_ertr = crimson::errorator<
crimson::ct_error::input_output_error,
crimson::ct_error::invarg,
virtual size_t get_size() const = 0;
virtual segment_off_t get_block_size() const = 0;
virtual segment_off_t get_segment_size() const = 0;
- virtual segment_id_t get_num_segments() const {
+ virtual device_segment_id_t get_num_segments() const {
ceph_assert(get_size() % get_segment_size() == 0);
- return ((segment_id_t)(get_size() / get_segment_size()));
+ return ((device_segment_id_t)(get_size() / get_segment_size()));
}
virtual const seastore_meta_t &get_meta() const = 0;
+ virtual device_id_t get_device_id() const = 0;
+
+ virtual secondary_device_set_t& get_secondary_devices() = 0;
+
+ virtual device_spec_t get_device_spec() const = 0;
+
+ virtual magic_t get_magic() const = 0;
+
virtual ~SegmentManager() {}
+
+ static seastar::future<SegmentManagerRef> get_segment_manager(const std::string &device);
};
-using SegmentManagerRef = std::unique_ptr<SegmentManager>;
}
+
+WRITE_CLASS_DENC(
+ crimson::os::seastore::device_spec_t
+)
+WRITE_CLASS_DENC(
+ crimson::os::seastore::block_sm_superblock_t
+)