mirror of
https://github.com/MariaDB/server.git
synced 2025-12-24 11:21:21 +03:00
MDEV-8272: Encryption performance: Reduce the number of unused memcpy's
Removed memcpy's on cases when page is not encrypted and make sure we use the correct buffer for reading/writing.
This commit is contained in:
@@ -5714,30 +5714,31 @@ Encrypts a buffer page right before it's flushed to disk
|
||||
byte*
|
||||
buf_page_encrypt_before_write(
|
||||
/*==========================*/
|
||||
buf_page_t* bpage, /*!< in/out: buffer page to be flushed */
|
||||
const byte* src_frame, /*!< in: src frame */
|
||||
ulint space_id) /*!< in: space id */
|
||||
buf_page_t* bpage, /*!< in/out: buffer page to be flushed */
|
||||
byte* src_frame, /*!< in: src frame */
|
||||
ulint space_id) /*!< in: space id */
|
||||
{
|
||||
fil_space_crypt_t* crypt_data = fil_space_get_crypt_data(space_id);
|
||||
ulint zip_size = buf_page_get_zip_size(bpage);
|
||||
ulint page_size = (zip_size) ? zip_size : UNIV_PAGE_SIZE;
|
||||
buf_pool_t* buf_pool = buf_pool_from_bpage(bpage);
|
||||
bool page_compressed = fil_space_is_page_compressed(bpage->space);
|
||||
bpage->real_size = UNIV_PAGE_SIZE;
|
||||
bool encrypted = true;
|
||||
|
||||
bpage->real_size = UNIV_PAGE_SIZE;
|
||||
|
||||
fil_page_type_validate(src_frame);
|
||||
|
||||
if (bpage->offset == 0) {
|
||||
/* Page 0 of a tablespace is not encrypted/compressed */
|
||||
ut_ad(bpage->key_version == 0);
|
||||
return const_cast<byte*>(src_frame);
|
||||
return src_frame;
|
||||
}
|
||||
|
||||
if (bpage->space == TRX_SYS_SPACE && bpage->offset == TRX_SYS_PAGE_NO) {
|
||||
/* don't encrypt/compress page as it contains address to dblwr buffer */
|
||||
bpage->key_version = 0;
|
||||
return const_cast<byte*>(src_frame);
|
||||
return src_frame;
|
||||
}
|
||||
|
||||
if (crypt_data != NULL && crypt_data->encryption == FIL_SPACE_ENCRYPTION_OFF) {
|
||||
@@ -5759,31 +5760,35 @@ buf_page_encrypt_before_write(
|
||||
|
||||
if (!encrypted && !page_compressed) {
|
||||
/* No need to encrypt or page compress the page */
|
||||
return const_cast<byte*>(src_frame);
|
||||
return src_frame;
|
||||
}
|
||||
|
||||
/* Find free slot from temporary memory array */
|
||||
buf_tmp_buffer_t* slot = buf_pool_reserve_tmp_slot(buf_pool, page_compressed);
|
||||
slot->out_buf = NULL;
|
||||
bpage->slot = slot;
|
||||
|
||||
byte *dst_frame = bpage->slot->out_buf = slot->crypt_buf;
|
||||
byte *dst_frame = slot->crypt_buf;
|
||||
|
||||
if (!page_compressed) {
|
||||
/* Encrypt page content */
|
||||
fil_space_encrypt(bpage->space,
|
||||
bpage->offset,
|
||||
bpage->newest_modification,
|
||||
src_frame,
|
||||
zip_size,
|
||||
dst_frame);
|
||||
byte* tmp = fil_space_encrypt(bpage->space,
|
||||
bpage->offset,
|
||||
bpage->newest_modification,
|
||||
src_frame,
|
||||
zip_size,
|
||||
dst_frame);
|
||||
|
||||
unsigned key_version =
|
||||
mach_read_from_4(dst_frame + FIL_PAGE_FILE_FLUSH_LSN_OR_KEY_VERSION);
|
||||
ut_ad(key_version == 0 || key_version >= bpage->key_version);
|
||||
bpage->key_version = key_version;
|
||||
bpage->real_size = page_size;
|
||||
slot->out_buf = dst_frame = tmp;
|
||||
|
||||
fil_page_type_validate(dst_frame);
|
||||
#ifdef UNIV_DEBUG
|
||||
fil_page_type_validate(tmp);
|
||||
#endif
|
||||
|
||||
} else {
|
||||
/* First we compress the page content */
|
||||
@@ -5803,22 +5808,27 @@ buf_page_encrypt_before_write(
|
||||
|
||||
bpage->real_size = out_len;
|
||||
|
||||
#ifdef UNIV_DEBUG
|
||||
fil_page_type_validate(tmp);
|
||||
#endif
|
||||
|
||||
if(encrypted) {
|
||||
|
||||
/* And then we encrypt the page content */
|
||||
fil_space_encrypt(bpage->space,
|
||||
bpage->offset,
|
||||
bpage->newest_modification,
|
||||
tmp,
|
||||
zip_size,
|
||||
dst_frame);
|
||||
} else {
|
||||
bpage->slot->out_buf = dst_frame = tmp;
|
||||
tmp = fil_space_encrypt(bpage->space,
|
||||
bpage->offset,
|
||||
bpage->newest_modification,
|
||||
tmp,
|
||||
zip_size,
|
||||
dst_frame);
|
||||
}
|
||||
|
||||
slot->out_buf = dst_frame = tmp;
|
||||
}
|
||||
|
||||
#ifdef UNIV_DEBUG
|
||||
fil_page_type_validate(dst_frame);
|
||||
#endif
|
||||
|
||||
// return dst_frame which will be written
|
||||
return dst_frame;
|
||||
@@ -5830,7 +5840,7 @@ Decrypt page after it has been read from disk
|
||||
ibool
|
||||
buf_page_decrypt_after_read(
|
||||
/*========================*/
|
||||
buf_page_t* bpage) /*!< in/out: buffer page read from disk */
|
||||
buf_page_t* bpage) /*!< in/out: buffer page read from disk */
|
||||
{
|
||||
ulint zip_size = buf_page_get_zip_size(bpage);
|
||||
ulint size = (zip_size) ? zip_size : UNIV_PAGE_SIZE;
|
||||
@@ -5855,8 +5865,11 @@ buf_page_decrypt_after_read(
|
||||
/* Find free slot from temporary memory array */
|
||||
buf_tmp_buffer_t* slot = buf_pool_reserve_tmp_slot(buf_pool, page_compressed);
|
||||
|
||||
#ifdef UNIV_DEBUG
|
||||
fil_page_type_validate(dst_frame);
|
||||
#endif
|
||||
|
||||
/* decompress using comp_buf to dst_frame */
|
||||
fil_decompress_page(slot->comp_buf,
|
||||
dst_frame,
|
||||
size,
|
||||
@@ -5866,24 +5879,27 @@ buf_page_decrypt_after_read(
|
||||
slot->reserved = false;
|
||||
key_version = 0;
|
||||
|
||||
#ifdef UNIV_DEBUG
|
||||
fil_page_type_validate(dst_frame);
|
||||
#endif
|
||||
} else {
|
||||
buf_tmp_buffer_t* slot = NULL;
|
||||
|
||||
if (key_version) {
|
||||
/* Find free slot from temporary memory array */
|
||||
slot = buf_pool_reserve_tmp_slot(buf_pool, page_compressed);
|
||||
memcpy(slot->crypt_buf, dst_frame, size);
|
||||
|
||||
#ifdef UNIV_DEBUG
|
||||
fil_page_type_validate(dst_frame);
|
||||
fil_page_type_validate(slot->crypt_buf);
|
||||
/* decrypt from crypt_buf to dst_frame */
|
||||
#endif
|
||||
/* decrypt using crypt_buf to dst_frame */
|
||||
fil_space_decrypt(bpage->space,
|
||||
slot->crypt_buf,
|
||||
size,
|
||||
dst_frame);
|
||||
slot->crypt_buf,
|
||||
size,
|
||||
dst_frame);
|
||||
#ifdef UNIV_DEBUG
|
||||
fil_page_type_validate(dst_frame);
|
||||
fil_page_type_validate(slot->crypt_buf);
|
||||
#endif
|
||||
}
|
||||
|
||||
if (page_compressed_encrypted) {
|
||||
@@ -5894,13 +5910,16 @@ buf_page_decrypt_after_read(
|
||||
#ifdef UNIV_DEBUG
|
||||
fil_page_type_validate(dst_frame);
|
||||
#endif
|
||||
/* decompress using comp_buf to dst_frame */
|
||||
fil_decompress_page(slot->comp_buf,
|
||||
dst_frame,
|
||||
size,
|
||||
&bpage->write_size);
|
||||
}
|
||||
|
||||
#ifdef UNIV_DEBUG
|
||||
fil_page_type_validate(dst_frame);
|
||||
#endif
|
||||
|
||||
/* Mark this slot as free */
|
||||
if (slot) {
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*****************************************************************************
|
||||
|
||||
Copyright (c) 1995, 2014, Oracle and/or its affiliates. All Rights Reserved.
|
||||
Copyright (c) 2013, 2014, SkySQL Ab. All Rights Reserved.
|
||||
Copyright (c) 2013, 2015, MariaDB Corporation. All Rights Reserved.
|
||||
|
||||
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
|
||||
@@ -391,11 +391,11 @@ buf_dblwr_init_or_load_pages(
|
||||
doublewrite = read_buf + TRX_SYS_DOUBLEWRITE;
|
||||
|
||||
if (mach_read_from_4(read_buf + FIL_PAGE_FILE_FLUSH_LSN_OR_KEY_VERSION) != 0) {
|
||||
fil_space_decrypt((ulint)TRX_SYS_SPACE,
|
||||
read_buf,
|
||||
UNIV_PAGE_SIZE, /* page size */
|
||||
read_buf + UNIV_PAGE_SIZE);
|
||||
doublewrite = read_buf + UNIV_PAGE_SIZE + TRX_SYS_DOUBLEWRITE;
|
||||
byte* tmp = fil_space_decrypt((ulint)TRX_SYS_SPACE,
|
||||
read_buf + UNIV_PAGE_SIZE,
|
||||
UNIV_PAGE_SIZE, /* page size */
|
||||
read_buf);
|
||||
doublewrite = tmp + TRX_SYS_DOUBLEWRITE;
|
||||
}
|
||||
|
||||
if (mach_read_from_4(doublewrite + TRX_SYS_DOUBLEWRITE_MAGIC)
|
||||
|
||||
@@ -545,13 +545,13 @@ fil_space_clear_crypt_data(
|
||||
/******************************************************************
|
||||
Encrypt a page */
|
||||
UNIV_INTERN
|
||||
void
|
||||
byte*
|
||||
fil_space_encrypt(
|
||||
/*==============*/
|
||||
ulint space, /*!< in: Space id */
|
||||
ulint offset, /*!< in: Page offset */
|
||||
lsn_t lsn, /*!< in: lsn */
|
||||
const byte* src_frame, /*!< in: Source page to be encrypted */
|
||||
byte* src_frame, /*!< in: Source page to be encrypted */
|
||||
ulint zip_size, /*!< in: compressed size if
|
||||
row_format compressed */
|
||||
byte* dst_frame) /*!< in: outbut buffer */
|
||||
@@ -566,18 +566,14 @@ fil_space_encrypt(
|
||||
|| orig_page_type==FIL_PAGE_TYPE_XDES) {
|
||||
/* File space header or extent descriptor do not need to be
|
||||
encrypted. */
|
||||
//TODO: is this really needed ?
|
||||
memcpy(dst_frame, src_frame, page_size);
|
||||
return;
|
||||
return src_frame;
|
||||
}
|
||||
|
||||
/* Get crypt data from file space */
|
||||
crypt_data = fil_space_get_crypt_data(space);
|
||||
|
||||
if (crypt_data == NULL) {
|
||||
//TODO: Is this really needed ?
|
||||
memcpy(dst_frame, src_frame, page_size);
|
||||
return;
|
||||
return src_frame;
|
||||
}
|
||||
|
||||
ut_ad(crypt_data->encryption != FIL_SPACE_ENCRYPTION_OFF);
|
||||
@@ -663,6 +659,8 @@ fil_space_encrypt(
|
||||
mach_write_to_4(dst_frame + FIL_PAGE_FILE_FLUSH_LSN_OR_KEY_VERSION + 4, checksum);
|
||||
|
||||
srv_stats.pages_encrypted.inc();
|
||||
|
||||
return dst_frame;
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
@@ -693,24 +691,22 @@ fil_space_check_encryption_read(
|
||||
|
||||
/******************************************************************
|
||||
Decrypt a page
|
||||
@return true if page was encrypted */
|
||||
@return true if page decrypted, false if not.*/
|
||||
UNIV_INTERN
|
||||
bool
|
||||
fil_space_decrypt(
|
||||
/*==============*/
|
||||
fil_space_crypt_t* crypt_data, /*!< in: crypt data */
|
||||
const byte* src_frame, /*!< in: input buffer */
|
||||
byte* tmp_frame, /*!< in: temporary buffer */
|
||||
ulint page_size, /*!< in: page size */
|
||||
byte* dst_frame) /*!< out: output buffer */
|
||||
byte* src_frame) /*!< in:out: page buffer */
|
||||
{
|
||||
ulint page_type = mach_read_from_2(src_frame+FIL_PAGE_TYPE);
|
||||
uint key_version = mach_read_from_4(src_frame + FIL_PAGE_FILE_FLUSH_LSN_OR_KEY_VERSION);
|
||||
bool page_compressed = (page_type == FIL_PAGE_PAGE_COMPRESSED_ENCRYPTED);
|
||||
|
||||
if (key_version == ENCRYPTION_KEY_NOT_ENCRYPTED) {
|
||||
//TODO: is this really needed ?
|
||||
memcpy(dst_frame, src_frame, page_size);
|
||||
return false; /* page not decrypted */
|
||||
return false;
|
||||
}
|
||||
|
||||
ut_ad(crypt_data->encryption != FIL_SPACE_ENCRYPTION_OFF);
|
||||
@@ -723,11 +719,11 @@ fil_space_decrypt(
|
||||
ib_uint64_t lsn = mach_read_from_8(src_frame + FIL_PAGE_LSN);
|
||||
|
||||
/* Copy FIL page header, it is not encrypted */
|
||||
memcpy(dst_frame, src_frame, FIL_PAGE_DATA);
|
||||
memcpy(tmp_frame, src_frame, FIL_PAGE_DATA);
|
||||
|
||||
/* Calculate the offset where decryption starts */
|
||||
const byte* src = src_frame + FIL_PAGE_DATA;
|
||||
byte* dst = dst_frame + FIL_PAGE_DATA;
|
||||
byte* dst = tmp_frame + FIL_PAGE_DATA;
|
||||
uint32 dstlen = 0;
|
||||
ulint srclen = page_size - (FIL_PAGE_DATA + FIL_PAGE_DATA_END);
|
||||
|
||||
@@ -751,12 +747,12 @@ fil_space_decrypt(
|
||||
to sector boundary is written. */
|
||||
if (!page_compressed) {
|
||||
/* Copy FIL trailer */
|
||||
memcpy(dst_frame + page_size - FIL_PAGE_DATA_END,
|
||||
memcpy(tmp_frame + page_size - FIL_PAGE_DATA_END,
|
||||
src_frame + page_size - FIL_PAGE_DATA_END,
|
||||
FIL_PAGE_DATA_END);
|
||||
|
||||
// clear key-version & crypt-checksum from dst
|
||||
memset(dst_frame + FIL_PAGE_FILE_FLUSH_LSN_OR_KEY_VERSION, 0, 8);
|
||||
memset(tmp_frame + FIL_PAGE_FILE_FLUSH_LSN_OR_KEY_VERSION, 0, 8);
|
||||
}
|
||||
|
||||
srv_stats.pages_decrypted.inc();
|
||||
@@ -765,18 +761,31 @@ fil_space_decrypt(
|
||||
}
|
||||
|
||||
/******************************************************************
|
||||
Decrypt a page */
|
||||
Decrypt a page
|
||||
@return encrypted page, or original not encrypted page if encryption is
|
||||
not needed. */
|
||||
UNIV_INTERN
|
||||
void
|
||||
byte*
|
||||
fil_space_decrypt(
|
||||
/*==============*/
|
||||
ulint space, /*!< in: Fil space id */
|
||||
const byte* src_frame, /*!< in: input buffer */
|
||||
byte* tmp_frame, /*!< in: temporary buffer */
|
||||
ulint page_size, /*!< in: page size */
|
||||
byte* dst_frame) /*!< out: output buffer */
|
||||
byte* src_frame) /*!< in/out: page buffer */
|
||||
{
|
||||
fil_space_decrypt(fil_space_get_crypt_data(space),
|
||||
src_frame, page_size, dst_frame);
|
||||
bool encrypted = fil_space_decrypt(
|
||||
fil_space_get_crypt_data(space),
|
||||
tmp_frame,
|
||||
page_size,
|
||||
src_frame);
|
||||
|
||||
if (encrypted) {
|
||||
/* Copy the decrypted page back to page buffer, not
|
||||
really any other options. */
|
||||
memcpy(src_frame, tmp_frame, page_size);
|
||||
}
|
||||
|
||||
return src_frame;
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
|
||||
@@ -6410,14 +6410,19 @@ fil_iterate(
|
||||
for (ulint i = 0; i < n_pages_read; ++i) {
|
||||
|
||||
if (iter.crypt_data != NULL) {
|
||||
ulint size = iter.page_size;
|
||||
bool decrypted = fil_space_decrypt(
|
||||
iter.crypt_data,
|
||||
readptr + i * iter.page_size, // src
|
||||
iter.page_size,
|
||||
io_buffer + i * iter.page_size); // dst
|
||||
iter.crypt_data,
|
||||
io_buffer + i * size, //dst
|
||||
iter.page_size,
|
||||
readptr + i * size); // src
|
||||
|
||||
if (decrypted) {
|
||||
/* write back unencrypted page */
|
||||
updated = true;
|
||||
} else {
|
||||
/* TODO: remove unnecessary memcpy's */
|
||||
memcpy(io_buffer + i * size, readptr + i * size, size);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1449,9 +1449,9 @@ UNIV_INTERN
|
||||
byte*
|
||||
buf_page_encrypt_before_write(
|
||||
/*==========================*/
|
||||
buf_page_t* page, /*!< in/out: buffer page to be flushed */
|
||||
const byte* frame,
|
||||
ulint space_id);
|
||||
buf_page_t* page, /*!< in/out: buffer page to be flushed */
|
||||
byte* frame, /*!< in: src frame */
|
||||
ulint space_id); /*!< in: space id */
|
||||
|
||||
/**********************************************************************
|
||||
The hook that is called after page is written to disk.
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*****************************************************************************
|
||||
|
||||
Copyright (C) 2013, 2015, Google Inc. All Rights Reserved.
|
||||
Copyright (c) 2015, MariaDB Corporation.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify it under
|
||||
@@ -197,43 +197,45 @@ bool
|
||||
fil_space_check_encryption_read(
|
||||
/*============================*/
|
||||
ulint space); /*!< in: tablespace id */
|
||||
|
||||
/*********************************************************************
|
||||
Encrypt buffer page */
|
||||
UNIV_INTERN
|
||||
void
|
||||
fil_space_encrypt(
|
||||
/*==============*/
|
||||
ulint space, /*!< in: tablespace id */
|
||||
ulint offset, /*!< in: page no */
|
||||
lsn_t lsn, /*!< in: page lsn */
|
||||
const byte* src_frame,/*!< in: page frame */
|
||||
ulint size, /*!< in: size of data to encrypt */
|
||||
byte* dst_frame); /*!< in: where to encrypt to */
|
||||
|
||||
/*********************************************************************
|
||||
Decrypt buffer page */
|
||||
UNIV_INTERN
|
||||
void
|
||||
fil_space_decrypt(
|
||||
/*==============*/
|
||||
ulint space, /*!< in: tablespace id */
|
||||
const byte* src_frame,/*!< in: page frame */
|
||||
ulint page_size, /*!< in: size of data to encrypt */
|
||||
byte* dst_frame); /*!< in: where to decrypt to */
|
||||
|
||||
|
||||
/*********************************************************************
|
||||
Decrypt buffer page
|
||||
@return true if page was encrypted */
|
||||
/******************************************************************
|
||||
Decrypt a page
|
||||
@return true if page is decrypted, false if not. */
|
||||
UNIV_INTERN
|
||||
bool
|
||||
fil_space_decrypt(
|
||||
/*==============*/
|
||||
fil_space_crypt_t* crypt_data, /*!< in: crypt data */
|
||||
const byte* src_frame,/*!< in: page frame */
|
||||
ulint page_size, /*!< in: page size */
|
||||
byte* dst_frame); /*!< in: where to decrypt to */
|
||||
fil_space_crypt_t* crypt_data, /*!< in: crypt data */
|
||||
byte* tmp_frame, /*!< in: temporary buffer */
|
||||
ulint page_size, /*!< in: page size */
|
||||
byte* src_frame); /*!< in:out: page buffer */
|
||||
|
||||
/*********************************************************************
|
||||
Encrypt buffer page
|
||||
@return encrypted page, or original not encrypted page if encrypt
|
||||
is not needed. */
|
||||
UNIV_INTERN
|
||||
byte*
|
||||
fil_space_encrypt(
|
||||
/*==============*/
|
||||
ulint space, /*!< in: tablespace id */
|
||||
ulint offset, /*!< in: page no */
|
||||
lsn_t lsn, /*!< in: page lsn */
|
||||
byte* src_frame, /*!< in: page frame */
|
||||
ulint size, /*!< in: size of data to encrypt */
|
||||
byte* dst_frame); /*!< in: where to encrypt to */
|
||||
|
||||
/*********************************************************************
|
||||
Decrypt buffer page
|
||||
@return decrypted page, or original not encrypted page if decrypt is
|
||||
not needed.*/
|
||||
UNIV_INTERN
|
||||
byte*
|
||||
fil_space_decrypt(
|
||||
/*==============*/
|
||||
ulint space, /*!< in: tablespace id */
|
||||
byte* src_frame, /*!< in: page frame */
|
||||
ulint page_size, /*!< in: size of data to encrypt */
|
||||
byte* dst_frame); /*!< in: where to decrypt to */
|
||||
|
||||
/*********************************************************************
|
||||
fil_space_verify_crypt_checksum
|
||||
|
||||
@@ -5873,30 +5873,31 @@ Encrypts a buffer page right before it's flushed to disk
|
||||
byte*
|
||||
buf_page_encrypt_before_write(
|
||||
/*==========================*/
|
||||
buf_page_t* bpage, /*!< in/out: buffer page to be flushed */
|
||||
const byte* src_frame, /*!< in: src frame */
|
||||
ulint space_id) /*!< in: space id */
|
||||
buf_page_t* bpage, /*!< in/out: buffer page to be flushed */
|
||||
byte* src_frame, /*!< in: src frame */
|
||||
ulint space_id) /*!< in: space id */
|
||||
{
|
||||
fil_space_crypt_t* crypt_data = fil_space_get_crypt_data(space_id);
|
||||
ulint zip_size = buf_page_get_zip_size(bpage);
|
||||
ulint page_size = (zip_size) ? zip_size : UNIV_PAGE_SIZE;
|
||||
buf_pool_t* buf_pool = buf_pool_from_bpage(bpage);
|
||||
bool page_compressed = fil_space_is_page_compressed(bpage->space);
|
||||
bpage->real_size = UNIV_PAGE_SIZE;
|
||||
bool encrypted = true;
|
||||
|
||||
bpage->real_size = UNIV_PAGE_SIZE;
|
||||
|
||||
fil_page_type_validate(src_frame);
|
||||
|
||||
if (bpage->offset == 0) {
|
||||
/* Page 0 of a tablespace is not encrypted/compressed */
|
||||
ut_ad(bpage->key_version == 0);
|
||||
return const_cast<byte*>(src_frame);
|
||||
return src_frame;
|
||||
}
|
||||
|
||||
if (bpage->space == TRX_SYS_SPACE && bpage->offset == TRX_SYS_PAGE_NO) {
|
||||
/* don't encrypt/compress page as it contains address to dblwr buffer */
|
||||
bpage->key_version = 0;
|
||||
return const_cast<byte*>(src_frame);
|
||||
return src_frame;
|
||||
}
|
||||
|
||||
if (crypt_data != NULL && crypt_data->encryption == FIL_SPACE_ENCRYPTION_OFF) {
|
||||
@@ -5918,31 +5919,35 @@ buf_page_encrypt_before_write(
|
||||
|
||||
if (!encrypted && !page_compressed) {
|
||||
/* No need to encrypt or page compress the page */
|
||||
return const_cast<byte*>(src_frame);
|
||||
return src_frame;
|
||||
}
|
||||
|
||||
/* Find free slot from temporary memory array */
|
||||
buf_tmp_buffer_t* slot = buf_pool_reserve_tmp_slot(buf_pool, page_compressed);
|
||||
slot->out_buf = NULL;
|
||||
bpage->slot = slot;
|
||||
|
||||
byte *dst_frame = bpage->slot->out_buf = slot->crypt_buf;
|
||||
byte *dst_frame = slot->crypt_buf;
|
||||
|
||||
if (!page_compressed) {
|
||||
/* Encrypt page content */
|
||||
fil_space_encrypt(bpage->space,
|
||||
bpage->offset,
|
||||
bpage->newest_modification,
|
||||
src_frame,
|
||||
zip_size,
|
||||
dst_frame);
|
||||
byte* tmp = fil_space_encrypt(bpage->space,
|
||||
bpage->offset,
|
||||
bpage->newest_modification,
|
||||
src_frame,
|
||||
zip_size,
|
||||
dst_frame);
|
||||
|
||||
unsigned key_version =
|
||||
mach_read_from_4(dst_frame + FIL_PAGE_FILE_FLUSH_LSN_OR_KEY_VERSION);
|
||||
ut_ad(key_version == 0 || key_version >= bpage->key_version);
|
||||
bpage->key_version = key_version;
|
||||
bpage->real_size = page_size;
|
||||
slot->out_buf = dst_frame = tmp;
|
||||
|
||||
fil_page_type_validate(dst_frame);
|
||||
#ifdef UNIV_DEBUG
|
||||
fil_page_type_validate(tmp);
|
||||
#endif
|
||||
|
||||
} else {
|
||||
/* First we compress the page content */
|
||||
@@ -5962,22 +5967,27 @@ buf_page_encrypt_before_write(
|
||||
|
||||
bpage->real_size = out_len;
|
||||
|
||||
#ifdef UNIV_DEBUG
|
||||
fil_page_type_validate(tmp);
|
||||
#endif
|
||||
|
||||
if(encrypted) {
|
||||
|
||||
/* And then we encrypt the page content */
|
||||
fil_space_encrypt(bpage->space,
|
||||
bpage->offset,
|
||||
bpage->newest_modification,
|
||||
tmp,
|
||||
zip_size,
|
||||
dst_frame);
|
||||
} else {
|
||||
bpage->slot->out_buf = dst_frame = tmp;
|
||||
tmp = fil_space_encrypt(bpage->space,
|
||||
bpage->offset,
|
||||
bpage->newest_modification,
|
||||
tmp,
|
||||
zip_size,
|
||||
dst_frame);
|
||||
}
|
||||
|
||||
slot->out_buf = dst_frame = tmp;
|
||||
}
|
||||
|
||||
#ifdef UNIV_DEBUG
|
||||
fil_page_type_validate(dst_frame);
|
||||
#endif
|
||||
|
||||
// return dst_frame which will be written
|
||||
return dst_frame;
|
||||
@@ -5989,7 +5999,7 @@ Decrypt page after it has been read from disk
|
||||
ibool
|
||||
buf_page_decrypt_after_read(
|
||||
/*========================*/
|
||||
buf_page_t* bpage) /*!< in/out: buffer page read from disk */
|
||||
buf_page_t* bpage) /*!< in/out: buffer page read from disk */
|
||||
{
|
||||
ulint zip_size = buf_page_get_zip_size(bpage);
|
||||
ulint size = (zip_size) ? zip_size : UNIV_PAGE_SIZE;
|
||||
@@ -6014,8 +6024,11 @@ buf_page_decrypt_after_read(
|
||||
/* Find free slot from temporary memory array */
|
||||
buf_tmp_buffer_t* slot = buf_pool_reserve_tmp_slot(buf_pool, page_compressed);
|
||||
|
||||
#ifdef UNIV_DEBUG
|
||||
fil_page_type_validate(dst_frame);
|
||||
#endif
|
||||
|
||||
/* decompress using comp_buf to dst_frame */
|
||||
fil_decompress_page(slot->comp_buf,
|
||||
dst_frame,
|
||||
size,
|
||||
@@ -6025,24 +6038,27 @@ buf_page_decrypt_after_read(
|
||||
slot->reserved = false;
|
||||
key_version = 0;
|
||||
|
||||
#ifdef UNIV_DEBUG
|
||||
fil_page_type_validate(dst_frame);
|
||||
#endif
|
||||
} else {
|
||||
buf_tmp_buffer_t* slot = NULL;
|
||||
|
||||
if (key_version) {
|
||||
/* Find free slot from temporary memory array */
|
||||
slot = buf_pool_reserve_tmp_slot(buf_pool, page_compressed);
|
||||
memcpy(slot->crypt_buf, dst_frame, size);
|
||||
|
||||
#ifdef UNIV_DEBUG
|
||||
fil_page_type_validate(dst_frame);
|
||||
fil_page_type_validate(slot->crypt_buf);
|
||||
/* decrypt from crypt_buf to dst_frame */
|
||||
#endif
|
||||
/* decrypt using crypt_buf to dst_frame */
|
||||
fil_space_decrypt(bpage->space,
|
||||
slot->crypt_buf,
|
||||
size,
|
||||
dst_frame);
|
||||
slot->crypt_buf,
|
||||
size,
|
||||
dst_frame);
|
||||
#ifdef UNIV_DEBUG
|
||||
fil_page_type_validate(dst_frame);
|
||||
fil_page_type_validate(slot->crypt_buf);
|
||||
#endif
|
||||
}
|
||||
|
||||
if (page_compressed_encrypted) {
|
||||
@@ -6053,13 +6069,16 @@ buf_page_decrypt_after_read(
|
||||
#ifdef UNIV_DEBUG
|
||||
fil_page_type_validate(dst_frame);
|
||||
#endif
|
||||
/* decompress using comp_buf to dst_frame */
|
||||
fil_decompress_page(slot->comp_buf,
|
||||
dst_frame,
|
||||
size,
|
||||
&bpage->write_size);
|
||||
}
|
||||
|
||||
#ifdef UNIV_DEBUG
|
||||
fil_page_type_validate(dst_frame);
|
||||
#endif
|
||||
|
||||
/* Mark this slot as free */
|
||||
if (slot) {
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*****************************************************************************
|
||||
|
||||
Copyright (c) 1995, 2014, Oracle and/or its affiliates. All Rights Reserved.
|
||||
Copyright (c) 2013, 2014, SkySQL Ab. All Rights Reserved.
|
||||
Copyright (c) 2013, 2015, MariaDB Corporation. All Rights Reserved.
|
||||
|
||||
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
|
||||
@@ -391,11 +391,11 @@ buf_dblwr_init_or_load_pages(
|
||||
doublewrite = read_buf + TRX_SYS_DOUBLEWRITE;
|
||||
|
||||
if (mach_read_from_4(read_buf + FIL_PAGE_FILE_FLUSH_LSN_OR_KEY_VERSION) != 0) {
|
||||
fil_space_decrypt((ulint)TRX_SYS_SPACE,
|
||||
read_buf,
|
||||
UNIV_PAGE_SIZE, /* page size */
|
||||
read_buf + UNIV_PAGE_SIZE);
|
||||
doublewrite = read_buf + UNIV_PAGE_SIZE + TRX_SYS_DOUBLEWRITE;
|
||||
byte* tmp = fil_space_decrypt((ulint)TRX_SYS_SPACE,
|
||||
read_buf + UNIV_PAGE_SIZE,
|
||||
UNIV_PAGE_SIZE, /* page size */
|
||||
read_buf);
|
||||
doublewrite = tmp + TRX_SYS_DOUBLEWRITE;
|
||||
}
|
||||
|
||||
if (mach_read_from_4(doublewrite + TRX_SYS_DOUBLEWRITE_MAGIC)
|
||||
|
||||
@@ -545,13 +545,13 @@ fil_space_clear_crypt_data(
|
||||
/******************************************************************
|
||||
Encrypt a page */
|
||||
UNIV_INTERN
|
||||
void
|
||||
byte*
|
||||
fil_space_encrypt(
|
||||
/*==============*/
|
||||
ulint space, /*!< in: Space id */
|
||||
ulint offset, /*!< in: Page offset */
|
||||
lsn_t lsn, /*!< in: lsn */
|
||||
const byte* src_frame, /*!< in: Source page to be encrypted */
|
||||
byte* src_frame, /*!< in: Source page to be encrypted */
|
||||
ulint zip_size, /*!< in: compressed size if
|
||||
row_format compressed */
|
||||
byte* dst_frame) /*!< in: outbut buffer */
|
||||
@@ -566,18 +566,14 @@ fil_space_encrypt(
|
||||
|| orig_page_type==FIL_PAGE_TYPE_XDES) {
|
||||
/* File space header or extent descriptor do not need to be
|
||||
encrypted. */
|
||||
//TODO: is this really needed ?
|
||||
memcpy(dst_frame, src_frame, page_size);
|
||||
return;
|
||||
return src_frame;
|
||||
}
|
||||
|
||||
/* Get crypt data from file space */
|
||||
crypt_data = fil_space_get_crypt_data(space);
|
||||
|
||||
if (crypt_data == NULL) {
|
||||
//TODO: Is this really needed ?
|
||||
memcpy(dst_frame, src_frame, page_size);
|
||||
return;
|
||||
return src_frame;
|
||||
}
|
||||
|
||||
ut_ad(crypt_data->encryption != FIL_SPACE_ENCRYPTION_OFF);
|
||||
@@ -663,6 +659,8 @@ fil_space_encrypt(
|
||||
mach_write_to_4(dst_frame + FIL_PAGE_FILE_FLUSH_LSN_OR_KEY_VERSION + 4, checksum);
|
||||
|
||||
srv_stats.pages_encrypted.inc();
|
||||
|
||||
return dst_frame;
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
@@ -693,24 +691,22 @@ fil_space_check_encryption_read(
|
||||
|
||||
/******************************************************************
|
||||
Decrypt a page
|
||||
@return true if page was encrypted */
|
||||
@return true if page decrypted, false if not.*/
|
||||
UNIV_INTERN
|
||||
bool
|
||||
fil_space_decrypt(
|
||||
/*==============*/
|
||||
fil_space_crypt_t* crypt_data, /*!< in: crypt data */
|
||||
const byte* src_frame, /*!< in: input buffer */
|
||||
byte* tmp_frame, /*!< in: temporary buffer */
|
||||
ulint page_size, /*!< in: page size */
|
||||
byte* dst_frame) /*!< out: output buffer */
|
||||
byte* src_frame) /*!< in:out: page buffer */
|
||||
{
|
||||
ulint page_type = mach_read_from_2(src_frame+FIL_PAGE_TYPE);
|
||||
uint key_version = mach_read_from_4(src_frame + FIL_PAGE_FILE_FLUSH_LSN_OR_KEY_VERSION);
|
||||
bool page_compressed = (page_type == FIL_PAGE_PAGE_COMPRESSED_ENCRYPTED);
|
||||
|
||||
if (key_version == ENCRYPTION_KEY_NOT_ENCRYPTED) {
|
||||
//TODO: is this really needed ?
|
||||
memcpy(dst_frame, src_frame, page_size);
|
||||
return false; /* page not decrypted */
|
||||
return false;
|
||||
}
|
||||
|
||||
ut_ad(crypt_data->encryption != FIL_SPACE_ENCRYPTION_OFF);
|
||||
@@ -723,11 +719,11 @@ fil_space_decrypt(
|
||||
ib_uint64_t lsn = mach_read_from_8(src_frame + FIL_PAGE_LSN);
|
||||
|
||||
/* Copy FIL page header, it is not encrypted */
|
||||
memcpy(dst_frame, src_frame, FIL_PAGE_DATA);
|
||||
memcpy(tmp_frame, src_frame, FIL_PAGE_DATA);
|
||||
|
||||
/* Calculate the offset where decryption starts */
|
||||
const byte* src = src_frame + FIL_PAGE_DATA;
|
||||
byte* dst = dst_frame + FIL_PAGE_DATA;
|
||||
byte* dst = tmp_frame + FIL_PAGE_DATA;
|
||||
uint32 dstlen = 0;
|
||||
ulint srclen = page_size - (FIL_PAGE_DATA + FIL_PAGE_DATA_END);
|
||||
|
||||
@@ -751,12 +747,12 @@ fil_space_decrypt(
|
||||
to sector boundary is written. */
|
||||
if (!page_compressed) {
|
||||
/* Copy FIL trailer */
|
||||
memcpy(dst_frame + page_size - FIL_PAGE_DATA_END,
|
||||
memcpy(tmp_frame + page_size - FIL_PAGE_DATA_END,
|
||||
src_frame + page_size - FIL_PAGE_DATA_END,
|
||||
FIL_PAGE_DATA_END);
|
||||
|
||||
// clear key-version & crypt-checksum from dst
|
||||
memset(dst_frame + FIL_PAGE_FILE_FLUSH_LSN_OR_KEY_VERSION, 0, 8);
|
||||
memset(tmp_frame + FIL_PAGE_FILE_FLUSH_LSN_OR_KEY_VERSION, 0, 8);
|
||||
}
|
||||
|
||||
srv_stats.pages_decrypted.inc();
|
||||
@@ -765,18 +761,31 @@ fil_space_decrypt(
|
||||
}
|
||||
|
||||
/******************************************************************
|
||||
Decrypt a page */
|
||||
Decrypt a page
|
||||
@return encrypted page, or original not encrypted page if encryption is
|
||||
not needed. */
|
||||
UNIV_INTERN
|
||||
void
|
||||
byte*
|
||||
fil_space_decrypt(
|
||||
/*==============*/
|
||||
ulint space, /*!< in: Fil space id */
|
||||
const byte* src_frame, /*!< in: input buffer */
|
||||
byte* tmp_frame, /*!< in: temporary buffer */
|
||||
ulint page_size, /*!< in: page size */
|
||||
byte* dst_frame) /*!< out: output buffer */
|
||||
byte* src_frame) /*!< in/out: page buffer */
|
||||
{
|
||||
fil_space_decrypt(fil_space_get_crypt_data(space),
|
||||
src_frame, page_size, dst_frame);
|
||||
bool encrypted = fil_space_decrypt(
|
||||
fil_space_get_crypt_data(space),
|
||||
tmp_frame,
|
||||
page_size,
|
||||
src_frame);
|
||||
|
||||
if (encrypted) {
|
||||
/* Copy the decrypted page back to page buffer, not
|
||||
really any other options. */
|
||||
memcpy(src_frame, tmp_frame, page_size);
|
||||
}
|
||||
|
||||
return src_frame;
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
|
||||
@@ -6468,14 +6468,19 @@ fil_iterate(
|
||||
for (ulint i = 0; i < n_pages_read; ++i) {
|
||||
|
||||
if (iter.crypt_data != NULL) {
|
||||
ulint size = iter.page_size;
|
||||
bool decrypted = fil_space_decrypt(
|
||||
iter.crypt_data,
|
||||
readptr + i * iter.page_size, // src
|
||||
iter.page_size,
|
||||
io_buffer + i * iter.page_size); // dst
|
||||
iter.crypt_data,
|
||||
io_buffer + i * size, //dst
|
||||
iter.page_size,
|
||||
readptr + i * size); // src
|
||||
|
||||
if (decrypted) {
|
||||
/* write back unencrypted page */
|
||||
updated = true;
|
||||
} else {
|
||||
/* TODO: remove unnecessary memcpy's */
|
||||
memcpy(io_buffer + i * size, readptr + i * size, size);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1477,9 +1477,9 @@ UNIV_INTERN
|
||||
byte*
|
||||
buf_page_encrypt_before_write(
|
||||
/*==========================*/
|
||||
buf_page_t* page, /*!< in/out: buffer page to be flushed */
|
||||
const byte* frame,
|
||||
ulint space_id);
|
||||
buf_page_t* page, /*!< in/out: buffer page to be flushed */
|
||||
byte* frame, /*!< in: src frame */
|
||||
ulint space_id); /*!< in: space id */
|
||||
|
||||
/**********************************************************************
|
||||
The hook that is called after page is written to disk.
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*****************************************************************************
|
||||
|
||||
Copyright (C) 2013, 2015, Google Inc. All Rights Reserved.
|
||||
Copyright (c) 2015, MariaDB Corporation.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify it under
|
||||
@@ -197,43 +197,45 @@ bool
|
||||
fil_space_check_encryption_read(
|
||||
/*============================*/
|
||||
ulint space); /*!< in: tablespace id */
|
||||
|
||||
/*********************************************************************
|
||||
Encrypt buffer page */
|
||||
UNIV_INTERN
|
||||
void
|
||||
fil_space_encrypt(
|
||||
/*==============*/
|
||||
ulint space, /*!< in: tablespace id */
|
||||
ulint offset, /*!< in: page no */
|
||||
lsn_t lsn, /*!< in: page lsn */
|
||||
const byte* src_frame,/*!< in: page frame */
|
||||
ulint size, /*!< in: size of data to encrypt */
|
||||
byte* dst_frame); /*!< in: where to encrypt to */
|
||||
|
||||
/*********************************************************************
|
||||
Decrypt buffer page */
|
||||
UNIV_INTERN
|
||||
void
|
||||
fil_space_decrypt(
|
||||
/*==============*/
|
||||
ulint space, /*!< in: tablespace id */
|
||||
const byte* src_frame,/*!< in: page frame */
|
||||
ulint page_size, /*!< in: size of data to encrypt */
|
||||
byte* dst_frame); /*!< in: where to decrypt to */
|
||||
|
||||
|
||||
/*********************************************************************
|
||||
Decrypt buffer page
|
||||
@return true if page was encrypted */
|
||||
/******************************************************************
|
||||
Decrypt a page
|
||||
@return true if page is decrypted, false if not. */
|
||||
UNIV_INTERN
|
||||
bool
|
||||
fil_space_decrypt(
|
||||
/*==============*/
|
||||
fil_space_crypt_t* crypt_data, /*!< in: crypt data */
|
||||
const byte* src_frame,/*!< in: page frame */
|
||||
ulint page_size, /*!< in: page size */
|
||||
byte* dst_frame); /*!< in: where to decrypt to */
|
||||
fil_space_crypt_t* crypt_data, /*!< in: crypt data */
|
||||
byte* tmp_frame, /*!< in: temporary buffer */
|
||||
ulint page_size, /*!< in: page size */
|
||||
byte* src_frame); /*!< in:out: page buffer */
|
||||
|
||||
/*********************************************************************
|
||||
Encrypt buffer page
|
||||
@return encrypted page, or original not encrypted page if encrypt
|
||||
is not needed. */
|
||||
UNIV_INTERN
|
||||
byte*
|
||||
fil_space_encrypt(
|
||||
/*==============*/
|
||||
ulint space, /*!< in: tablespace id */
|
||||
ulint offset, /*!< in: page no */
|
||||
lsn_t lsn, /*!< in: page lsn */
|
||||
byte* src_frame, /*!< in: page frame */
|
||||
ulint size, /*!< in: size of data to encrypt */
|
||||
byte* dst_frame); /*!< in: where to encrypt to */
|
||||
|
||||
/*********************************************************************
|
||||
Decrypt buffer page
|
||||
@return decrypted page, or original not encrypted page if decrypt is
|
||||
not needed.*/
|
||||
UNIV_INTERN
|
||||
byte*
|
||||
fil_space_decrypt(
|
||||
/*==============*/
|
||||
ulint space, /*!< in: tablespace id */
|
||||
byte* src_frame, /*!< in: page frame */
|
||||
ulint page_size, /*!< in: size of data to encrypt */
|
||||
byte* dst_frame); /*!< in: where to decrypt to */
|
||||
|
||||
/*********************************************************************
|
||||
fil_space_verify_crypt_checksum
|
||||
|
||||
Reference in New Issue
Block a user