From: Yingxin Cheng Date: Thu, 6 Jan 2022 08:03:20 +0000 (+0800) Subject: crimson/os/seastore/../segment_manager: add more validations X-Git-Tag: v17.1.0~80^2 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=8aaaeea814c429e9e477f69cb4b5a72fc3192405;p=ceph.git crimson/os/seastore/../segment_manager: add more validations Signed-off-by: Yingxin Cheng --- diff --git a/src/crimson/os/seastore/segment_manager.h b/src/crimson/os/seastore/segment_manager.h index 7b501706420..5a7c48a00a5 100644 --- a/src/crimson/os/seastore/segment_manager.h +++ b/src/crimson/os/seastore/segment_manager.h @@ -73,6 +73,30 @@ struct block_sm_superblock_t { } 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&); diff --git a/src/crimson/os/seastore/segment_manager/block.cc b/src/crimson/os/seastore/segment_manager/block.cc index 320b0620e68..f27942d5d3e 100644 --- a/src/crimson/os/seastore/segment_manager/block.cc +++ b/src/crimson/os/seastore/segment_manager/block.cc @@ -304,6 +304,7 @@ write_superblock( { LOG_PREFIX(block_write_superblock); DEBUG("D{} write {}", device_id, sb); + sb.validate(); assert(ceph::encoded_sizeof(sb) < sb.block_size); return seastar::do_with( @@ -382,7 +383,8 @@ Segment::write_ertr::future<> BlockSegment::write( 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(), @@ -460,6 +462,7 @@ BlockSegmentManager::mount_ret BlockSegmentManager::mount() }).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(superblock)); @@ -616,6 +619,13 @@ SegmentManager::read_ertr::future<> BlockSegmentManager::read( 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,