Commit 8b00501b authored by marko's avatar marko

branches/zip: Clarify that buf_buddy_alloc() should only be used for

allocating compressed page frames or their control blocks.  Also note
that if buf_buddy_alloc() is used for allocating a control block,
it must be initialized before releasing buf_pool->mutex.

buf_page_init_for_read(): When the page hash check fails after
buf_buddy_alloc(), free the uninitialized control block before freeing
the compressed page frame.  This fixes a potential error in
buf_buddy_relocate_block().
parent b7acbef6
...@@ -537,6 +537,14 @@ buf_buddy_relocate( ...@@ -537,6 +537,14 @@ buf_buddy_relocate(
is used for either compressed pages or buf_page_t is used for either compressed pages or buf_page_t
objects covering compressed pages. */ objects covering compressed pages. */
/* We look inside the allocated objects returned by
buf_buddy_alloc() and assume that anything of
PAGE_ZIP_MIN_SIZE or larger is a compressed page that contains
a valid space_id and page_no in the page header. Should the
fields be invalid, we will be unable to relocate the block.
We also assume that anything that fits sizeof(buf_page_t)
actually is a properly initialized buf_page_t object. */
if (size >= PAGE_ZIP_MIN_SIZE) { if (size >= PAGE_ZIP_MIN_SIZE) {
/* This is a compressed page. */ /* This is a compressed page. */
mutex_t* mutex; mutex_t* mutex;
......
...@@ -2595,8 +2595,8 @@ err_exit2: ...@@ -2595,8 +2595,8 @@ err_exit2:
&& UNIV_LIKELY_NULL(buf_page_hash_get(space, offset))) { && UNIV_LIKELY_NULL(buf_page_hash_get(space, offset))) {
/* The block was added by some other thread. */ /* The block was added by some other thread. */
buf_buddy_free(data, zip_size);
buf_buddy_free(bpage, sizeof *bpage); buf_buddy_free(bpage, sizeof *bpage);
buf_buddy_free(data, zip_size);
goto err_exit2; goto err_exit2;
} }
......
...@@ -19,9 +19,13 @@ Created December 2006 by Marko Makela ...@@ -19,9 +19,13 @@ Created December 2006 by Marko Makela
/************************************************************************** /**************************************************************************
Allocate a block. The thread calling this function must hold Allocate a block. The thread calling this function must hold
buf_pool->mutex and must not hold buf_pool->zip_mutex or any block->mutex. buf_pool->mutex and must not hold buf_pool->zip_mutex or any
The buf_pool->mutex may only be released and reacquired if block->mutex. The buf_pool->mutex may only be released and reacquired
lru == BUF_BUDDY_USE_LRU. */ if lru == BUF_BUDDY_USE_LRU. This function should only be used for
allocating compressed page frames or control blocks (buf_page_t).
Allocated control blocks must be properly initialized immediately
after buf_buddy_alloc() has returned the memory, before releasing
buf_pool->mutex. */
UNIV_INLINE UNIV_INLINE
void* void*
buf_buddy_alloc( buf_buddy_alloc(
......
...@@ -68,9 +68,13 @@ buf_buddy_get_slot( ...@@ -68,9 +68,13 @@ buf_buddy_get_slot(
/************************************************************************** /**************************************************************************
Allocate a block. The thread calling this function must hold Allocate a block. The thread calling this function must hold
buf_pool->mutex and must not hold buf_pool->zip_mutex or any block->mutex. buf_pool->mutex and must not hold buf_pool->zip_mutex or any
The buf_pool->mutex may only be released and reacquired if block->mutex. The buf_pool->mutex may only be released and reacquired
lru == BUF_BUDDY_USE_LRU. */ if lru == BUF_BUDDY_USE_LRU. This function should only be used for
allocating compressed page frames or control blocks (buf_page_t).
Allocated control blocks must be properly initialized immediately
after buf_buddy_alloc() has returned the memory, before releasing
buf_pool->mutex. */
UNIV_INLINE UNIV_INLINE
void* void*
buf_buddy_alloc( buf_buddy_alloc(
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment