Commit d7f3d889 authored by Jan Lindström's avatar Jan Lindström

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