diff options
Diffstat (limited to 'storage/innobase/fil/fil0crypt.cc')
-rw-r--r-- | storage/innobase/fil/fil0crypt.cc | 90 |
1 files changed, 34 insertions, 56 deletions
diff --git a/storage/innobase/fil/fil0crypt.cc b/storage/innobase/fil/fil0crypt.cc index 663fc60aef8..6d30af25b3c 100644 --- a/storage/innobase/fil/fil0crypt.cc +++ b/storage/innobase/fil/fil0crypt.cc @@ -914,43 +914,32 @@ fil_crypt_needs_rotation( /** Read page 0 and possible crypt data from there. @param[in,out] space Tablespace */ -static inline -void -fil_crypt_read_crypt_data(fil_space_t* space) +static inline void fil_crypt_read_crypt_data(fil_space_t *space) { - if (space->crypt_data || space->size || !space->get_size()) { - /* The encryption metadata has already been read, or - the tablespace is not encrypted and the file has been - opened already, or the file cannot be accessed, - likely due to a concurrent DROP - (possibly as part of TRUNCATE or ALTER TABLE). - FIXME: The file can become unaccessible any time - after this check! We should really remove this - function and instead make crypt_data an integral - part of fil_space_t. */ - return; - } + if (space->crypt_data || space->size || !space->get_size()) + /* The encryption metadata has already been read, or the + tablespace is not encrypted and the file has been opened already, + or the file cannot be accessed, likely due to a concurrent DROP + (possibly as part of TRUNCATE or ALTER TABLE). + + FIXME: The file can become unaccessible any time after this check! + We should really remove this function and instead make crypt_data + an integral part of fil_space_t. */ + return; - const ulint zip_size = space->zip_size(); - mtr_t mtr; - mtr.start(); - if (buf_block_t* block = buf_page_get_gen(page_id_t(space->id, 0), - zip_size, RW_S_LATCH, - nullptr, - BUF_GET_POSSIBLY_FREED, - &mtr)) { - if (block->page.is_freed()) { - goto func_exit; - } - mysql_mutex_lock(&fil_system.mutex); - if (!space->crypt_data && !space->is_stopping()) { - space->crypt_data = fil_space_read_crypt_data( - zip_size, block->page.frame); - } - mysql_mutex_unlock(&fil_system.mutex); - } -func_exit: - mtr.commit(); + const ulint zip_size= space->zip_size(); + mtr_t mtr; + mtr.start(); + if (buf_block_t* b= buf_page_get_gen(page_id_t{space->id, 0}, zip_size, + RW_S_LATCH, nullptr, + BUF_GET_POSSIBLY_FREED, &mtr)) + { + mysql_mutex_lock(&fil_system.mutex); + if (!space->crypt_data && !space->is_stopping()) + space->crypt_data= fil_space_read_crypt_data(zip_size, b->page.frame); + mysql_mutex_unlock(&fil_system.mutex); + } + mtr.commit(); } /** Start encrypting a space @@ -997,15 +986,9 @@ func_exit: mtr.start(); /* 2 - get page 0 */ - dberr_t err = DB_SUCCESS; if (buf_block_t* block = buf_page_get_gen( page_id_t(space->id, 0), space->zip_size(), - RW_X_LATCH, NULL, BUF_GET_POSSIBLY_FREED, - &mtr, &err)) { - if (block->page.is_freed()) { - goto abort; - } - + RW_X_LATCH, NULL, BUF_GET_POSSIBLY_FREED, &mtr)) { crypt_data->type = CRYPT_SCHEME_1; crypt_data->min_key_version = 0; // all pages are unencrypted crypt_data->rotate_state.start_time = time(0); @@ -1716,7 +1699,8 @@ fil_crypt_get_page_throttle( return NULL; } - if (fseg_page_is_free(space, state->offset)) { + if (DB_SUCCESS_LOCKED_REC + != fseg_page_is_allocated(space, state->offset)) { /* page is already freed */ return NULL; } @@ -1794,10 +1778,7 @@ fil_crypt_rotate_page( const lsn_t block_lsn = mach_read_from_8(FIL_PAGE_LSN + frame); uint kv = buf_page_get_key_version(frame, space->flags); - if (block->page.is_freed()) { - /* Do not modify freed pages to avoid an assertion - failure on recovery.*/ - } else if (block->page.oldest_modification() > 1) { + if (block->page.oldest_modification() > 1) { /* Do not unnecessarily touch pages that are already dirty. */ } else if (space->is_stopping()) { @@ -1809,11 +1790,11 @@ fil_crypt_rotate_page( allocated. Because key rotation is accessing pages in a pattern that is unlike the normal B-tree and undo log access pattern, we cannot - invoke fseg_page_is_free() here, because that + invoke fseg_page_is_allocated() here, because that could result in a deadlock. If we invoked - fseg_page_is_free() and released the + fseg_page_is_allocated() and released the tablespace latch before acquiring block->lock, - then the fseg_page_is_free() information + then the fseg_page_is_allocated() information could be stale already. */ /* If the data file was originally created @@ -1872,8 +1853,7 @@ fil_crypt_rotate_page( /* If block read failed mtr memo and log should be empty. */ ut_ad(!mtr.has_modifications()); ut_ad(!mtr.is_dirty()); - ut_ad(mtr.get_memo()->size() == 0); - ut_ad(mtr.get_log()->size() == 0); + ut_ad(mtr.is_empty()); mtr.commit(); } @@ -1974,10 +1954,8 @@ fil_crypt_flush_space( if (buf_block_t* block = buf_page_get_gen( page_id_t(space->id, 0), space->zip_size(), RW_X_LATCH, NULL, BUF_GET_POSSIBLY_FREED, &mtr)) { - if (!block->page.is_freed()) { - mtr.set_named_space(space); - crypt_data->write_page0(block, &mtr); - } + mtr.set_named_space(space); + crypt_data->write_page0(block, &mtr); } mtr.commit(); |