@@ -529,15 +529,15 @@ Cache::scan(Continuation *cont, std::string_view hostname, int KB_per_second) co
529529
530530Action *
531531Cache::open_read (Continuation *cont, const CacheKey *key, CacheHTTPHdr *request, const HttpConfigAccessor *params,
532- CacheFragType type, std::string_view hostname) const
532+ CacheFragType type, std::string_view hostname, int volume_override ) const
533533{
534534 if (!CacheProcessor::IsCacheReady (type)) {
535535 cont->handleEvent (CACHE_EVENT_OPEN_READ_FAILED, reinterpret_cast <void *>(-ECACHE_NOT_READY));
536536 return ACTION_RESULT_DONE;
537537 }
538538 ink_assert (caches[type] == this );
539539
540- StripeSM *stripe = key_to_stripe (key, hostname);
540+ StripeSM *stripe = key_to_stripe (key, hostname, volume_override );
541541 Dir result, *last_collision = nullptr ;
542542 ProxyMutex *mutex = cont->mutex .get ();
543543 OpenDirEntry *od = nullptr ;
@@ -603,8 +603,8 @@ Cache::open_read(Continuation *cont, const CacheKey *key, CacheHTTPHdr *request,
603603
604604// main entry point for writing of http documents
605605Action *
606- Cache::open_write (Continuation *cont, const CacheKey *key, CacheHTTPInfo *info , time_t apin_in_cache , CacheFragType type,
607- std::string_view hostname) const
606+ Cache::open_write (Continuation *cont, const CacheKey *key, CacheHTTPInfo *old_info , time_t pin_in_cache , CacheFragType type,
607+ std::string_view hostname, int volume_override ) const
608608{
609609 if (!CacheProcessor::IsCacheReady (type)) {
610610 cont->handleEvent (CACHE_EVENT_OPEN_WRITE_FAILED, reinterpret_cast <void *>(-ECACHE_NOT_READY));
@@ -613,7 +613,7 @@ Cache::open_write(Continuation *cont, const CacheKey *key, CacheHTTPInfo *info,
613613
614614 ink_assert (caches[type] == this );
615615 intptr_t err = 0 ;
616- int if_writers = reinterpret_cast <uintptr_t >(info ) == CACHE_ALLOW_MULTIPLE_WRITES;
616+ int if_writers = reinterpret_cast <uintptr_t >(old_info ) == CACHE_ALLOW_MULTIPLE_WRITES;
617617 CacheVC *c = new_CacheVC (cont);
618618 c->vio .op = VIO::WRITE;
619619 c->first_key = *key;
@@ -629,10 +629,10 @@ Cache::open_write(Continuation *cont, const CacheKey *key, CacheHTTPInfo *info,
629629 } while (DIR_MASK_TAG (c->key .slice32 (2 )) == DIR_MASK_TAG (c->first_key .slice32 (2 )));
630630 c->earliest_key = c->key ;
631631 c->frag_type = CACHE_FRAG_TYPE_HTTP;
632- c->stripe = key_to_stripe (key, hostname);
632+ c->stripe = key_to_stripe (key, hostname, volume_override );
633633 StripeSM *stripe = c->stripe ;
634- c->info = info ;
635- if (c->info && reinterpret_cast <uintptr_t >(info ) != CACHE_ALLOW_MULTIPLE_WRITES) {
634+ c->info = old_info ;
635+ if (c->info && reinterpret_cast <uintptr_t >(old_info ) != CACHE_ALLOW_MULTIPLE_WRITES) {
636636 /*
637637 Update has the following code paths :
638638 a) Update alternate header only :
@@ -664,17 +664,17 @@ Cache::open_write(Continuation *cont, const CacheKey *key, CacheHTTPInfo *info,
664664 c->f .update = 1 ;
665665 c->op_type = static_cast <int >(CacheOpType::Update);
666666 DDbg (dbg_ctl_cache_update, " Update called" );
667- info ->object_key_get (&c->update_key );
667+ old_info ->object_key_get (&c->update_key );
668668 ink_assert (!(c->update_key .is_zero ()));
669- c->update_len = info ->object_size_get ();
669+ c->update_len = old_info ->object_size_get ();
670670 } else {
671671 c->op_type = static_cast <int >(CacheOpType::Write);
672672 }
673673
674674 ts::Metrics::Gauge::increment (cache_rsb.status [c->op_type ].active );
675675 ts::Metrics::Gauge::increment (stripe->cache_vol ->vol_rsb .status [c->op_type ].active );
676676 // coverity[Y2K38_SAFETY:FALSE]
677- c->pin_in_cache = static_cast <uint32_t >(apin_in_cache );
677+ c->pin_in_cache = static_cast <uint32_t >(pin_in_cache );
678678
679679 {
680680 CACHE_TRY_LOCK (lock, c->stripe ->mutex , cont->mutex ->thread_holding );
@@ -745,41 +745,70 @@ CacheVConnection::CacheVConnection() : VConnection(nullptr) {}
745745
746746// if generic_host_rec.stripes == nullptr, what do we do???
747747StripeSM *
748- Cache::key_to_stripe (const CacheKey *key, std::string_view hostname) const
748+ Cache::key_to_stripe (const CacheKey *key, std::string_view hostname, int volume_override ) const
749749{
750750 ReplaceablePtr<CacheHostTable>::ScopedReader hosttable (&this ->hosttable );
751751
752- uint32_t h = (key->slice32 (2 ) >> DIR_TAG_WIDTH) % STRIPE_HASH_TABLE_SIZE;
753- unsigned short *hash_table = hosttable->gen_host_rec .vol_hash_table ;
754- const CacheHostRecord *host_rec = &hosttable->gen_host_rec ;
752+ uint32_t h = (key->slice32 (2 ) >> DIR_TAG_WIDTH) % STRIPE_HASH_TABLE_SIZE;
753+ unsigned short *hash_table = hosttable->gen_host_rec .vol_hash_table ;
754+ const CacheHostRecord *host_rec = &hosttable->gen_host_rec ;
755+ StripeSM *selected_stripe = nullptr ;
756+ bool remap_selection = false ;
757+
758+ if (volume_override > 0 ) {
759+ for (int i = 0 ; i < host_rec->num_cachevols ; i++) {
760+ if (host_rec->cp [i] && host_rec->cp [i]->vol_number == volume_override) {
761+ for (int j = 0 ; j < host_rec->num_vols ; j++) {
762+ if (host_rec->stripes [j] && host_rec->stripes [j]->cache_vol &&
763+ host_rec->stripes [j]->cache_vol ->vol_number == volume_override) {
764+ selected_stripe = host_rec->stripes [j];
765+ remap_selection = true ;
766+ break ;
767+ }
768+ }
769+ break ;
770+ }
771+ }
772+
773+ if (!selected_stripe) {
774+ Warning (" Invalid volume override %d, volume configured but no stripes available. Falling back to hostname-based selection." ,
775+ volume_override);
776+ }
777+ }
755778
756- if (hosttable->m_numEntries > 0 && !hostname.empty ()) {
779+ // Normal hostname-based volume selection (if no valid override)
780+ if (!selected_stripe && hosttable->m_numEntries > 0 && !hostname.empty ()) {
757781 CacheHostResult res;
782+
758783 hosttable->Match (hostname, &res);
759784 if (res.record ) {
760785 unsigned short *host_hash_table = res.record ->vol_hash_table ;
786+
761787 if (host_hash_table) {
762- if (dbg_ctl_cache_hosting.on ()) {
763- char format_str[50 ];
764- snprintf (format_str, sizeof (format_str), " Volume: %%xd for host: %%.%ds" , static_cast <int >(hostname.length ()));
765- Dbg (dbg_ctl_cache_hosting, format_str, res.record , hostname.data ());
766- }
767- return res.record ->stripes [host_hash_table[h]];
788+ Dbg (dbg_ctl_cache_hosting, " Volume: %p for host: %.*s" , res.record , static_cast <int >(hostname.length ()), hostname.data ());
789+ selected_stripe = res.record ->stripes [host_hash_table[h]];
768790 }
769791 }
770792 }
771- if (hash_table) {
772- if (dbg_ctl_cache_hosting.on ()) {
773- char format_str[50 ];
774- snprintf (format_str, sizeof (format_str), " Generic volume: %%xd for host: %%.%ds" , static_cast <int >(hostname.length ()));
775- Dbg (dbg_ctl_cache_hosting, format_str, host_rec, hostname.data ());
793+
794+ // Generic/default volume selection (if no hostname match in hosting)
795+ if (!selected_stripe) {
796+ if (hash_table) {
797+ selected_stripe = host_rec->stripes [hash_table[h]];
798+ } else {
799+ selected_stripe = host_rec->stripes [0 ];
776800 }
777- return host_rec->stripes [hash_table[h]];
778- } else {
779- return host_rec->stripes [0 ];
780801 }
781- }
782802
803+ if (dbg_ctl_cache_hosting.on () && selected_stripe && selected_stripe->cache_vol ) {
804+ Dbg (dbg_ctl_cache_hosting, " Cache volume selected: %d (%s) for key=%08x%08x hostname='%.*s' %s" ,
805+ selected_stripe->cache_vol ->vol_number ,
806+ selected_stripe->cache_vol ->ramcache_enabled ? " ramcache_enabled" : " ramcache_disabled" , key->slice32 (0 ), key->slice32 (1 ),
807+ static_cast <int >(hostname.length ()), hostname.data (), remap_selection ? " (remap)" : " (calculated)" );
808+ }
809+
810+ return selected_stripe;
811+ }
783812int
784813FragmentSizeUpdateCb (const char * /* name ATS_UNUSED */ , RecDataT /* data_type ATS_UNUSED */ , RecData data,
785814 void * /* cookie ATS_UNUSED */ )
0 commit comments