]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
crimson/zns: Add zone-capacity support.
authorAravind Ramesh <Aravind.Ramesh@wdc.com>
Thu, 18 Aug 2022 15:42:13 +0000 (21:12 +0530)
committerAravind <aravind.ramesh@wdc.com>
Fri, 2 Sep 2022 05:07:05 +0000 (10:37 +0530)
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 <aravind.ramesh@wdc.com>
src/crimson/os/seastore/segment_manager/zns.cc
src/crimson/os/seastore/segment_manager/zns.h

index 27dc1aed3147d7d29cc1278e1c1587f65ce5ac9c..cfca8da737d03b9b5f6d75713cd95ae56fda03b0 100644 (file)
@@ -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);
index b870eb15fd78c9315c9b61f50331ed7f769e7c45..7766a88271dc42b0a46a75e849cccc04c308d014 100644 (file)
@@ -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 {