From: Aravind Ramesh Date: Thu, 18 Aug 2022 15:42:13 +0000 (+0530) Subject: crimson/zns: Add zone-capacity support. X-Git-Tag: v18.0.0~94^2~4 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=792aed13a214a4ebba67084915c0ffc8c30d4129;p=ceph.git crimson/zns: Add zone-capacity support. ZNS SSDs have an attribute called zone_capacity which can be less than or equal to zone_size. zone_capacity represents the actual writable media in a zone. When zone_capacity is less than zone_size, writing to offsets beyond zone_capacity will cause write errors. Set the segment size as equal to zone_capacity, so that segment managers writes only upto capacity of the zone/segment. Update device size to actual available bytes so that the gc can kick in at appropriate thresholds. Signed-off-by: Aravind Ramesh --- diff --git a/src/crimson/os/seastore/segment_manager/zns.cc b/src/crimson/os/seastore/segment_manager/zns.cc index 27dc1aed3147..cfca8da737d0 100644 --- a/src/crimson/os/seastore/segment_manager/zns.cc +++ b/src/crimson/os/seastore/segment_manager/zns.cc @@ -45,7 +45,7 @@ static open_device_ret open_device( } static zns_sm_metadata_t make_metadata( - uint64_t size, + uint64_t total_size, seastore_meta_t meta, const seastar::stat_data &data, size_t zone_size_sectors, @@ -61,13 +61,17 @@ static zns_sm_metadata_t make_metadata( size_t segment_size = zone_size; size_t zones_per_segment = segment_size / zone_size; size_t segments = (num_zones - RESERVED_ZONES) / zones_per_segment; + size_t available_size = zone_capacity * segments; + + assert(total_size == num_zones * zone_size); WARN("Ignoring configuration values for device and segment size"); INFO( - "device size {}, block_size {}, allocated_size {}," + "device size {}, available_size {}, block_size {}, allocated_size {}," " total zones {}, zone_size {}, zone_capacity {}," " total segments {}, zones per segment {}, segment size {}", - size, + total_size, + available_size, data.block_size, data.allocated_size, num_zones, @@ -78,7 +82,7 @@ static zns_sm_metadata_t make_metadata( zone_capacity * zones_per_segment); zns_sm_metadata_t ret = zns_sm_metadata_t{ - size, + available_size, segment_size, zone_capacity * zones_per_segment, zones_per_segment, @@ -549,12 +553,12 @@ SegmentManager::read_ertr::future<> ZNSSegmentManager::read( auto& seg_addr = addr.as_seg_paddr(); if (seg_addr.get_segment_id().device_segment_id() >= get_num_segments()) { ERROR("invalid segment {}", - addr); + seg_addr.get_segment_id().device_segment_id()); return crimson::ct_error::invarg::make(); } - if (seg_addr.get_segment_off() + len > metadata.segment_size) { - ERROR("invalid offset {}, len {}", + if (seg_addr.get_segment_off() + len > metadata.segment_capacity) { + ERROR("invalid read offset {}, len {}", addr, len); return crimson::ct_error::invarg::make(); @@ -653,8 +657,9 @@ Segment::write_ertr::future<> ZNSSegment::write( id, offset, write_pointer); return crimson::ct_error::invarg::make(); } - if (offset + bl.length() > manager.metadata.segment_size) + if (offset + bl.length() > manager.metadata.segment_capacity) { return crimson::ct_error::enospc::make(); + } write_pointer = offset + bl.length(); return manager.segment_write(paddr_t::make_seg_paddr(id, offset), bl); diff --git a/src/crimson/os/seastore/segment_manager/zns.h b/src/crimson/os/seastore/segment_manager/zns.h index b870eb15fd78..7766a88271dc 100644 --- a/src/crimson/os/seastore/segment_manager/zns.h +++ b/src/crimson/os/seastore/segment_manager/zns.h @@ -108,7 +108,7 @@ namespace crimson::os::seastore::segment_manager::zns { }; seastore_off_t get_segment_size() const final { - return metadata.segment_size; + return metadata.segment_capacity; }; const seastore_meta_t &get_meta() const {