@@ -59,6 +59,7 @@ Created 11/5/1995 Heikki Tuuri
5959#include " ut0byte.h"
6060
6161#include " fil0pageencryption.h"
62+ #include " fil0pagecompress.h"
6263
6364
6465/* prototypes for new functions added to ha_innodb.cc */
@@ -574,7 +575,7 @@ buf_page_is_corrupted(
574575ulint zip_size)/* !< in: size of compressed page;
5755760 for uncompressed pages */
576577{
577- ulint page_encrypted = fil_page_is_encrypted (read_buf);
578+ ulint page_encrypted = fil_page_is_compressed_encrypted (read_buf) || fil_page_is_encrypted (read_buf);
578579ulint checksum_field1;
579580ulint checksum_field2;
580581ibool crc32_inited = FALSE ;
@@ -1080,8 +1081,11 @@ buf_block_init(
10801081block->page .io_fix = BUF_IO_NONE;
10811082block->page .crypt_buf = NULL ;
10821083block->page .crypt_buf_free = NULL ;
1084+ block->page .comp_buf = NULL ;
1085+ block->page .comp_buf_free = NULL ;
10831086block->page .key_version = 0 ;
10841087
1088+
10851089block->modify_clock = 0 ;
10861090
10871091#if defined UNIV_DEBUG_FILE_ACCESSES || defined UNIV_DEBUG
@@ -3580,6 +3584,8 @@ buf_page_init_low(
35803584bpage->write_size = 0 ;
35813585bpage->crypt_buf = NULL ;
35823586bpage->crypt_buf_free = NULL ;
3587+ bpage->comp_buf = NULL ;
3588+ bpage->comp_buf_free = NULL ;
35833589bpage->key_version = 0 ;
35843590
35853591HASH_INVALIDATE (bpage, hash);
@@ -5787,6 +5793,11 @@ buf_page_encrypt_before_write(
57875793buf_page_t * bpage, /* !< in/out: buffer page to be flushed */
57885794const byte* src_frame) /* !< in: src frame */
57895795{
5796+ if (srv_encrypt_tables == FALSE ) {
5797+ /* Encryption is disabled */
5798+ return const_cast <byte*>(src_frame);
5799+ }
5800+
57905801if (bpage->offset == 0 ) {
57915802/* Page 0 of a tablespace is not encrypted */
57925803ut_ad (bpage->key_version == 0 );
@@ -5806,6 +5817,7 @@ buf_page_encrypt_before_write(
58065817}
58075818
58085819ulint zip_size = buf_page_get_zip_size (bpage);
5820+ ulint page_size = (zip_size) ? zip_size : UNIV_PAGE_SIZE;
58095821
58105822/* *
58115823* TODO(jonaso): figure out more clever malloc strategy
@@ -5822,18 +5834,28 @@ buf_page_encrypt_before_write(
58225834* considered a lot.
58235835*/
58245836
5825- bpage->crypt_buf_free = (byte*)malloc (UNIV_PAGE_SIZE*2 );
5826- byte *dst_frame = bpage->crypt_buf = (byte *)ut_align (bpage->crypt_buf_free , UNIV_PAGE_SIZE);
5837+ if (bpage->crypt_buf_free == NULL ) {
5838+ bpage->crypt_buf_free = (byte*)malloc (page_size*2 );
5839+ // TODO: Is 4k aligment enough ?
5840+ bpage->crypt_buf = (byte *)ut_align (bpage->crypt_buf_free , page_size);
5841+ }
58275842
5828- // encrypt page content
5829- fil_space_encrypt (bpage->space , bpage->offset ,
5830- bpage->newest_modification ,
5831- src_frame, zip_size, dst_frame, 0 );
5843+ byte *dst_frame = bpage->crypt_buf ;
58325844
5833- unsigned key_version =
5834- mach_read_from_4 (dst_frame + FIL_PAGE_FILE_FLUSH_LSN_OR_KEY_VERSION);
5835- ut_ad (key_version == 0 || key_version >= bpage->key_version );
5836- bpage->key_version = key_version;
5845+ if (!fil_space_is_page_compressed (bpage->space )) {
5846+ // encrypt page content
5847+ fil_space_encrypt (bpage->space , bpage->offset ,
5848+ bpage->newest_modification ,
5849+ src_frame, zip_size, dst_frame, 0 );
5850+
5851+ unsigned key_version =
5852+ mach_read_from_4 (dst_frame + FIL_PAGE_FILE_FLUSH_LSN_OR_KEY_VERSION);
5853+ ut_ad (key_version == 0 || key_version >= bpage->key_version );
5854+ bpage->key_version = key_version;
5855+ } else {
5856+ // We do compression and encryption later on os0file.cc
5857+ dst_frame = (byte *)src_frame;
5858+ }
58375859
58385860// return dst_frame which will be written
58395861return dst_frame;
@@ -5852,6 +5874,13 @@ buf_page_encrypt_after_write(
58525874bpage->crypt_buf_free = NULL ;
58535875bpage->crypt_buf = NULL ;
58545876}
5877+
5878+ if (bpage->comp_buf_free != NULL ) {
5879+ free (bpage->comp_buf_free );
5880+ bpage->comp_buf_free = NULL ;
5881+ bpage->comp_buf = NULL ;
5882+ }
5883+
58555884return (TRUE );
58565885}
58575886
@@ -5861,27 +5890,28 @@ Allocates memory to read in an encrypted page
58615890byte*
58625891buf_page_decrypt_before_read (
58635892/* =========================*/
5864- buf_page_t * bpage) /* !< in/out: buffer page to be read */
5893+ buf_page_t * bpage, /* !< in/out: buffer page to be read */
5894+ ulint zip_size) /* !< in: compressed page size, or 0 */
58655895{
5866- ulint zip_size = buf_page_get_zip_size (bpage);
5867-
5868- if (bpage->offset == 0 ) {
5869- /* File header pages are not encrypted */
5870- unencrypted:
5871- if (zip_size)
5872- return bpage->zip .data ;
5873- else
5874- return ((buf_block_t *) bpage)->frame ;
5875- }
5876-
5877- if (fil_space_check_encryption_read (bpage->space ) == false ) {
5878- goto unencrypted;
5879- }
5896+ ulint size = (zip_size) ? zip_size : UNIV_PAGE_SIZE;
58805897
5881- // allocate buffer to read data into
5882- bpage->crypt_buf_free = (byte*)malloc (UNIV_PAGE_SIZE*2 );
5883- bpage->crypt_buf = (byte*)ut_align (bpage->crypt_buf_free , UNIV_PAGE_SIZE);
5884- return bpage->crypt_buf ;
5898+ /*
5899+ Here we only need to allocate space for not header pages
5900+ in case of file space encryption. Table encryption is handled
5901+ later.
5902+ */
5903+ if (!srv_encrypt_tables || bpage->offset == 0 ||
5904+ fil_space_check_encryption_read (bpage->space ) == false )
5905+ return zip_size ? bpage->zip .data : ((buf_block_t *) bpage)->frame ;
5906+
5907+ if (bpage->crypt_buf_free == NULL )
5908+ {
5909+ // allocate buffer to read data into
5910+ bpage->crypt_buf_free = (byte*)malloc (size*2 );
5911+ // TODO: Is 4K aligment enough ?
5912+ bpage->crypt_buf = (byte*)ut_align (bpage->crypt_buf_free , size);
5913+ }
5914+ return bpage->crypt_buf ;
58855915}
58865916
58875917/* *******************************************************************/ /* *
@@ -5893,28 +5923,41 @@ buf_page_decrypt_after_read(
58935923buf_page_t * bpage) /* !< in/out: buffer page read from disk */
58945924{
58955925ut_ad (bpage->key_version == 0 );
5926+ ulint zip_size = buf_page_get_zip_size (bpage);
5927+ ulint size = (zip_size) ? zip_size : UNIV_PAGE_SIZE;
5928+
5929+ byte* dst_frame = (zip_size) ? bpage->zip .data :
5930+ ((buf_block_t *) bpage)->frame ;
5931+
58965932if (bpage->offset == 0 ) {
58975933/* File header pages are not encrypted */
58985934ut_a (bpage->crypt_buf == NULL );
58995935return (TRUE );
59005936}
59015937
5902- ulint zip_size = buf_page_get_zip_size (bpage);
5903- ulint size = (zip_size) ? zip_size : UNIV_PAGE_SIZE;
5904-
5905- byte* dst_frame = (zip_size) ? bpage->zip .data :
5906- ((buf_block_t *) bpage)->frame ;
59075938const byte* src_frame = bpage->crypt_buf != NULL ?
59085939bpage->crypt_buf : dst_frame;
59095940
59105941unsigned key_version =
59115942mach_read_from_4 (src_frame + FIL_PAGE_FILE_FLUSH_LSN_OR_KEY_VERSION);
5943+ bool page_compressed_encrypted = fil_page_is_compressed_encrypted (dst_frame);
59125944
59135945if (key_version == 0 ) {
59145946/* the page we read is unencrypted */
5915- if (dst_frame != src_frame) {
5916- /* but we had allocated a crypt_buf */
5917- memcpy (dst_frame, src_frame, size);
5947+ if (fil_page_is_compressed (dst_frame)) {
5948+ if (bpage->comp_buf_free == NULL ) {
5949+ bpage->comp_buf_free = (byte *)malloc (UNIV_PAGE_SIZE*2 );
5950+ // TODO: is 4k aligment enough ?
5951+ bpage->comp_buf = (byte*)ut_align (bpage->comp_buf_free , UNIV_PAGE_SIZE);
5952+ }
5953+
5954+ fil_decompress_page (bpage->comp_buf , dst_frame, size, NULL );
5955+ } else {
5956+ if (dst_frame != src_frame) {
5957+ /* but we had allocated a crypt_buf */
5958+ // TODO: Can this be avoided ?
5959+ memcpy (dst_frame, src_frame, size);
5960+ }
59185961}
59195962} else {
59205963/* the page we read is encrypted */
@@ -5923,13 +5966,27 @@ buf_page_decrypt_after_read(
59235966* malloc a buffer, copy page to it
59245967* and then decrypt from that into real page*/
59255968bpage->crypt_buf_free = (byte *)malloc (UNIV_PAGE_SIZE*2 );
5969+ // TODO: is 4k aligment enough ?
59265970src_frame = bpage->crypt_buf = (byte*)ut_align (bpage->crypt_buf_free , UNIV_PAGE_SIZE);
59275971memcpy (bpage->crypt_buf , dst_frame, size);
59285972}
59295973/* decrypt from src_frame to dst_frame */
59305974fil_space_decrypt (bpage->space ,
59315975 src_frame, size, dst_frame);
5976+
5977+ /* decompress from dst_frame to comp_buf and then copy to
5978+ buffer pool */
5979+ if (page_compressed_encrypted) {
5980+ if (bpage->comp_buf_free == NULL ) {
5981+ bpage->comp_buf_free = (byte *)malloc (UNIV_PAGE_SIZE*2 );
5982+ // TODO: is 4k aligment enough ?
5983+ bpage->comp_buf = (byte*)ut_align (bpage->comp_buf_free , UNIV_PAGE_SIZE);
5984+ }
5985+
5986+ fil_decompress_page (bpage->comp_buf , dst_frame, size, NULL );
5987+ }
59325988}
5989+
59335990bpage->key_version = key_version;
59345991
59355992if (bpage->crypt_buf_free != NULL ) {
@@ -5938,6 +5995,14 @@ buf_page_decrypt_after_read(
59385995bpage->crypt_buf = NULL ;
59395996bpage->crypt_buf_free = NULL ;
59405997}
5998+
5999+ if (bpage->comp_buf_free != NULL ) {
6000+ // free temp page
6001+ free (bpage->comp_buf_free );
6002+ bpage->comp_buf = NULL ;
6003+ bpage->comp_buf_free = NULL ;
6004+ }
6005+
59416006return (TRUE );
59426007}
59436008
0 commit comments