summaryrefslogtreecommitdiff
path: root/storage/innobase/fut/fut0lst.cc
diff options
context:
space:
mode:
Diffstat (limited to 'storage/innobase/fut/fut0lst.cc')
-rw-r--r--storage/innobase/fut/fut0lst.cc175
1 files changed, 97 insertions, 78 deletions
diff --git a/storage/innobase/fut/fut0lst.cc b/storage/innobase/fut/fut0lst.cc
index 98f37be002a..a52027f28bc 100644
--- a/storage/innobase/fut/fut0lst.cc
+++ b/storage/innobase/fut/fut0lst.cc
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 1995, 2016, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2019, 2021, MariaDB Corporation.
+Copyright (c) 2019, 2022, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
@@ -38,9 +38,8 @@ Created 11/28/1995 Heikki Tuuri
static void flst_write_addr(const buf_block_t& block, byte *faddr,
uint32_t page, uint16_t boffset, mtr_t* mtr)
{
- ut_ad(mtr->memo_contains_page_flagged(faddr,
- MTR_MEMO_PAGE_X_FIX
- | MTR_MEMO_PAGE_SX_FIX));
+ ut_ad(mtr->memo_contains_page_flagged(faddr, MTR_MEMO_PAGE_X_FIX |
+ MTR_MEMO_PAGE_SX_FIX));
ut_a(page == FIL_NULL || boffset >= FIL_PAGE_DATA);
ut_a(ut_align_offset(faddr, srv_page_size) >= FIL_PAGE_DATA);
@@ -69,7 +68,7 @@ static void flst_write_addr(const buf_block_t& block, byte *faddr,
/** Write 2 null file addresses.
@param[in] b file page
-@param[in,out] addr file address to be zeroed out
+@param[in,out] addr file address to be zeroed out
@param[in,out] mtr mini-transaction */
static void flst_zero_both(const buf_block_t& b, byte *addr, mtr_t *mtr)
{
@@ -120,10 +119,11 @@ static void flst_add_to_empty(buf_block_t *base, uint16_t boffset,
@param[in] coffset byte offset of the insert position
@param[in,out] add block to be added
@param[in] aoffset byte offset of the block to be added
-@param[in,outr] mtr mini-transaction */
-static void flst_insert_after(buf_block_t *base, uint16_t boffset,
- buf_block_t *cur, uint16_t coffset,
- buf_block_t *add, uint16_t aoffset, mtr_t *mtr)
+@param[in,out] mtr mini-transaction */
+static dberr_t flst_insert_after(buf_block_t *base, uint16_t boffset,
+ buf_block_t *cur, uint16_t coffset,
+ buf_block_t *add, uint16_t aoffset,
+ mtr_t *mtr)
{
ut_ad(base != cur || boffset != coffset);
ut_ad(base != add || boffset != aoffset);
@@ -145,23 +145,25 @@ static void flst_insert_after(buf_block_t *base, uint16_t boffset,
flst_write_addr(*add, add->page.frame + aoffset + FLST_NEXT,
next_addr.page, next_addr.boffset, mtr);
+ dberr_t err= DB_SUCCESS;
+
if (next_addr.page == FIL_NULL)
flst_write_addr(*base, base->page.frame + boffset + FLST_LAST,
add->page.id().page_no(), aoffset, mtr);
- else
- {
- buf_block_t *block;
- if (flst_node_t *next= fut_get_ptr(add->page.id().space(), add->zip_size(),
- next_addr, RW_SX_LATCH, mtr, &block))
- flst_write_addr(*block, next + FLST_PREV,
- add->page.id().page_no(), aoffset, mtr);
- }
+ else if (buf_block_t *block=
+ buf_page_get_gen(page_id_t{add->page.id().space(), next_addr.page},
+ add->zip_size(), RW_SX_LATCH, nullptr,
+ BUF_GET_POSSIBLY_FREED, mtr, &err))
+ flst_write_addr(*block, block->page.frame +
+ next_addr.boffset + FLST_PREV,
+ add->page.id().page_no(), aoffset, mtr);
flst_write_addr(*cur, cur->page.frame + coffset + FLST_NEXT,
add->page.id().page_no(), aoffset, mtr);
byte *len= &base->page.frame[boffset + FLST_LEN];
mtr->write<4>(*base, len, mach_read_from_4(len) + 1);
+ return err;
}
/** Insert a node before another one.
@@ -171,10 +173,12 @@ static void flst_insert_after(buf_block_t *base, uint16_t boffset,
@param[in] coffset byte offset of the insert position
@param[in,out] add block to be added
@param[in] aoffset byte offset of the block to be added
-@param[in,outr] mtr mini-transaction */
-static void flst_insert_before(buf_block_t *base, uint16_t boffset,
- buf_block_t *cur, uint16_t coffset,
- buf_block_t *add, uint16_t aoffset, mtr_t *mtr)
+@param[in,out] mtr mini-transaction
+@return error code */
+static dberr_t flst_insert_before(buf_block_t *base, uint16_t boffset,
+ buf_block_t *cur, uint16_t coffset,
+ buf_block_t *add, uint16_t aoffset,
+ mtr_t *mtr)
{
ut_ad(base != cur || boffset != coffset);
ut_ad(base != add || boffset != aoffset);
@@ -194,25 +198,27 @@ static void flst_insert_before(buf_block_t *base, uint16_t boffset,
flst_write_addr(*add, add->page.frame + aoffset + FLST_PREV,
prev_addr.page, prev_addr.boffset, mtr);
flst_write_addr(*add, add->page.frame + aoffset + FLST_NEXT,
- cur->page.id().page_no(), coffset, mtr);
+ cur->page.id().page_no(), coffset, mtr);
+
+ dberr_t err= DB_SUCCESS;
if (prev_addr.page == FIL_NULL)
flst_write_addr(*base, base->page.frame + boffset + FLST_FIRST,
add->page.id().page_no(), aoffset, mtr);
- else
- {
- buf_block_t *block;
- if (flst_node_t *prev= fut_get_ptr(add->page.id().space(), add->zip_size(),
- prev_addr, RW_SX_LATCH, mtr, &block))
- flst_write_addr(*block, prev + FLST_NEXT,
- add->page.id().page_no(), aoffset, mtr);
- }
+ else if (buf_block_t *block=
+ buf_page_get_gen(page_id_t{add->page.id().space(), prev_addr.page},
+ add->zip_size(), RW_SX_LATCH, nullptr,
+ BUF_GET_POSSIBLY_FREED, mtr, &err))
+ flst_write_addr(*block, block->page.frame +
+ prev_addr.boffset + FLST_NEXT,
+ add->page.id().page_no(), aoffset, mtr);
flst_write_addr(*cur, cur->page.frame + coffset + FLST_PREV,
add->page.id().page_no(), aoffset, mtr);
byte *len= &base->page.frame[boffset + FLST_LEN];
mtr->write<4>(*base, len, mach_read_from_4(len) + 1);
+ return err;
}
/** Initialize a list base node.
@@ -234,8 +240,8 @@ void flst_init(const buf_block_t& block, byte *base, mtr_t *mtr)
@param[in,out] add block to be added
@param[in] aoffset byte offset of the node to be added
@param[in,outr] mtr mini-transaction */
-void flst_add_last(buf_block_t *base, uint16_t boffset,
- buf_block_t *add, uint16_t aoffset, mtr_t *mtr)
+dberr_t flst_add_last(buf_block_t *base, uint16_t boffset,
+ buf_block_t *add, uint16_t aoffset, mtr_t *mtr)
{
ut_ad(base != add || boffset != aoffset);
ut_ad(boffset < base->physical_size());
@@ -244,21 +250,23 @@ void flst_add_last(buf_block_t *base, uint16_t boffset,
MTR_MEMO_PAGE_SX_FIX));
ut_ad(mtr->memo_contains_flagged(add, MTR_MEMO_PAGE_X_FIX |
MTR_MEMO_PAGE_SX_FIX));
-
if (!flst_get_len(base->page.frame + boffset))
+ {
flst_add_to_empty(base, boffset, add, aoffset, mtr);
+ return DB_SUCCESS;
+ }
else
{
fil_addr_t addr= flst_get_last(base->page.frame + boffset);
buf_block_t *cur= add;
- const flst_node_t *c= addr.page == add->page.id().page_no()
- ? add->page.frame + addr.boffset
- : fut_get_ptr(add->page.id().space(), add->zip_size(), addr,
- RW_SX_LATCH, mtr, &cur);
- if (c)
- flst_insert_after(base, boffset, cur,
- static_cast<uint16_t>(c - cur->page.frame),
- add, aoffset, mtr);
+ 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;
+ return flst_insert_after(base, boffset, cur, addr.boffset,
+ add, aoffset, mtr);
}
}
@@ -267,9 +275,10 @@ void flst_add_last(buf_block_t *base, uint16_t boffset,
@param[in] boffset byte offset of the base node
@param[in,out] add block to be added
@param[in] aoffset byte offset of the node to be added
-@param[in,outr] mtr mini-transaction */
-void flst_add_first(buf_block_t *base, uint16_t boffset,
- buf_block_t *add, uint16_t aoffset, mtr_t *mtr)
+@param[in,out] mtr mini-transaction
+@return error code */
+dberr_t flst_add_first(buf_block_t *base, uint16_t boffset,
+ buf_block_t *add, uint16_t aoffset, mtr_t *mtr)
{
ut_ad(base != add || boffset != aoffset);
ut_ad(boffset < base->physical_size());
@@ -280,19 +289,22 @@ void flst_add_first(buf_block_t *base, uint16_t boffset,
MTR_MEMO_PAGE_SX_FIX));
if (!flst_get_len(base->page.frame + boffset))
+ {
flst_add_to_empty(base, boffset, add, aoffset, mtr);
+ return DB_SUCCESS;
+ }
else
{
fil_addr_t addr= flst_get_first(base->page.frame + boffset);
buf_block_t *cur= add;
- const flst_node_t *c= addr.page == add->page.id().page_no()
- ? add->page.frame + addr.boffset
- : fut_get_ptr(add->page.id().space(), add->zip_size(), addr,
- RW_SX_LATCH, mtr, &cur);
- if (c)
- flst_insert_before(base, boffset, cur,
- static_cast<uint16_t>(c - cur->page.frame),
- add, aoffset, mtr);
+ 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;
+ return flst_insert_before(base, boffset, cur, addr.boffset,
+ add, aoffset, mtr);
}
}
@@ -301,9 +313,10 @@ void flst_add_first(buf_block_t *base, uint16_t boffset,
@param[in] boffset byte offset of the base node
@param[in,out] cur block to be removed
@param[in] coffset byte offset of the current record to be removed
-@param[in,outr] mtr mini-transaction */
-void flst_remove(buf_block_t *base, uint16_t boffset,
- buf_block_t *cur, uint16_t coffset, mtr_t *mtr)
+@param[in,out] mtr mini-transaction
+@return error code */
+dberr_t flst_remove(buf_block_t *base, uint16_t boffset,
+ buf_block_t *cur, uint16_t coffset, mtr_t *mtr)
{
ut_ad(boffset < base->physical_size());
ut_ad(coffset < cur->physical_size());
@@ -314,18 +327,19 @@ void flst_remove(buf_block_t *base, uint16_t boffset,
const fil_addr_t prev_addr= flst_get_prev_addr(cur->page.frame + coffset);
const fil_addr_t next_addr= flst_get_next_addr(cur->page.frame + coffset);
+ dberr_t err= DB_SUCCESS;
if (prev_addr.page == FIL_NULL)
flst_write_addr(*base, base->page.frame + boffset + FLST_FIRST,
next_addr.page, next_addr.boffset, mtr);
else
{
- buf_block_t *block= cur;
- if (flst_node_t *prev= prev_addr.page == cur->page.id().page_no()
- ? cur->page.frame + prev_addr.boffset
- : fut_get_ptr(cur->page.id().space(), cur->zip_size(), prev_addr,
- RW_SX_LATCH, mtr, &block))
- flst_write_addr(*block, prev + FLST_NEXT,
+ buf_block_t *b= cur;
+ if (prev_addr.page == b->page.id().page_no() ||
+ (b= buf_page_get_gen(page_id_t(b->page.id().space(), prev_addr.page),
+ b->zip_size(), RW_SX_LATCH, nullptr,
+ BUF_GET_POSSIBLY_FREED, mtr, &err)))
+ flst_write_addr(*b, b->page.frame + prev_addr.boffset + FLST_NEXT,
next_addr.page, next_addr.boffset, mtr);
}
@@ -334,18 +348,23 @@ void flst_remove(buf_block_t *base, uint16_t boffset,
prev_addr.page, prev_addr.boffset, mtr);
else
{
- buf_block_t *block= cur;
- if (flst_node_t *next= next_addr.page == cur->page.id().page_no()
- ? cur->page.frame + next_addr.boffset
- : fut_get_ptr(cur->page.id().space(), cur->zip_size(), next_addr,
- RW_SX_LATCH, mtr, &block))
- flst_write_addr(*block, next + FLST_PREV,
+ 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)))
+ 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;
}
byte *len= &base->page.frame[boffset + FLST_LEN];
- ut_ad(mach_read_from_4(len) > 0);
+ if (UNIV_UNLIKELY(!mach_read_from_4(len)))
+ return DB_CORRUPTION;
mtr->write<4>(*base, len, mach_read_from_4(len) - 1);
+ return err;
}
#ifdef UNIV_DEBUG
@@ -369,11 +388,11 @@ void flst_validate(const buf_block_t *base, uint16_t boffset, mtr_t *mtr)
for (uint32_t i= len; i--; )
{
mtr2.start();
- const flst_node_t *node= fut_get_ptr(base->page.id().space(),
- base->zip_size(), addr,
- RW_SX_LATCH, &mtr2);
- ut_ad(node);
- addr= flst_get_next_addr(node);
+ const buf_block_t *b=
+ buf_page_get_gen(page_id_t(base->page.id().space(), addr.page),
+ base->zip_size(), RW_SX_LATCH, nullptr, BUF_GET, mtr);
+ ut_ad(b);
+ addr= flst_get_next_addr(b->page.frame + addr.boffset);
mtr2.commit();
}
@@ -384,11 +403,11 @@ void flst_validate(const buf_block_t *base, uint16_t boffset, mtr_t *mtr)
for (uint32_t i= len; i--; )
{
mtr2.start();
- const flst_node_t *node= fut_get_ptr(base->page.id().space(),
- base->zip_size(), addr,
- RW_SX_LATCH, &mtr2);
- ut_ad(node);
- addr= flst_get_prev_addr(node);
+ const buf_block_t *b=
+ buf_page_get_gen(page_id_t(base->page.id().space(), addr.page),
+ base->zip_size(), RW_SX_LATCH, nullptr, BUF_GET, mtr);
+ ut_ad(b);
+ addr= flst_get_prev_addr(b->page.frame + addr.boffset);
mtr2.commit();
}