From e323a34d1f3d076ab9c0a13814d137c7138ec532 Mon Sep 17 00:00:00 2001 From: Alexey Kopytov Date: Wed, 30 Dec 2015 23:20:19 +0300 Subject: [PATCH] Bug #79378: buf_block_align() makes incorrect assumptions about chunk size Code in buf_block_align() depended on srv_buf_pool_chunk_unit to find the chunk corresponding to a given pointer. The problem was that srv_buf_pool_chunk_unit does not necessarily reflect the real chunk size in bytes as explained in the bug report. Fix the algorithm buf_block_align() to not depend on any specific chunk size, but use std::map properly to find the corresponding element in the chunk map. --- storage/innobase/buf/buf0buf.cc | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/storage/innobase/buf/buf0buf.cc b/storage/innobase/buf/buf0buf.cc index ab0f086..ce8680a 100644 --- a/storage/innobase/buf/buf0buf.cc +++ b/storage/innobase/buf/buf0buf.cc @@ -3826,15 +3826,11 @@ buf_block_align( } #endif /* UNIV_DEBUG */ buf_pool_chunk_map_t* chunk_map = buf_chunk_map_ref; + buf_chunk_t* chunk; - if (ptr < reinterpret_cast(srv_buf_pool_chunk_unit)) { - it = chunk_map->upper_bound(0); - } else { - it = chunk_map->upper_bound( - ptr - srv_buf_pool_chunk_unit); - } + it = chunk_map->upper_bound(ptr); - if (it == chunk_map->end()) { + if (it == chunk_map->begin()) { #ifdef UNIV_DEBUG if (!resize_disabled) { rw_lock_s_unlock(buf_chunk_map_latch); @@ -3845,9 +3841,12 @@ buf_block_align( ut_a(counter < 10); os_thread_sleep(100000); /* 0.1 sec */ goto retry; + } else if (it == chunk_map->end()) { + chunk = chunk_map->rbegin()->second; + } else { + chunk = (--it)->second; } - buf_chunk_t* chunk = it->second; #ifdef UNIV_DEBUG if (!resize_disabled) { rw_lock_s_unlock(buf_chunk_map_latch);