diff options
author | Monty <monty@mariadb.org> | 2014-12-22 16:53:17 +0200 |
---|---|---|
committer | Sergei Golubchik <serg@mariadb.org> | 2015-02-10 10:21:17 +0100 |
commit | d7d589dc01f6d70d1518b74d46fd3b75e76267f5 (patch) | |
tree | f9df59951453660f0038ed78cf5ceadc852bf74c /storage/innobase/os | |
parent | 3a3ec744b5a31318a00821dc0ed6da8af49fda25 (diff) | |
download | mariadb-git-d7d589dc01f6d70d1518b74d46fd3b75e76267f5.tar.gz |
Push for testing of encryption
Diffstat (limited to 'storage/innobase/os')
-rw-r--r-- | storage/innobase/os/os0file.cc | 306 |
1 files changed, 230 insertions, 76 deletions
diff --git a/storage/innobase/os/os0file.cc b/storage/innobase/os/os0file.cc index 4db5f183892..f41ddaf2b30 100644 --- a/storage/innobase/os/os0file.cc +++ b/storage/innobase/os/os0file.cc @@ -43,7 +43,9 @@ Created 10/21/1995 Heikki Tuuri #include "srv0srv.h" #include "srv0start.h" #include "fil0fil.h" +#include "fsp0fsp.h" #include "fil0pagecompress.h" +#include "fil0pageencryption.h" #include "buf0buf.h" #include "srv0mon.h" #include "srv0srv.h" @@ -223,9 +225,17 @@ struct os_aio_slot_t{ freed after the write has been completed */ + byte* page_encryption_page; /*!< Memory allocated for + page encrypted page and + freed after the write + has been completed */ + ibool page_compression; ulint page_compression_level; + ibool page_encryption; + ulint page_encryption_key; + ulint* write_size; /*!< Actual write size initialized after fist successfull trim operation for this page and if @@ -236,9 +246,17 @@ struct os_aio_slot_t{ page compressed pages, do not free this */ - ibool page_compress_success; - /*!< TRUE if page compression was - successfull, false if not */ + byte* page_buf2; /*!< Actual page buffer for + page encrypted pages, do not + free this */ + byte* tmp_encryption_buf; /*!< a temporal buffer used by page encryption */ + + ibool page_compression_success; + ibool page_encryption_success; + /*!< TRUE if page compression was + successfull, false if not */ + + lsn_t lsn; /* lsn of the newest modification */ ulint file_block_size;/*!< file block size */ @@ -398,6 +416,19 @@ os_slot_alloc_lzo_mem( os_aio_slot_t* slot); /*!< in: slot structure */ #endif +/**********************************************************************//** +Allocate memory for temporal buffer used for page encryption. This +buffer is freed later. */ +UNIV_INTERN +void +os_slot_alloc_page_buf2( + os_aio_slot_t* slot); /*!< in: slot structure */ +/**********************************************************************//** +Allocate memory for temporal buffer used for page encryption. */ +UNIV_INTERN +void +os_slot_alloc_tmp_encryption_buf( + os_aio_slot_t* slot); /*!< in: slot structure */ /****************************************************************//** Does error handling when a file operation fails. @return TRUE if we should retry the operation */ @@ -2923,14 +2954,6 @@ try_again: os_mutex_exit(os_file_count_mutex); if (ret && len == n) { - /* Note that InnoDB writes files that are not formated - as file spaces and they do not have FIL_PAGE_TYPE - field, thus we must use here information is the actual - file space compressed. */ - if (fil_page_is_compressed((byte *)buf)) { - fil_decompress_page(NULL, (byte *)buf, len, NULL); - } - return(TRUE); } #else /* __WIN__ */ @@ -2943,14 +2966,6 @@ try_again: ret = os_file_pread(file, buf, n, offset); if ((ulint) ret == n) { - /* Note that InnoDB writes files that are not formated - as file spaces and they do not have FIL_PAGE_TYPE - field, thus we must use here information is the actual - file space compressed. */ - if (fil_page_is_compressed((byte *)buf)) { - fil_decompress_page(NULL, (byte *)buf, n, NULL); - } - return(TRUE); } @@ -3066,15 +3081,6 @@ try_again: os_mutex_exit(os_file_count_mutex); if (ret && len == n) { - - /* Note that InnoDB writes files that are not formated - as file spaces and they do not have FIL_PAGE_TYPE - field, thus we must use here information is the actual - file space compressed. */ - if (fil_page_is_compressed((byte *)buf)) { - fil_decompress_page(NULL, (byte *)buf, n, NULL); - } - return(TRUE); } #else /* __WIN__ */ @@ -3087,14 +3093,6 @@ try_again: ret = os_file_pread(file, buf, n, offset); if ((ulint) ret == n) { - /* Note that InnoDB writes files that are not formated - as file spaces and they do not have FIL_PAGE_TYPE - field, thus we must use here information is the actual - file space compressed. */ - if (fil_page_is_compressed((byte *)buf)) { - fil_decompress_page(NULL, (byte *)buf, n, NULL); - } - return(TRUE); } #endif /* __WIN__ */ @@ -4180,6 +4178,7 @@ os_aio_array_free( for (i = 0; i < array->n_slots; i++) { os_aio_slot_t* slot = os_aio_array_get_nth_slot(array, i); + if (slot->page_compression_page) { ut_free(slot->page_compression_page); slot->page_compression_page = NULL; @@ -4189,8 +4188,19 @@ os_aio_array_free( ut_free(slot->lzo_mem); slot->lzo_mem = NULL; } + + if (slot->page_encryption_page) { + ut_free(slot->page_encryption_page); + slot->page_encryption_page = NULL; + } + + if (slot->tmp_encryption_buf) { + ut_free(slot->tmp_encryption_buf); + slot->tmp_encryption_buf = NULL; + } } + ut_free(array->slots); ut_free(array); @@ -4532,8 +4542,13 @@ os_aio_array_reserve_slot( actual page size does not decrease. */ ibool page_compression, /*!< in: is page compression used on this file space */ - ulint page_compression_level) /*!< page compression - level to be used */ + ulint page_compression_level, /*!< page compression + level to be used */ + ibool page_encryption, /*!< in: is page encryption used + on this file space */ + ulint page_encryption_key, /*!< page encryption key + to be used */ + lsn_t lsn) /* lsn of the newest modification */ { os_aio_slot_t* slot = NULL; #ifdef WIN_ASYNC_IO @@ -4622,11 +4637,15 @@ found: slot->type = type; slot->buf = static_cast<byte*>(buf); slot->offset = offset; + slot->lsn = lsn; slot->io_already_done = FALSE; - slot->page_compress_success = FALSE; + slot->page_compression_success = FALSE; + slot->page_encryption_success = FALSE; slot->write_size = write_size; slot->page_compression_level = page_compression_level; slot->page_compression = page_compression; + slot->page_encryption_key = page_encryption_key; + slot->page_encryption = page_encryption; if (message1) { slot->file_block_size = fil_node_get_block_size(message1); @@ -4652,7 +4671,8 @@ found: #endif /* Call page compression */ - tmp = fil_compress_page(fil_node_get_space_id(slot->message1), + tmp = fil_compress_page( + fil_node_get_space_id(slot->message1), (byte *)buf, slot->page_buf, len, @@ -4667,9 +4687,9 @@ found: len = real_len; buf = slot->page_buf; slot->len = real_len; - slot->page_compress_success = TRUE; + slot->page_compression_success = TRUE; } else { - slot->page_compress_success = FALSE; + slot->page_compression_success = FALSE; } /* Take array mutex back, not sure if this is really needed @@ -4678,6 +4698,35 @@ found: } +// if (srv_encrypt_tables) { + //page_encryption = TRUE; +// } + + /* If the space is page encryption and this is write operation + then we encrypt the page */ + if (message1 && type == OS_FILE_WRITE && page_encryption ) { + /* Release the array mutex while encrypting */ + os_mutex_exit(array->mutex); + + // We allocate memory for page encrypted buffer if and only + // if it is not yet allocated. + os_slot_alloc_page_buf2(slot); + + fil_space_encrypt( + fil_node_get_space_id(slot->message1), + slot->offset, + slot->lsn, + (byte *)buf, + slot->len, + slot->page_buf2, + slot->page_encryption_key); + + slot->page_encryption_success = TRUE; + buf = slot->page_buf2; + + /* Take array mutex back */ + os_mutex_enter(array->mutex); + } #ifdef WIN_ASYNC_IO control = &slot->control; @@ -4963,12 +5012,18 @@ os_aio_func( actual page size does not decrease. */ ibool page_compression, /*!< in: is page compression used on this file space */ - ulint page_compression_level) /*!< page compression + ulint page_compression_level, /*!< page compression level to be used */ + ibool page_encryption, /*!< in: is page encryption used + on this file space */ + ulint page_encryption_key, /*!< page encryption key + to be used */ + lsn_t lsn) /* lsn of the newest modification */ { os_aio_array_t* array; os_aio_slot_t* slot; #ifdef WIN_ASYNC_IO + void* buffer = NULL; ibool retval; BOOL ret = TRUE; DWORD len = (DWORD) n; @@ -4987,6 +5042,7 @@ os_aio_func( ut_ad((n & 0xFFFFFFFFUL) == n); #endif + wake_later = mode & OS_AIO_SIMULATED_WAKE_LATER; mode = mode & (~OS_AIO_SIMULATED_WAKE_LATER); @@ -5077,7 +5133,9 @@ try_again: } slot = os_aio_array_reserve_slot(type, array, message1, message2, file, - name, buf, offset, n, write_size, page_compression, page_compression_level); + name, buf, offset, n, write_size, + page_compression, page_compression_level, + page_encryption, page_encryption_key, lsn); if (type == OS_FILE_READ) { if (srv_use_native_aio) { @@ -5104,7 +5162,18 @@ try_again: if (srv_use_native_aio) { os_n_file_writes++; #ifdef WIN_ASYNC_IO - ret = WriteFile(file, buf, (DWORD) n, &len, + if (page_encryption && slot->page_encryption_success) { + buffer = slot->page_buf2; + n = slot->len; + } else { + if (page_compression && slot->page_compression_success) { + buffer = slot->page_buf; + n = slot->len; + } else { + buffer = buf; + } + } + ret = WriteFile(file, buffer, (DWORD) n, &len, &(slot->control)); #elif defined(LINUX_NATIVE_AIO) @@ -5307,21 +5376,29 @@ os_aio_windows_handle( ut_a((slot->len & 0xFFFFFFFFUL) == slot->len); - switch (slot->type) { - case OS_FILE_WRITE: - if (slot->message1 && - slot->page_compression && - slot->page_compress_success && - slot->page_buf) { - ret = WriteFile(slot->file, slot->page_buf, - (DWORD) slot->len, &len, - &(slot->control)); + switch (slot->type) { + case OS_FILE_WRITE: + if (slot->message1 + && slot->page_encryption + && slot->page_encryption_success) { + ret_val = os_file_write(slot->name, + slot->file, + slot->page_buf2, + slot->offset, + slot->len); } else { - ret = WriteFile(slot->file, slot->buf, - (DWORD) slot->len, &len, - &(slot->control)); - } - + if (slot->message1 + && slot->page_compression + && slot->page_compression_success) { + ret = WriteFile(slot->file, slot->page_buf, + (DWORD) slot->len, &len, + &(slot->control)); + } else { + ret = WriteFile(slot->file, slot->buf, + (DWORD) slot->len, &len, + &(slot->control)); + } + } break; case OS_FILE_READ: ret = ReadFile(slot->file, slot->buf, @@ -5353,20 +5430,41 @@ os_aio_windows_handle( } if (slot->type == OS_FILE_READ) { - if(fil_page_is_compressed(slot->buf)) { + if (fil_page_is_compressed_encrypted(slot->buf) || + fil_page_is_encrypted(slot->buf)) { + ut_ad(slot->message1 != NULL); + os_slot_alloc_page_buf2(slot); + os_slot_alloc_tmp_encryption_buf(slot); + + // Decrypt the data + fil_space_decrypt( + fil_node_get_space_id(slot->message1), + slot->buf, + slot->len, + slot->page_buf2); + // Copy decrypted buffer back to buf + memcpy(slot->buf, slot->page_buf2, slot->len); + } + if (fil_page_is_compressed(slot->buf)) { + /* We allocate memory for page compressed buffer if + and only if it is not yet allocated. */ os_slot_alloc_page_buf(slot); - #ifdef HAVE_LZO if (fil_page_is_lzo_compressed(slot->buf)) { os_slot_alloc_lzo_mem(slot); } #endif - - fil_decompress_page(slot->page_buf, slot->buf, slot->len, slot->write_size); + fil_decompress_page( + slot->page_buf, + slot->buf, + slot->len, + slot->write_size); } } else { /* OS_FILE_WRITE */ - if (slot->page_compress_success && fil_page_is_compressed(slot->page_buf)) { + if (slot->page_compression_success && + (fil_page_is_compressed(slot->page_buf) || + fil_page_is_compressed_encrypted(slot->buf))) { if (srv_use_trim && os_fallocate_failed == FALSE) { // Deallocate unused blocks from file system os_file_trim(slot); @@ -5464,9 +5562,27 @@ retry: ut_a(slot->pos < end_pos); if (slot->type == OS_FILE_READ) { - /* If the table is page compressed and this is read, - we decompress before we annouce the read is - complete. For writes, we free the compressed page. */ + /* If the page is page encrypted we encrypt */ + if (fil_page_is_compressed_encrypted(slot->buf) || + fil_page_is_encrypted(slot->buf)) { + os_slot_alloc_page_buf2(slot); + os_slot_alloc_tmp_encryption_buf(slot); + ut_ad(slot->message1 != NULL); + + // Decrypt the data + fil_space_decrypt( + fil_node_get_space_id(slot->message1), + slot->buf, + slot->len, + slot->page_buf2); + // Copy decrypted buffer back to buf + memcpy(slot->buf, slot->page_buf2, slot->len); + } + + /* If the table is page compressed and this + is read, we decompress before we announce + the read is complete. For writes, we free + the compressed page. */ if (fil_page_is_compressed(slot->buf)) { // We allocate memory for page compressed buffer if and only // if it is not yet allocated. @@ -5481,9 +5597,9 @@ retry: } } else { /* OS_FILE_WRITE */ - if (slot->page_compress_success && - fil_page_is_compressed(slot->page_buf)) { - ut_ad(slot->page_compression_page); + if (slot->page_compression_success && + (fil_page_is_compressed(slot->page_buf) || + fil_page_is_compressed_encrypted(slot->buf))) { if (srv_use_trim && os_fallocate_failed == FALSE) { // Deallocate unused blocks from file system os_file_trim(slot); @@ -6509,6 +6625,29 @@ os_file_trim( #endif /* !UNIV_HOTBACKUP */ /**********************************************************************//** +Allocate memory for temporal buffer used for page encryption. This +buffer is freed later. */ +UNIV_INTERN +void +os_slot_alloc_page_buf2( +/*===================*/ + os_aio_slot_t* slot) /*!< in: slot structure */ +{ + ut_a(slot != NULL); + + if(slot->page_buf2 == NULL) { + byte* cbuf2; + byte* cbuf; + + cbuf2 = static_cast<byte *>(ut_malloc(UNIV_PAGE_SIZE*2)); + cbuf = static_cast<byte *>(ut_align(cbuf2, UNIV_PAGE_SIZE)); + slot->page_encryption_page = static_cast<byte *>(cbuf2); + slot->page_buf2 = static_cast<byte *>(cbuf); + memset(slot->page_encryption_page, 0, UNIV_PAGE_SIZE*2); + } +} + +/**********************************************************************//** Allocate memory for temporal buffer used for page compression. This buffer is freed later. */ UNIV_INTERN @@ -6517,18 +6656,17 @@ os_slot_alloc_page_buf( /*===================*/ os_aio_slot_t* slot) /*!< in: slot structure */ { - byte* cbuf2; - byte* cbuf; - ut_a(slot != NULL); - if (slot->page_compression_page == NULL) { + if (slot->page_buf == NULL) { + byte* cbuf2; + byte* cbuf; /* We allocate extra to avoid memory overwrite on compression */ cbuf2 = static_cast<byte *>(ut_malloc(UNIV_PAGE_SIZE*2)); cbuf = static_cast<byte *>(ut_align(cbuf2, UNIV_PAGE_SIZE)); slot->page_compression_page = static_cast<byte *>(cbuf2); slot->page_buf = static_cast<byte *>(cbuf); - memset(slot->page_compression_page, 0, UNIV_PAGE_SIZE*2); ut_a(slot->page_buf != NULL); + memset(slot->page_compression_page, 0, UNIV_PAGE_SIZE*2); } } @@ -6545,12 +6683,28 @@ os_slot_alloc_lzo_mem( ut_a(slot != NULL); if(slot->lzo_mem == NULL) { slot->lzo_mem = static_cast<byte *>(ut_malloc(LZO1X_1_15_MEM_COMPRESS)); - memset(slot->lzo_mem, 0, LZO1X_1_15_MEM_COMPRESS); ut_a(slot->lzo_mem != NULL); + memset(slot->lzo_mem, 0, LZO1X_1_15_MEM_COMPRESS); } } #endif +/**********************************************************************//** +Allocate memory for temporal buffer used for page encryption. */ +UNIV_INTERN +void +os_slot_alloc_tmp_encryption_buf( +/*=============================*/ + os_aio_slot_t* slot) /*!< in: slot structure */ +{ + ut_a(slot != NULL); + if (slot->tmp_encryption_buf == NULL) { + slot->tmp_encryption_buf = static_cast<byte *>(ut_malloc(64)); + memset(slot->tmp_encryption_buf, 0, 64); + } +} + + /***********************************************************************//** Try to get number of bytes per sector from file system. @return file block size */ |