MDEV-38419: Fix some clang-21 -fsanitize=memory failures

fil_space_t::free_page(): Turn a parameter into a template parameter,
and remove some duplicated code. This fixes an error that was flagged
by clang++-21 -fsanitize=memory in buf_page_create().

fseg_create(): Merge the parameter reserved_extent to n_reserved.
This fixes an error about n_reserved being uninitialized.

fseg_alloc_free_page_low(): Simplify a debug assertion.

flst_add_last(), flst_remove(): Reduce the scope of a conditionally
initialized variable.

Reviewed by: Thirunarayanan Balathandayuthapani
This commit is contained in:
Marko Mäkelä 2026-01-02 09:25:46 +02:00
commit c7313daf8c
5 changed files with 41 additions and 34 deletions

View file

@ -3474,7 +3474,7 @@ buf_block_t*
buf_page_create(fil_space_t *space, uint32_t offset,
ulint zip_size, mtr_t *mtr, buf_block_t *free_block) noexcept
{
space->free_page(offset, false);
space->free_page<false>(offset);
return buf_page_create_low({space->id, offset}, zip_size, mtr, free_block);
}

View file

@ -1683,8 +1683,7 @@ fseg_create(fil_space_t *space, ulint byte_offset, mtr_t *mtr, dberr_t *err,
{
fseg_inode_t* inode;
ib_id_t seg_id;
uint32_t n_reserved;
bool reserved_extent = false;
uint32_t n_reserved = 0;
DBUG_ENTER("fseg_create");
@ -1712,16 +1711,16 @@ inode_alloc:
if (!inode) {
block = nullptr;
reserve_extent:
if (!has_done_reservation && !reserved_extent) {
if (!has_done_reservation && !n_reserved) {
*err = fsp_reserve_free_extents(&n_reserved, space, 2,
FSP_NORMAL, mtr);
if (UNIV_UNLIKELY(*err != DB_SUCCESS)) {
DBUG_RETURN(nullptr);
}
ut_ad(n_reserved > 0);
/* Extents reserved successfully. So
try allocating the page or inode */
reserved_extent = true;
if (inode) {
goto page_alloc;
}
@ -1791,7 +1790,8 @@ page_alloc:
+ block->page.frame, space->id);
funct_exit:
if (!has_done_reservation && reserved_extent) {
if (n_reserved) {
ut_ad(!has_done_reservation);
space->release_free_extents(n_reserved);
}
@ -2173,8 +2173,6 @@ take_hinted_page:
buf_block_t* block = fsp_alloc_free_page(
space, hint, mtr, init_mtr, err);
ut_ad(block || !has_done_reservation || *err);
if (block) {
/* Put the page in the fragment page array of the
segment */
@ -2187,6 +2185,8 @@ take_hinted_page:
fseg_set_nth_frag_page_no(
seg_inode, iblock, n,
block->page.id().page_no(), mtr);
} else {
ut_ad(*err != DB_SUCCESS);
}
/* fsp_alloc_free_page() invoked fsp_init_file_page()

View file

@ -281,12 +281,15 @@ dberr_t flst_add_last(buf_block_t *base, uint16_t boffset,
return DB_CORRUPTION;
buf_block_t *cur= add;
dberr_t err;
if (addr.page != add->page.id().page_no() &&
!(cur= buf_page_get_gen(page_id_t{add->page.id().space(), addr.page},
add->zip_size(), RW_SX_LATCH, nullptr,
BUF_GET_POSSIBLY_FREED, mtr, &err)))
return err;
if (addr.page != add->page.id().page_no())
{
dberr_t err;
cur= buf_page_get_gen(page_id_t{add->page.id().space(), addr.page},
add->zip_size(), RW_SX_LATCH, nullptr,
BUF_GET_POSSIBLY_FREED, mtr, &err);
if (!cur)
return err;
}
return flst_insert_after(base, boffset, cur, addr.boffset,
add, aoffset, limit, mtr);
}
@ -382,16 +385,21 @@ dberr_t flst_remove(buf_block_t *base, uint16_t boffset,
prev_addr.page, prev_addr.boffset, mtr);
else
{
dberr_t err2;
if (next_addr.page == cur->page.id().page_no() ||
(cur= buf_page_get_gen(page_id_t(cur->page.id().space(),
next_addr.page),
cur->zip_size(), RW_SX_LATCH, nullptr,
BUF_GET_POSSIBLY_FREED, mtr, &err2)))
if (next_addr.page == cur->page.id().page_no())
write_addr:
flst_write_addr(*cur, cur->page.frame + next_addr.boffset + FLST_PREV,
prev_addr.page, prev_addr.boffset, mtr);
else if (err == DB_SUCCESS)
err= err2;
else
{
dberr_t err2;
cur= buf_page_get_gen(page_id_t(cur->page.id().space(), next_addr.page),
cur->zip_size(), RW_SX_LATCH, nullptr,
BUF_GET_POSSIBLY_FREED, mtr, &err2);
if (cur)
goto write_addr;
if (err == DB_SUCCESS)
err= err2;
}
}
byte *len= &base->page.frame[boffset + FLST_LEN];

View file

@ -995,19 +995,16 @@ public:
@retval nullptr if the tablespace is missing or inaccessible */
static fil_space_t *get_for_write(ulint id) noexcept;
/** Add/remove the free page in the freed ranges list.
@param[in] offset page number to be added
@param[in] free true if page to be freed */
void free_page(uint32_t offset, bool add=true)
/** Add/remove a page in freed_ranges.
@tparam add true=add, false=remove
@param offset page number */
template<bool add=true> void free_page(uint32_t offset) noexcept
{
std::lock_guard<std::mutex> freed_lock(freed_range_mutex);
if (add)
return freed_ranges.add_value(offset);
if (freed_ranges.empty())
return;
return freed_ranges.remove_value(offset);
freed_ranges.add_value(offset);
else
freed_ranges.remove_value(offset);
}
/** Add the range of freed pages */

View file

@ -2358,8 +2358,10 @@ static void store_freed_or_init_rec(page_id_t page_id, bool freed)
space= fil_system.sys_space;
else
space= fil_space_get(space_id);
space->free_page(page_no, freed);
if (freed)
space->free_page<true>(page_no);
else
space->free_page<false>(page_no);
return;
}