@@ -80,6 +80,12 @@ size_t storage_pool::device_t::chunks() const
8080 return metadata_->chunks (size_of_file_);
8181}
8282
83+ size_t storage_pool::device_t::cnv_chunks () const
84+ {
85+ MONAD_ASSERT (!is_zoned_device (), " zonefs support isn't implemented yet" );
86+ return metadata_->num_cnv_chunks ;
87+ }
88+
8389std::pair<file_offset_t , file_offset_t > storage_pool::device_t::capacity () const
8490{
8591 switch (type_) {
@@ -454,6 +460,7 @@ storage_pool::device_t storage_pool::make_device_(
454460 memcpy (metadata_footer->magic , " MND0" , 4 );
455461 metadata_footer->chunk_capacity =
456462 static_cast <uint32_t >(chunk_capacity);
463+ metadata_footer->num_cnv_chunks = flags.num_cnv_chunks ;
457464 MONAD_ASSERT_PRINTF (
458465 ::pwrite (
459466 readwritefd,
@@ -504,21 +511,29 @@ void storage_pool::fill_chunks_(creation_flags const &flags)
504511 fnv1a_hash<uint32_t >::add (
505512 hashshouldbe, uint32_t (device.unique_hash_ >> 32 ));
506513 }
514+ // Backward compatibility: databases created before `num_cnv_chunks` was
515+ // added have this field set to 0. Treat 0 as the legacy default of 3
516+ // chunks.
517+ uint32_t const cnv_chunks_count =
518+ devices_[0 ].metadata_ ->num_cnv_chunks == 0
519+ ? 3
520+ : devices_[0 ].metadata_ ->num_cnv_chunks ;
507521 std::vector<size_t > chunks;
508522 size_t total = 0 ;
509523 chunks.reserve (devices_.size ());
510524 for (auto const &device : devices_) {
511525 if (device.is_file () || device.is_block_device ()) {
512526 auto const devicechunks = device.chunks ();
513527 MONAD_ASSERT_PRINTF (
514- devicechunks >= 4 ,
515- " Device %s has %zu chunks the minimum allowed is four ." ,
528+ devicechunks >= cnv_chunks_count + 1 ,
529+ " Device %s has %zu chunks the minimum allowed is %u ." ,
516530 device.current_path ().c_str (),
517- devicechunks);
531+ devicechunks,
532+ cnv_chunks_count + 1 );
518533 MONAD_ASSERT (devicechunks <= std::numeric_limits<uint32_t >::max ());
519- // Take off three for the cnv chunks
520- chunks.push_back (devicechunks - 3 );
521- total += devicechunks - 3 ;
534+ // Take off cnv_chunks_count for the cnv chunks
535+ chunks.push_back (devicechunks - cnv_chunks_count );
536+ total += devicechunks - cnv_chunks_count ;
522537 fnv1a_hash<uint32_t >::add (
523538 hashshouldbe, static_cast <uint32_t >(devicechunks));
524539 fnv1a_hash<uint32_t >::add (
@@ -560,22 +575,17 @@ void storage_pool::fill_chunks_(creation_flags const &flags)
560575 auto const zone_id = [this ](int const chunk_type) {
561576 return static_cast <uint32_t >(chunks_[chunk_type].size ());
562577 };
563- // First three blocks of each device goes to conventional, remainder go to
564- // sequential
565- chunks_[cnv].reserve (devices_.size () * 3 );
578+ // First cnv_chunks_count blocks of each device goes to conventional,
579+ // remainder go to sequential
580+ chunks_[cnv].reserve (devices_.size () * cnv_chunks_count );
566581 chunks_[seq].reserve (total);
567582 if (flags.interleave_chunks_evenly ) {
568- for (auto &device : devices_) {
569- chunks_[cnv].emplace_back (
570- activate_chunk (storage_pool::cnv, device, 0 , zone_id (cnv)));
571- }
572- for (auto &device : devices_) {
573- chunks_[cnv].emplace_back (
574- activate_chunk (storage_pool::cnv, device, 1 , zone_id (cnv)));
575- }
576- for (auto &device : devices_) {
577- chunks_[cnv].emplace_back (
578- activate_chunk (storage_pool::cnv, device, 2 , zone_id (cnv)));
583+ for (uint32_t chunk_idx = 0 ; chunk_idx < cnv_chunks_count;
584+ ++chunk_idx) {
585+ for (auto &device : devices_) {
586+ chunks_[cnv].emplace_back (activate_chunk (
587+ storage_pool::cnv, device, chunk_idx, zone_id (cnv)));
588+ }
579589 }
580590 // We now need to evenly spread the sequential chunks such that if
581591 // device A has 20, device B has 10 and device C has 5, the interleaving
@@ -585,7 +595,7 @@ void storage_pool::fill_chunks_(creation_flags const &flags)
585595 for (size_t n = 0 ; n < chunks.size (); n++) {
586596 chunkratios[n] = double (total) / static_cast <double >(chunks[n]);
587597 chunkcounts[n] = chunkratios[n];
588- chunks[n] = 3 ;
598+ chunks[n] = cnv_chunks_count ;
589599 }
590600 while (chunks_[seq].size () < chunks_[seq].capacity ()) {
591601 for (size_t n = 0 ; n < chunks.size (); n++) {
@@ -612,19 +622,18 @@ void storage_pool::fill_chunks_(creation_flags const &flags)
612622 }
613623 else {
614624 for (auto &device : devices_) {
615- chunks_[cnv].emplace_back (
616- activate_chunk (cnv, device, 0 , zone_id (cnv)));
617- chunks_[cnv].emplace_back (
618- activate_chunk (cnv, device, 1 , zone_id (cnv)));
619- chunks_[cnv].emplace_back (
620- activate_chunk (cnv, device, 2 , zone_id (cnv)));
625+ for (uint32_t chunk_idx = 0 ; chunk_idx < cnv_chunks_count;
626+ ++chunk_idx) {
627+ chunks_[cnv].emplace_back (
628+ activate_chunk (cnv, device, chunk_idx, zone_id (cnv)));
629+ }
621630 }
622631 for (size_t deviceidx = 0 ; deviceidx < chunks.size (); deviceidx++) {
623632 for (size_t n = 0 ; n < chunks[deviceidx]; n++) {
624633 chunks_[seq].emplace_back (activate_chunk (
625634 seq,
626635 devices_[deviceidx],
627- static_cast <uint32_t >(3 + n),
636+ static_cast <uint32_t >(cnv_chunks_count + n),
628637 zone_id (seq)));
629638 }
630639 }
0 commit comments