}
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&);
{
LOG_PREFIX(block_write_superblock);
DEBUG("D{} write {}", device_id, sb);
+ sb.validate();
assert(ceph::encoded_sizeof<block_sm_superblock_t>(sb) <
sb.block_size);
return seastar::do_with(
manager.get_offset(paddr));
if (offset < write_pointer ||
- offset % manager.superblock.block_size != 0) {
+ offset % manager.superblock.block_size != 0 ||
+ bl.length() % manager.superblock.block_size != 0) {
ERROR("D{} S{} offset={}~{} poffset={} invalid write",
id.device_id(),
id.device_segment_id(),
}).safe_then([=](auto sb) {
set_device_id(sb.device_id);
INFO("D{} read {}", get_device_id(), sb);
+ sb.validate();
superblock = sb;
stats.data_read.increment(
ceph::encoded_sizeof<block_sm_superblock_t>(superblock));
assert(addr.get_device_id() == get_device_id());
+ if (s_off % superblock.block_size != 0 ||
+ len % superblock.block_size != 0) {
+ ERROR("D{} S{} offset={}~{} poffset={} invalid read",
+ get_device_id(), s_id, s_off, len, p_off);
+ return crimson::ct_error::invarg::make();
+ }
+
if (s_id >= get_num_segments()) {
ERROR("D{} S{} offset={}~{} poffset={} segment-id out of range {}",
get_device_id(), s_id, s_off, len, p_off,