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
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) {
......
/*****************************************************************************
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.
......
/*****************************************************************************
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 */
/******************************************************************
Decrypt a page
@return true if page is decrypted, false if not. */
UNIV_INTERN
void
fil_space_encrypt(
bool
fil_space_decrypt(
/*==============*/
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 */
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 */
/*********************************************************************
Decrypt buffer page */
Encrypt buffer page
@return encrypted page, or original not encrypted page if encrypt
is not needed. */
UNIV_INTERN
void
fil_space_decrypt(
byte*
fil_space_encrypt(
/*==============*/
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 */
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 true if page was encrypted */
@return decrypted page, or original not encrypted page if decrypt is
not needed.*/
UNIV_INTERN
bool
byte*
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 */
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) {
......
/*****************************************************************************
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.
......
/*****************************************************************************
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 */
/******************************************************************
Decrypt a page
@return true if page is decrypted, false if not. */
UNIV_INTERN
void
fil_space_encrypt(
bool
fil_space_decrypt(
/*==============*/
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 */
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 */
/*********************************************************************
Decrypt buffer page */
Encrypt buffer page
@return encrypted page, or original not encrypted page if encrypt
is not needed. */
UNIV_INTERN
void
fil_space_decrypt(
byte*
fil_space_encrypt(
/*==============*/
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 */
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 true if page was encrypted */
@return decrypted page, or original not encrypted page if decrypt is
not needed.*/
UNIV_INTERN
bool
byte*
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 */
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
......
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