1 /***********************************************************************
2
3 Copyright (c) 1995, 2021, Oracle and/or its affiliates.
4 Copyright (c) 2009, 2017, Percona Inc.
5
6 Portions of this file contain modifications contributed and copyrighted
7 by Percona Inc.. Those modifications are
8 gratefully acknowledged and are described briefly in the InnoDB
9 documentation. The contributions by Percona Inc. are incorporated with
10 their permission, and subject to the conditions contained in the file
11 COPYING.Percona.
12
13 This program is free software; you can redistribute it and/or modify
14 it under the terms of the GNU General Public License, version 2.0,
15 as published by the Free Software Foundation.
16
17 This program is also distributed with certain software (including
18 but not limited to OpenSSL) that is licensed under separate terms,
19 as designated in a particular file or component or in included license
20 documentation. The authors of MySQL hereby grant you an additional
21 permission to link the program and your derivative works with the
22 separately licensed software that they have included with MySQL.
23
24 This program is distributed in the hope that it will be useful,
25 but WITHOUT ANY WARRANTY; without even the implied warranty of
26 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
27 GNU General Public License, version 2.0, for more details.
28
29 You should have received a copy of the GNU General Public License along with
30 this program; if not, write to the Free Software Foundation, Inc.,
31 51 Franklin Street, Suite 500, Boston, MA 02110-1335 USA
32
33 ***********************************************************************/
34
35 /**************************************************//**
36 @file include/os0file.h
37 The interface to the operating system file io
38
39 Created 10/21/1995 Heikki Tuuri
40 *******************************************************/
41
42 #ifndef os0file_h
43 #define os0file_h
44
45 #include "univ.i"
46
47 #ifndef _WIN32
48 #include <dirent.h>
49 #include <sys/stat.h>
50 #include <time.h>
51 #endif /* !_WIN32 */
52 #include "page0types.h"
53
54 /** File node of a tablespace or the log data space */
55 struct fil_node_t;
56
57 struct trx_t;
58
59 extern bool os_has_said_disk_full;
60
61 /** Number of pending read operations */
62 extern ulint os_n_pending_reads;
63 /** Number of pending write operations */
64 extern ulint os_n_pending_writes;
65
66 /** File offset in bytes */
67 typedef ib_uint64_t os_offset_t;
68
69 #ifdef _WIN32
70
71 /**
72 Gets the operating system version. Currently works only on Windows.
73 @return OS_WIN95, OS_WIN31, OS_WINNT, OS_WIN2000, OS_WINXP, OS_WINVISTA,
74 OS_WIN7. */
75
76 ulint
77 os_get_os_version();
78
79 typedef HANDLE os_file_dir_t; /*!< directory stream */
80
81 /** We define always WIN_ASYNC_IO, and check at run-time whether
82 the OS actually supports it: Win 95 does not, NT does. */
83 # define WIN_ASYNC_IO
84
85 /** Use unbuffered I/O */
86 # define UNIV_NON_BUFFERED_IO
87
88 # define SRV_PATH_SEPARATOR '\\'
89
90 /** File handle */
91 # define os_file_t HANDLE
92
93 /** Convert a C file descriptor to a native file handle
94 @param fd file descriptor
95 @return native file handle */
96 # define OS_FILE_FROM_FD(fd) (HANDLE) _get_osfhandle(fd)
97
98 #else /* _WIN32 */
99
100 #define SRV_PATH_SEPARATOR '/'
101
102 typedef DIR* os_file_dir_t; /*!< directory stream */
103
104 /** File handle */
105 typedef int os_file_t;
106
107 /** Convert a C file descriptor to a native file handle
108 @param fd file descriptor
109 @return native file handle */
110 # define OS_FILE_FROM_FD(fd) fd
111
112 #endif /* _WIN32 */
113
114 static const os_file_t OS_FILE_CLOSED = os_file_t(~0);
115
116 /** Common file descriptor for file IO instrumentation with PFS
117 on windows and other platforms */
118 struct pfs_os_file_t
119 {
120 os_file_t m_file;
121 #ifdef UNIV_PFS_IO
122 struct PSI_file *m_psi;
123 #endif
124
is_closedpfs_os_file_t125 bool is_closed() const {
126 return m_file == OS_FILE_CLOSED;
127 }
128
set_closedpfs_os_file_t129 void set_closed() {
130 m_file = OS_FILE_CLOSED;
131 }
132 };
133
134 /** The next value should be smaller or equal to the smallest sector size used
135 on any disk. A log block is required to be a portion of disk which is written
136 so that if the start and the end of a block get written to disk, then the
137 whole block gets written. This should be true even in most cases of a crash:
138 if this fails for a log block, then it is equivalent to a media failure in the
139 log. */
140
141 #define OS_FILE_LOG_BLOCK_SIZE 512
142
143 /** Options for os_file_create_func @{ */
144 enum os_file_create_t {
145 OS_FILE_OPEN = 51, /*!< to open an existing file (if
146 doesn't exist, error) */
147 OS_FILE_CREATE, /*!< to create new file (if
148 exists, error) */
149 OS_FILE_OVERWRITE, /*!< to create a new file, if exists
150 the overwrite old file */
151 OS_FILE_OPEN_RAW, /*!< to open a raw device or disk
152 partition */
153 OS_FILE_CREATE_PATH, /*!< to create the directories */
154 OS_FILE_OPEN_RETRY, /*!< open with retry */
155
156 /** Flags that can be combined with the above values. Please ensure
157 that the above values stay below 128. */
158
159 OS_FILE_ON_ERROR_NO_EXIT = 128, /*!< do not exit on unknown errors */
160 OS_FILE_ON_ERROR_SILENT = 256, /*!< don't print diagnostic messages to
161 the log unless it is a fatal error,
162 this flag is only used if
163 ON_ERROR_NO_EXIT is set */
164 OS_FILE_O_SYNC = 512 /*!< Open file with O_SYNC */
165 };
166
167 /** Options for os_file_advise_func @{ */
168 enum os_file_advise_t {
169 OS_FILE_ADVISE_NORMAL = 1, /*!< no advice on access pattern
170 (default) */
171 OS_FILE_ADVISE_RANDOM = 2, /*!< access in random order */
172 OS_FILE_ADVISE_SEQUENTIAL = 4, /*!< access the specified data
173 sequentially (with lower offsets read
174 before higher ones) */
175 OS_FILE_ADVISE_WILLNEED = 8, /*!< specified data will be accessed
176 in the near future */
177 OS_FILE_ADVISE_DONTNEED = 16, /*!< specified data will not be
178 accessed in the near future */
179 OS_FILE_ADVISE_NOREUSE = 32 /*!< access only once */
180 };
181
182 static const ulint OS_FILE_READ_ONLY = 333;
183 static const ulint OS_FILE_READ_WRITE = 444;
184
185 /** Used by MySQLBackup */
186 static const ulint OS_FILE_READ_ALLOW_DELETE = 555;
187
188 /* Options for file_create */
189 static const ulint OS_FILE_AIO = 61;
190 static const ulint OS_FILE_NORMAL = 62;
191 /* @} */
192
193 /** Types for file create @{ */
194 static const ulint OS_DATA_FILE = 100;
195 static const ulint OS_LOG_FILE = 101;
196 static const ulint OS_DATA_TEMP_FILE = 102;
197 /* @} */
198
199 /** Error codes from os_file_get_last_error @{ */
200 static const ulint OS_FILE_NOT_FOUND = 71;
201 static const ulint OS_FILE_DISK_FULL = 72;
202 static const ulint OS_FILE_ALREADY_EXISTS = 73;
203 static const ulint OS_FILE_PATH_ERROR = 74;
204
205 /** wait for OS aio resources to become available again */
206 static const ulint OS_FILE_AIO_RESOURCES_RESERVED = 75;
207
208 static const ulint OS_FILE_SHARING_VIOLATION = 76;
209 static const ulint OS_FILE_ERROR_NOT_SPECIFIED = 77;
210 static const ulint OS_FILE_INSUFFICIENT_RESOURCE = 78;
211 static const ulint OS_FILE_AIO_INTERRUPTED = 79;
212 static const ulint OS_FILE_OPERATION_ABORTED = 80;
213 static const ulint OS_FILE_ACCESS_VIOLATION = 81;
214 static const ulint OS_FILE_ERROR_MAX = 100;
215 /* @} */
216
217 /** Compression algorithm. */
218 struct Compression {
219
220 /** Algorithm types supported */
221 enum Type {
222 /* Note: During recovery we don't have the compression type
223 because the .frm file has not been read yet. Therefore
224 we write the recovered pages out without compression. */
225
226 /** No compression */
227 NONE = 0,
228
229 /** Use ZLib */
230 ZLIB = 1,
231
232 /** Use LZ4 faster variant, usually lower compression. */
233 LZ4 = 2
234 };
235
236 /** Compressed page meta-data */
237 struct meta_t {
238
239 /** Version number */
240 uint8_t m_version;
241
242 /** Algorithm type */
243 Type m_algorithm;
244
245 /** Original page type */
246 uint16_t m_original_type;
247
248 /** Original page size, before compression */
249 uint16_t m_original_size;
250
251 /** Size after compression */
252 uint16_t m_compressed_size;
253 };
254
255 /** Default constructor */
CompressionCompression256 Compression() : m_type(NONE) { };
257
258 /** Specific constructor
259 @param[in] type Algorithm type */
CompressionCompression260 explicit Compression(Type type)
261 :
262 m_type(type)
263 {
264 #ifdef UNIV_DEBUG
265 switch (m_type) {
266 case NONE:
267 case ZLIB:
268 case LZ4:
269
270 default:
271 ut_error;
272 }
273 #endif /* UNIV_DEBUG */
274 }
275
276 /** Version of compressed page */
277 static const uint8_t FIL_PAGE_VERSION_1 = 1;
278 static const uint8_t FIL_PAGE_VERSION_2 = 2;
279
280 /** Check the page header type field.
281 @param[in] page Page contents
282 @return true if it is a compressed page */
283 static bool is_compressed_page(const byte* page)
284 MY_ATTRIBUTE((warn_unused_result));
285
286 /** Check the page header type field.
287 @param[in] page Page contents
288 @return true if it is a compressed and encrypted page */
289 static bool is_compressed_encrypted_page(const byte *page)
290 MY_ATTRIBUTE((warn_unused_result));
291
292 /** Check if the version on page is valid.
293 @param[in] version version
294 @return true if version is valid */
295 static bool is_valid_page_version(uint8_t version);
296
297 /** Check wether the compression algorithm is supported.
298 @param[in] algorithm Compression algorithm to check
299 @param[out] type The type that algorithm maps to
300 @return DB_SUCCESS or error code */
301 static dberr_t check(const char* algorithm, Compression* type)
302 MY_ATTRIBUTE((warn_unused_result));
303
304 /** Validate the algorithm string.
305 @param[in] algorithm Compression algorithm to check
306 @return DB_SUCCESS or error code */
307 static dberr_t validate(const char* algorithm)
308 MY_ATTRIBUTE((warn_unused_result));
309
310 /** Convert to a "string".
311 @param[in] type The compression type
312 @return the string representation */
313 static const char* to_string(Type type)
314 MY_ATTRIBUTE((warn_unused_result));
315
316 /** Convert the meta data to a std::string.
317 @param[in] meta Page Meta data
318 @return the string representation */
319 static std::string to_string(const meta_t& meta)
320 MY_ATTRIBUTE((warn_unused_result));
321
322 /** Deserizlise the page header compression meta-data
323 @param[in] header Pointer to the page header
324 @param[out] control Deserialised data */
325 static void deserialize_header(
326 const byte* page,
327 meta_t* control);
328
329 /** Check if the string is "empty" or "none".
330 @param[in] algorithm Compression algorithm to check
331 @return true if no algorithm requested */
332 static bool is_none(const char* algorithm)
333 MY_ATTRIBUTE((warn_unused_result));
334
335
336 static bool is_no(const char* algorithm)
337 MY_ATTRIBUTE((warn_unused_result));
338
339 /** Decompress the page data contents. Page type must be
340 FIL_PAGE_COMPRESSED, if not then the source contents are
341 left unchanged and DB_SUCCESS is returned.
342 @param[in] dblwr_recover true of double write recovery
343 in progress
344 @param[in,out] src Data read from disk, decompressed
345 data will be copied to this page
346 @param[in,out] dst Scratch area to use for decompression
347 @param[in] dst_len Size of the scratch area in bytes
348 @return DB_SUCCESS or error code */
349 static dberr_t deserialize(
350 bool dblwr_recover,
351 byte* src,
352 byte* dst,
353 ulint dst_len)
354 MY_ATTRIBUTE((warn_unused_result));
355
356 /** Compression type */
357 Type m_type;
358 };
359
360 static const uint ENCRYPTION_KEY_VERSION_INVALID = (~(uint)0);
361
362 static const uint FIL_DEFAULT_ENCRYPTION_KEY = 0;
363
364 static const uint ENCRYPTION_KEY_VERSION_NOT_ENCRYPTED = 0;
365
366 /** Encryption key length */
367 static const ulint ENCRYPTION_KEY_LEN = 32;
368
369 /** Encryption magic bytes size */
370 static const ulint ENCRYPTION_MAGIC_SIZE = 3;
371
372 /** Encryption magic bytes for 5.7.11, it's for checking the encryption information
373 version. */
374 static const char ENCRYPTION_KEY_MAGIC_V1[] = "lCA";
375
376 /** Encryption magic bytes for 5.7.12+, it's for checking the encryption information
377 version. */
378 static const char ENCRYPTION_KEY_MAGIC_V2[] = "lCB";
379
380 /** Encryption magic bytes for 5.7.28+, it's for checking the encryption information
381 version. */
382 static const char ENCRYPTION_KEY_MAGIC_V3[] = "lCC";
383
384 static const char ENCRYPTION_KEY_MAGIC_PS_V1[] = "PSA";
385
386 /** Encryption magic bytes for rotated redo log encryption, it's for checking the
387 encryption information version. */
388 static const char ENCRYPTION_KEY_MAGIC_RK[] = "lCR";
389
390 /** Encryption master key prifix */
391 static const char ENCRYPTION_MASTER_KEY_PRIFIX[] = "INNODBKey";
392
393 /** Encryption master key prifix size */
394 static const ulint ENCRYPTION_MASTER_KEY_PRIFIX_LEN = 9;
395
396 static const char ENCRYPTION_ZIP_PAGE_KEYRING_ENCRYPTION_MAGIC[] = "RK";
397
398 static const ulint ENCRYPTION_ZIP_PAGE_KEYRING_ENCRYPTION_MAGIC_LEN = 2;
399
400 /** Encryption master key prifix */
401 //TODO: Change this to percona_innodb_idb
402 static const char ENCRYPTION_PERCONA_SYSTEM_KEY_PREFIX[] = "percona_innodb";
403
404 /** Encryption master key prifix size */
405 static const ulint ENCRYPTION_PERCONA_SYSTEM_KEY_PREFIX_LEN = array_elements(ENCRYPTION_PERCONA_SYSTEM_KEY_PREFIX);
406
407 /** Encryption master key prifix size */
408 static const ulint ENCRYPTION_MASTER_KEY_NAME_MAX_LEN = 100;
409
410 /** UUID of server instance, it's needed for composing master key name */
411 static const ulint ENCRYPTION_SERVER_UUID_LEN = 36;
412
413
414 /** Encryption information total size for 5.7.11: magic number + master_key_id +
415 key + iv + checksum */
416 static const ulint ENCRYPTION_INFO_SIZE_V1 = (ENCRYPTION_MAGIC_SIZE \
417 + (ENCRYPTION_KEY_LEN * 2) \
418 + 2 * sizeof(ulint));
419
420 /** Encryption information total size: magic number + master_key_id +
421 key + iv + server_uuid + checksum */
422 static const ulint ENCRYPTION_INFO_SIZE_V2 = (ENCRYPTION_MAGIC_SIZE \
423 + (ENCRYPTION_KEY_LEN * 2) \
424 + ENCRYPTION_SERVER_UUID_LEN \
425 + 2 * sizeof(ulint));
426
427 class IORequest;
428
429 static const char ENCRYPTION_DEFAULT_MASTER_KEY[] = "DefaultMasterKey";
430 static const ulint ENCRYPTION_DEFAULT_MASTER_KEY_ID = 0;
431
432 /** Encryption algorithm. */
433 struct Encryption {
434
435 /** Algorithm types supported */
436 enum Type {
437
438 /** No encryption */
439 NONE = 0,
440
441 /** Use AES */
442 AES = 1,
443
444 KEYRING = 2
445 };
446
447 enum Encryption_rotation
448 {
449 NO_ROTATION,
450 MASTER_KEY_TO_KEYRING
451 };
452
453
454 /** Encryption information format version */
455 enum Version {
456
457 /** Version in 5.7.11 */
458 ENCRYPTION_VERSION_1 = 0,
459
460 /** Version in > 5.7.11 */
461 ENCRYPTION_VERSION_2 = 1,
462
463 /** Version in > 5.7.29 */
464 ENCRYPTION_VERSION_3 = 2,
465 };
466
467 /** Default constructor */
EncryptionEncryption468 Encryption():
469 m_type(NONE),
470 m_key(NULL),
471 m_klen(0),
472 m_key_allocated(false),
473 m_iv(NULL),
474 m_tablespace_iv(NULL),
475 m_tablespace_key(NULL),
476 m_key_version(0),
477 m_key_id(0),
478 m_checksum(0),
479 m_encryption_rotation(NO_ROTATION)
480 {}
481
482 /** Specific constructor
483 @param[in] type Algorithm type */
EncryptionEncryption484 explicit Encryption(Type type):
485 m_type(type),
486 m_key(NULL),
487 m_klen(0),
488 m_key_allocated(false),
489 m_iv(NULL),
490 m_tablespace_iv(NULL),
491 m_tablespace_key(NULL),
492 m_key_version(0),
493 m_key_id(0),
494 m_checksum(0),
495 m_encryption_rotation(NO_ROTATION)
496 {
497 #ifdef UNIV_DEBUG
498 switch (m_type) {
499 case NONE:
500 case AES:
501
502 default:
503 ut_error;
504 }
505 #endif /* UNIV_DEBUG */
506 }
507
508 /** Copy constructor */
EncryptionEncryption509 Encryption(const Encryption& other):
510 m_type(other.m_type),
511 m_key(other.m_key),
512 m_klen(other.m_klen),
513 m_key_allocated(other.m_key_allocated),
514 m_iv(other.m_iv),
515 m_tablespace_iv(other.m_tablespace_iv),
516 m_tablespace_key(other.m_tablespace_key),
517 m_key_version(other.m_key_version),
518 m_key_id(other.m_key_id),
519 m_checksum(other.m_checksum),
520 m_encryption_rotation(other.m_encryption_rotation)
521 {
522 if (other.m_key_allocated && other.m_key != NULL)
523 m_key = static_cast<byte *>(
524 my_memdup(PSI_NOT_INSTRUMENTED,
525 other.m_key, other.m_klen, MYF(0)));
526 }
527
528 Encryption& operator = (const Encryption& other) {
529 Encryption tmp(other);
530 swap(tmp);
531 return *this;
532 }
533
swapEncryption534 void swap(Encryption& other) {
535 std::swap(m_type, other.m_type);
536 std::swap(m_key, other.m_key);
537 std::swap(m_klen, other.m_klen);
538 std::swap(m_key_allocated, other.m_key_allocated);
539 std::swap(m_iv, other.m_iv);
540 std::swap(m_tablespace_iv, other.m_tablespace_iv);
541 std::swap(m_tablespace_key, other.m_tablespace_key);
542 std::swap(m_key_version, other.m_key_version);
543 std::swap(m_key_id, other.m_key_id);
544 std::swap(m_checksum, other.m_checksum);
545 std::swap(m_encryption_rotation, other.m_encryption_rotation);
546 }
547
~EncryptionEncryption548 ~Encryption() {
549 if (m_key_allocated && m_key != NULL)
550 my_free(m_key);
551 }
552
set_keyEncryption553 void set_key(byte *key, ulint key_len, bool allocated) {
554 if (m_key_allocated && m_key != NULL)
555 my_free(m_key);
556 m_key = key;
557 m_klen = key_len;
558 m_key_allocated = allocated;
559 }
560
561 /** Check if page is encrypted page or not
562 @param[in] page page which need to check
563 @return true if it is a encrypted page */
564 static bool is_encrypted_page(const byte* page)
565 MY_ATTRIBUTE((warn_unused_result));
566
567 /** Check if a log block is encrypted or not
568 @param[in] block block which need to check
569 @return true if it is an encrypted block */
570 static bool is_encrypted_log(const byte* block)
571 MY_ATTRIBUTE((warn_unused_result));
572
573 /** Check the encryption option and set it
574 @param[in] option encryption option
575 @param[in/out] encryption The encryption type
576 @return DB_SUCCESS or DB_UNSUPPORTED */
577 dberr_t set_algorithm(const char* option, Encryption* type)
578 MY_ATTRIBUTE((warn_unused_result));
579
580 /** Validate the algorithm string.
581 @param[in] algorithm Encryption algorithm to check
582 @return DB_SUCCESS or error code */
583 static dberr_t validate(const char* algorithm)
584 MY_ATTRIBUTE((warn_unused_result));
585
586 /** Convert to a "string".
587 @param[in] type The encryption type
588 @return the string representation */
589 static const char* to_string(Type type)
590 MY_ATTRIBUTE((warn_unused_result));
591
592 /** Check if the string is "" or "n".
593 @param[in] algorithm Encryption algorithm to check
594 @return true if no algorithm requested */
595 static bool is_none(const char* algorithm)
596 MY_ATTRIBUTE((warn_unused_result));
597
598 static bool is_master_key_encryption(const char* algorithm)
599 MY_ATTRIBUTE((warn_unused_result));
600
601 static bool is_no(const char* algorithm)
602 MY_ATTRIBUTE((warn_unused_result));
603
604 static bool is_empty(const char* algorithm)
605 MY_ATTRIBUTE((warn_unused_result));
606
607 static bool is_keyring(const char *algoritm)
608 MY_ATTRIBUTE((warn_unused_result));
609
610 /** Generate random encryption value for key and iv.
611 @param[in,out] value Encryption value */
612 static void random_value(byte* value);
613
614 //TODO:Robert: Czy to powinno być tutaj robione ?
615 static void create_tablespace_key(byte** tablespace_key,
616 uint key_id);
617
618 /** Create new master key for key rotation.
619 @param[in,out] master_key master key */
620 static void create_master_key(byte** master_key);
621
622 static bool tablespace_key_exists_or_create_new_one_if_does_not_exist(uint key_id);
623
624 static bool tablespace_key_exists(uint key_id);
625
626 static bool is_encrypted_and_compressed(const byte *page);
627
628 static uint encryption_get_latest_version(uint key_id);
629
630 //TODO:Robert: Te dwa są potrzebne.
631 static void get_latest_tablespace_key(uint key_id,
632 uint *tablespace_key_version,
633 byte** tablespace_key);
634
635
636 static void get_latest_tablespace_key_or_create_new_one(uint key_id,
637 uint *tablespace_key_version,
638 byte** tablespace_key);
639
640 static bool get_tablespace_key(uint key_id,
641 uint tablespace_key_version,
642 byte** tablespace_key,
643 size_t *key_len);
644
645 /** Get master key by key id.
646 @param[in] master_key_id master key id
647 @param[in] srv_uuid uuid of server instance
648 @param[in,out] master_key master key */
649 static void get_master_key(ulint master_key_id,
650 char* srv_uuid,
651 byte** master_key);
652
653 /** Get current master key and key id.
654 @param[in,out] master_key_id master key id
655 @param[in,out] master_key master key
656 @param[in,out] version encryption information version */
657 static void get_master_key(ulint* master_key_id,
658 byte** master_key,
659 Encryption::Version* version);
660
661 static bool is_keyring_alive();
662
663 static bool can_page_be_keyring_encrypted(ulint page_type);
664 static bool can_page_be_keyring_encrypted(byte* page);
665
666 /** Fill the encryption information.
667 @param[in] key encryption key
668 @param[in] iv encryption iv
669 @param[in,out] encrypt_info encryption information
670 @return true if success. */
671 MY_NODISCARD
672 static bool fill_encryption_info(byte* key,
673 byte* iv,
674 byte* encrypt_info);
675
676 /** Decoding the encryption info from the first page of a tablespace.
677 @param[in,out] key key
678 @param[in,out] iv iv
679 @param[in] encryption_info encrytion info.
680 @return true if success */
681 MY_NODISCARD
682 static bool decode_encryption_info(byte* key,
683 byte* iv,
684 byte* encryption_info);
685
686 /** Encrypt the redo log block.
687 @param[in] type IORequest
688 @param[in,out] src_ptr log block which need to encrypt
689 @param[in,out] dst_ptr destination area
690 @return true if success. */
691 MY_NODISCARD
692 bool encrypt_log_block(
693 const IORequest& type,
694 byte* src_ptr,
695 byte* dst_ptr);
696
697 /** Encrypt the redo log data contents.
698 @param[in] type IORequest
699 @param[in,out] src page data which need to encrypt
700 @param[in] src_len size of the source in bytes
701 @param[in,out] dst destination area
702 @param[in,out] dst_len size of the destination in bytes
703 @return buffer data, dst_len will have the length of the data */
704 MY_NODISCARD
705 byte* encrypt_log(
706 const IORequest& type,
707 byte* src,
708 ulint src_len,
709 byte* dst,
710 ulint* dst_len);
711
712 /** Encrypt the page data contents. Page type can't be
713 FIL_PAGE_ENCRYPTED, FIL_PAGE_COMPRESSED_AND_ENCRYPTED,
714 FIL_PAGE_ENCRYPTED_RTREE.
715 @param[in] type IORequest
716 @param[in,out] src page data which need to encrypt
717 @param[in] src_len Size of the source in bytes
718 @param[in,out] dst destination area
719 @param[in,out] dst_len Size of the destination in bytes
720 @return buffer data, dst_len will have the length of the data */
721 byte* encrypt(
722 const IORequest& type,
723 byte* src,
724 ulint src_len,
725 byte* dst,
726 ulint* dst_len)
727 MY_ATTRIBUTE((warn_unused_result));
728
729 /** Decrypt the log block.
730 @param[in] type IORequest
731 @param[in,out] src data read from disk, decrypted data will be
732 copied to this page
733 @param[in,out] dst scratch area to use for decryption
734 @return DB_SUCCESS or error code */
735 MY_NODISCARD
736 dberr_t decrypt_log_block(
737 const IORequest& type,
738 byte* src,
739 byte* dst);
740
741 /** Decrypt the log data contents.
742 @param[in] type IORequest
743 @param[in,out] src data read from disk, decrypted data will be
744 copied to this page
745 @param[in] src_len source data length
746 @param[in,out] dst scratch area to use for decryption
747 @param[in] dst_len size of the scratch area in bytes
748 @return DB_SUCCESS or error code */
749 MY_NODISCARD
750 dberr_t decrypt_log(
751 const IORequest& type,
752 byte* src,
753 ulint src_len,
754 byte* dst,
755 ulint dst_len);
756
757 /** Decrypt the page data contents. Page type must be
758 FIL_PAGE_ENCRYPTED, FIL_PAGE_COMPRESSED_AND_ENCRYPTED,
759 FIL_PAGE_ENCRYPTED_RTREE, if not then the source contents are
760 left unchanged and DB_SUCCESS is returned.
761 @param[in] type IORequest
762 @param[in,out] src Data read from disk, decrypt
763 data will be copied to this page
764 @param[in] src_len source data length
765 @param[in,out] dst Scratch area to use for decrypt
766 @param[in] dst_len Size of the scratch area in bytes
767 @return DB_SUCCESS or error code */
768 dberr_t decrypt(
769 const IORequest& type,
770 byte* src,
771 ulint src_len,
772 byte* dst,
773 ulint dst_len)
774 MY_ATTRIBUTE((warn_unused_result));
775
776 #ifndef UNIV_INNOCHECKSUM
777 /** Check if keyring plugin loaded. */
778 static bool MY_ATTRIBUTE((warn_unused_result)) check_keyring();
779 #endif
780
781 /** Encrypt type */
782 Type m_type;
783
784 /** Encrypt key */
785 byte* m_key;
786
787 /** Encrypt key length*/
788 ulint m_klen;
789
790 /** Encrypt key allocated */
791 bool m_key_allocated;
792
793 /** Encrypt initial vector */
794 byte* m_iv;
795
796 // We decide as the last step in decrypt (after reading the page)
797 // when re_encryption_type is MK_TO_RK whether page is
798 // encrypted with MK or RK => thus we do not know which tablespace_iv we are
799 // going to use RK or MK
800 byte* m_tablespace_iv;
801
802 byte* m_tablespace_key;
803
804 uint m_key_version;
805
806 uint m_key_id;
807
808 uint32 m_checksum;
809
810 //mutable bool m_was_page_encrypted_when_read;
811
812 /** Current master key id */
813 static ulint master_key_id;
814
815 /** Current uuid of server instance */
816 static char uuid[ENCRYPTION_SERVER_UUID_LEN + 1];
817
818 Encryption_rotation m_encryption_rotation;
819 private:
820 //TODO: Robert: Is it needed here?
821 static void get_keyring_key(const char *key_name, byte** key, size_t *key_len);
822
823 static void get_latest_system_key(const char *system_key_name, byte **key, uint *key_version,
824 size_t *key_length);
825
826 static void fill_key_name(char *key_name, uint key_id);
827
828 static void fill_key_name(char* key_name, uint key_id, uint key_version);
829 };
830
831 /** Types for AIO operations @{ */
832
833 /** No transformations during read/write, write as is. */
834 #define IORequestRead IORequest(IORequest::READ)
835 #define IORequestWrite IORequest(IORequest::WRITE)
836 #define IORequestLogRead IORequest(IORequest::LOG | IORequest::READ)
837 #define IORequestLogWrite IORequest(IORequest::LOG | IORequest::WRITE)
838
839 struct Zip_compressed_info
840 {
841 bool is_zip_compressed;
842 };
843
844 /**
845 The IO Context that is passed down to the low level IO code */
846 class IORequest {
847 public:
848 /** Flags passed in the request, they can be ORred together. */
849 enum {
850 READ = 1,
851 WRITE = 2,
852
853 /** Double write buffer recovery. */
854 DBLWR_RECOVER = 4,
855
856 /** Enumarations below can be ORed to READ/WRITE above*/
857
858 /** Data file */
859 DATA_FILE = 8,
860
861 /** Log file request*/
862 LOG = 16,
863
864 /** Disable partial read warnings */
865 DISABLE_PARTIAL_IO_WARNINGS = 32,
866
867 /** Do not to wake i/o-handler threads, but the caller will do
868 the waking explicitly later, in this way the caller can post
869 several requests in a batch; NOTE that the batch must not be
870 so big that it exhausts the slots in AIO arrays! NOTE that
871 a simulated batch may introduce hidden chances of deadlocks,
872 because I/Os are not actually handled until all
873 have been posted: use with great caution! */
874 DO_NOT_WAKE = 64,
875
876 /** Ignore failed reads of non-existent pages */
877 IGNORE_MISSING = 128,
878
879 /** Use punch hole if available, only makes sense if
880 compression algorithm != NONE. Ignored if not set */
881 PUNCH_HOLE = 256,
882
883 /** Force raw read, do not try to compress/decompress.
884 This can be used to force a read and write without any
885 compression e.g., for redo log, merge sort temporary files
886 and the truncate redo log. */
887 NO_COMPRESSION = 512,
888
889 /** Row log used in online DDL */
890 ROW_LOG = 1024,
891
892 /** Force write of decrypted pages in encrypted tablespace. */
893 NO_ENCRYPTION = 2048
894 };
895
896 /** Default constructor */
IORequest()897 IORequest()
898 :
899 m_block_size(UNIV_SECTOR_SIZE),
900 m_type(READ),
901 m_compression(),
902 m_encryption(),
903 m_is_page_zip_compressed(false),
904 m_zip_page_physical_size(0)
905 {
906 /* No op */
907 }
908
909 /**
910 @param[in] type Request type, can be a value that is
911 ORed from the above enum */
IORequest(ulint type)912 explicit IORequest(ulint type)
913 :
914 m_block_size(UNIV_SECTOR_SIZE),
915 m_type(static_cast<uint16_t>(type)),
916 m_compression(),
917 m_encryption(),
918 m_is_page_zip_compressed(false),
919 m_zip_page_physical_size(0)
920 {
921 if (is_log() || is_row_log()) {
922 disable_compression();
923 }
924
925 if (!is_punch_hole_supported()) {
926 clear_punch_hole();
927 }
928 }
929
930 /** Destructor */
~IORequest()931 ~IORequest() { }
932
933 /** @return true if ignore missing flag is set */
ignore_missing(ulint type)934 static bool ignore_missing(ulint type)
935 MY_ATTRIBUTE((warn_unused_result))
936 {
937 return((type & IGNORE_MISSING) == IGNORE_MISSING);
938 }
939
940 /** @return true if it is a read request */
is_read()941 bool is_read() const
942 MY_ATTRIBUTE((warn_unused_result))
943 {
944 return((m_type & READ) == READ);
945 }
946
947 /** @return true if it is a write request */
is_write()948 bool is_write() const
949 MY_ATTRIBUTE((warn_unused_result))
950 {
951 return((m_type & WRITE) == WRITE);
952 }
953
954 /** @return true if it is a redo log write */
is_log()955 bool is_log() const
956 MY_ATTRIBUTE((warn_unused_result))
957 {
958 return((m_type & LOG) == LOG);
959 }
960
961 /** @return true if it is a row log entry used in online DDL */
is_row_log()962 bool is_row_log() const
963 MY_ATTRIBUTE((warn_unused_result))
964 {
965 return((m_type & ROW_LOG) == ROW_LOG);
966 }
967
968 /** @return true if the simulated AIO thread should be woken up */
is_wake()969 bool is_wake() const
970 MY_ATTRIBUTE((warn_unused_result))
971 {
972 return((m_type & DO_NOT_WAKE) == 0);
973 }
974
975 /** @return true if partial read warning disabled */
is_partial_io_warning_disabled()976 bool is_partial_io_warning_disabled() const
977 MY_ATTRIBUTE((warn_unused_result))
978 {
979 return((m_type & DISABLE_PARTIAL_IO_WARNINGS)
980 == DISABLE_PARTIAL_IO_WARNINGS);
981 }
982
983 /** Disable partial read warnings */
disable_partial_io_warnings()984 void disable_partial_io_warnings()
985 {
986 m_type |= DISABLE_PARTIAL_IO_WARNINGS;
987 }
988
989 /** @return true if missing files should be ignored */
ignore_missing()990 bool ignore_missing() const
991 MY_ATTRIBUTE((warn_unused_result))
992 {
993 return(ignore_missing(m_type));
994 }
995
996 /** @return true if punch hole should be used */
punch_hole()997 bool punch_hole() const
998 MY_ATTRIBUTE((warn_unused_result))
999 {
1000 return((m_type & PUNCH_HOLE) == PUNCH_HOLE);
1001 }
1002
1003 /** @return true if the read should be validated */
validate()1004 bool validate() const
1005 MY_ATTRIBUTE((warn_unused_result))
1006 {
1007 ut_a(is_read() ^ is_write());
1008
1009 return(!is_read() || !punch_hole());
1010 }
1011
1012 /** Set the punch hole flag */
set_punch_hole()1013 void set_punch_hole()
1014 {
1015 if (is_punch_hole_supported()) {
1016 m_type |= PUNCH_HOLE;
1017 }
1018 }
1019
1020 /** Clear the do not wake flag */
clear_do_not_wake()1021 void clear_do_not_wake()
1022 {
1023 m_type &= ~DO_NOT_WAKE;
1024 }
1025
1026 /** Clear the punch hole flag */
clear_punch_hole()1027 void clear_punch_hole()
1028 {
1029 m_type &= ~PUNCH_HOLE;
1030 }
1031
1032 /** @return the block size to use for IO */
block_size()1033 ulint block_size() const
1034 MY_ATTRIBUTE((warn_unused_result))
1035 {
1036 return(m_block_size);
1037 }
1038
1039 /** Set the block size for IO
1040 @param[in] block_size Block size to set */
block_size(ulint block_size)1041 void block_size(ulint block_size)
1042 {
1043 m_block_size = static_cast<uint32_t>(block_size);
1044 }
1045
1046 /** Clear all compression related flags */
clear_compressed()1047 void clear_compressed()
1048 {
1049 clear_punch_hole();
1050
1051 m_compression.m_type = Compression::NONE;
1052 }
1053
1054 /** Compare two requests
1055 @reutrn true if the are equal */
1056 bool operator==(const IORequest& rhs) const
1057 {
1058 return(m_type == rhs.m_type);
1059 }
1060
1061 /** Set compression algorithm
1062 @param[in] compression The compression algorithm to use */
compression_algorithm(Compression::Type type)1063 void compression_algorithm(Compression::Type type)
1064 {
1065 if (type == Compression::NONE) {
1066 return;
1067 }
1068
1069 set_punch_hole();
1070
1071 m_compression.m_type = type;
1072 }
1073
1074 /** Get the compression algorithm.
1075 @return the compression algorithm */
compression_algorithm()1076 Compression compression_algorithm() const
1077 MY_ATTRIBUTE((warn_unused_result))
1078 {
1079 return(m_compression);
1080 }
1081
1082 /** @return true if the page should be compressed */
is_compressed()1083 bool is_compressed() const
1084 MY_ATTRIBUTE((warn_unused_result))
1085 {
1086 return(compression_algorithm().m_type != Compression::NONE);
1087 }
1088
mark_page_zip_compressed()1089 void mark_page_zip_compressed()
1090 {
1091 m_is_page_zip_compressed = true;
1092 }
1093
is_page_zip_compressed()1094 bool is_page_zip_compressed() const
1095 MY_ATTRIBUTE((warn_unused_result))
1096 {
1097 return m_is_page_zip_compressed;
1098 }
1099
get_zip_page_physical_size()1100 ulint get_zip_page_physical_size() const
1101 {
1102 return m_zip_page_physical_size;
1103 }
1104
set_zip_page_physical_size(ulint zip_page_physical_size)1105 void set_zip_page_physical_size(ulint zip_page_physical_size)
1106 {
1107 m_zip_page_physical_size = zip_page_physical_size;
1108 }
1109
1110 /** @return true if the page read should not be transformed. */
is_compression_enabled()1111 bool is_compression_enabled() const
1112 MY_ATTRIBUTE((warn_unused_result))
1113 {
1114 return((m_type & NO_COMPRESSION) == 0);
1115 }
1116
1117 /** @return true if the page write should not be encrypted */
is_encryption_disabled()1118 bool is_encryption_disabled() const MY_NODISCARD
1119 {
1120 return((m_type & NO_ENCRYPTION) != 0);
1121 }
1122
1123 /** Disable transformations. */
disable_compression()1124 void disable_compression()
1125 {
1126 m_type |= NO_COMPRESSION;
1127 }
1128
1129 /** Disable encryption of a page in encrypted tablespace */
disable_encryption()1130 void disable_encryption()
1131 {
1132 m_type |= NO_ENCRYPTION;
1133 }
1134
1135 /** Set encryption algorithm
1136 @param[in] type The encryption algorithm to use */
encryption_algorithm(Encryption::Type type)1137 void encryption_algorithm(Encryption::Type type)
1138 {
1139 if (type == Encryption::NONE) {
1140 return;
1141 }
1142
1143 m_encryption.m_type = type;
1144 }
1145
1146 /** Set encryption key and iv
1147 @param[in] key The encryption key to use
1148 @param[in] key_len length of the encryption key
1149 @param[in] iv The encryption iv to use */
encryption_key(byte * key,ulint key_len,bool key_allocated,byte * iv,uint key_version,uint key_id,byte * tablespace_iv,byte * tablespace_key)1150 void encryption_key(byte* key,
1151 ulint key_len,
1152 bool key_allocated,
1153 byte* iv,
1154 uint key_version,
1155 uint key_id,
1156 byte *tablespace_iv,
1157 byte *tablespace_key)
1158 {
1159 //ut_ad(m_encryption.m_key == NULL); //TODO:Robert need to make sure I am not overriding memory here
1160 m_encryption.set_key(key, key_len, key_allocated);
1161 m_encryption.m_iv = iv;
1162 m_encryption.m_key_version = key_version;
1163 m_encryption.m_key_id = key_id;
1164 m_encryption.m_tablespace_iv = tablespace_iv;
1165 m_encryption.m_tablespace_key = tablespace_key;
1166 }
1167
encryption_rotation(Encryption::Encryption_rotation encryption_rotation)1168 void encryption_rotation(Encryption::Encryption_rotation encryption_rotation)
1169 {
1170 m_encryption.m_encryption_rotation = encryption_rotation;
1171 }
1172
1173 /** Get the encryption algorithm.
1174 @return the encryption algorithm */
encryption_algorithm()1175 Encryption encryption_algorithm() const
1176 MY_ATTRIBUTE((warn_unused_result))
1177 {
1178 return(m_encryption);
1179 }
1180
1181 /** @return true if the page should be encrypted. */
is_encrypted()1182 bool is_encrypted() const
1183 MY_ATTRIBUTE((warn_unused_result))
1184 {
1185 return(m_encryption.m_type != Encryption::NONE);
1186 }
1187
1188 /** Clear all encryption related flags */
clear_encrypted()1189 void clear_encrypted()
1190 {
1191 m_encryption.set_key(NULL, 0, false);
1192 m_encryption.m_iv = NULL;
1193 m_encryption.m_type = Encryption::NONE;
1194 m_encryption.m_encryption_rotation = Encryption::NO_ROTATION;
1195 m_encryption.m_tablespace_iv = NULL;
1196 m_encryption.m_key_id = 0;
1197 m_encryption.m_tablespace_key = NULL;
1198 }
1199
1200 //bool was_page_encrypted_when_read() const
1201 //{
1202 //return m_encryption.m_was_page_encrypted_when_read;
1203 //}
1204
1205 //void set_that_page_was_encrypted_when_read() const
1206 //{
1207 //m_encryption.m_was_page_encrypted_when_read = true;
1208 //}
1209
1210 /** Note that the IO is for double write recovery. */
dblwr_recover()1211 void dblwr_recover()
1212 {
1213 m_type |= DBLWR_RECOVER;
1214 }
1215
1216 /** @return true if the request is from the dblwr recovery */
is_dblwr_recover()1217 bool is_dblwr_recover() const
1218 MY_ATTRIBUTE((warn_unused_result))
1219 {
1220 return((m_type & DBLWR_RECOVER) == DBLWR_RECOVER);
1221 }
1222
1223 /** @return true if punch hole is supported */
is_punch_hole_supported()1224 static bool is_punch_hole_supported()
1225 {
1226
1227 /* In this debugging mode, we act as if punch hole is supported,
1228 and then skip any calls to actually punch a hole here.
1229 In this way, Transparent Page Compression is still being tested. */
1230 DBUG_EXECUTE_IF("ignore_punch_hole",
1231 return(true);
1232 );
1233
1234 #if defined(HAVE_FALLOC_PUNCH_HOLE_AND_KEEP_SIZE) || defined(_WIN32)
1235 return(true);
1236 #else
1237 return(false);
1238 #endif /* HAVE_FALLOC_PUNCH_HOLE_AND_KEEP_SIZE || _WIN32 */
1239 }
1240
1241 //bool will_encrypt_page()
1242 //{
1243 //return m_encryption.key != NULL;
1244 //}
1245
1246 private:
1247 /* File system best block size */
1248 uint32_t m_block_size;
1249
1250 /** Request type bit flags */
1251 uint16_t m_type;
1252
1253 /** Compression algorithm */
1254 Compression m_compression;
1255
1256 /** Encryption algorithm */
1257 Encryption m_encryption;
1258
1259 bool m_is_page_zip_compressed;
1260
1261 ulint m_zip_page_physical_size;
1262 };
1263
1264 /* @} */
1265
1266 /** Sparse file size information. */
1267 struct os_file_size_t {
1268 /** Total size of file in bytes */
1269 os_offset_t m_total_size;
1270
1271 /** If it is a sparse file then this is the number of bytes
1272 actually allocated for the file. */
1273 os_offset_t m_alloc_size;
1274 };
1275
1276 /** Win NT does not allow more than 64 */
1277 static const ulint OS_AIO_N_PENDING_IOS_PER_THREAD = 32;
1278
1279 /** Modes for aio operations @{ */
1280 /** Normal asynchronous i/o not for ibuf pages or ibuf bitmap pages */
1281 static const ulint OS_AIO_NORMAL = 21;
1282
1283 /** Asynchronous i/o for ibuf pages or ibuf bitmap pages */
1284 static const ulint OS_AIO_IBUF = 22;
1285
1286 /** Asynchronous i/o for the log */
1287 static const ulint OS_AIO_LOG = 23;
1288
1289 /** Asynchronous i/o where the calling thread will itself wait for
1290 the i/o to complete, doing also the job of the i/o-handler thread;
1291 can be used for any pages, ibuf or non-ibuf. This is used to save
1292 CPU time, as we can do with fewer thread switches. Plain synchronous
1293 I/O is not as good, because it must serialize the file seek and read
1294 or write, causing a bottleneck for parallelism. */
1295 static const ulint OS_AIO_SYNC = 24;
1296 /* @} */
1297
1298 extern ulint os_n_file_reads;
1299 extern ulint os_n_file_writes;
1300 extern ulint os_n_fsyncs;
1301
1302 /* File types for directory entry data type */
1303
1304 enum os_file_type_t {
1305 OS_FILE_TYPE_UNKNOWN = 0,
1306 OS_FILE_TYPE_FILE, /* regular file */
1307 OS_FILE_TYPE_DIR, /* directory */
1308 OS_FILE_TYPE_LINK, /* symbolic link */
1309 OS_FILE_TYPE_BLOCK /* block device */
1310 };
1311
1312 /* Maximum path string length in bytes when referring to tables with in the
1313 './databasename/tablename.ibd' path format; we can allocate at least 2 buffers
1314 of this size from the thread stack; that is why this should not be made much
1315 bigger than 4000 bytes. The maximum path length used by any storage engine
1316 in the server must be at least this big. */
1317 #define OS_FILE_MAX_PATH 4000
1318 #if (FN_REFLEN_SE < OS_FILE_MAX_PATH)
1319 # error "(FN_REFLEN_SE < OS_FILE_MAX_PATH)"
1320 #endif
1321
1322 /** Struct used in fetching information of a file in a directory */
1323 struct os_file_stat_t {
1324 char name[OS_FILE_MAX_PATH]; /*!< path to a file */
1325 os_file_type_t type; /*!< file type */
1326 os_offset_t size; /*!< file size in bytes */
1327 os_offset_t alloc_size; /*!< Allocated size for
1328 sparse files in bytes */
1329 size_t block_size; /*!< Block size to use for IO
1330 in bytes*/
1331 time_t ctime; /*!< creation time */
1332 time_t mtime; /*!< modification time */
1333 time_t atime; /*!< access time */
1334 bool rw_perm; /*!< true if can be opened
1335 in read-write mode. Only valid
1336 if type == OS_FILE_TYPE_FILE */
1337 };
1338
1339 #ifndef UNIV_HOTBACKUP
1340 /** Create a temporary file. This function is like tmpfile(3), but
1341 the temporary file is created in the given parameter path. If the path
1342 is null then it will create the file in the mysql server configuration
1343 parameter (--tmpdir).
1344 @param[in] path location for creating temporary file
1345 @return temporary file handle, or NULL on error */
1346 FILE*
1347 os_file_create_tmpfile(
1348 const char* path);
1349 #endif /* !UNIV_HOTBACKUP */
1350
1351 /** The os_file_opendir() function opens a directory stream corresponding to the
1352 directory named by the dirname argument. The directory stream is positioned
1353 at the first entry. In both Unix and Windows we automatically skip the '.'
1354 and '..' items at the start of the directory listing.
1355
1356 @param[in] dirname directory name; it must not contain a trailing
1357 '\' or '/'
1358 @param[in] is_fatal true if we should treat an error as a fatal
1359 error; if we try to open symlinks then we do
1360 not wish a fatal error if it happens not to be
1361 a directory
1362 @return directory stream, NULL if error */
1363 os_file_dir_t
1364 os_file_opendir(
1365 const char* dirname,
1366 bool is_fatal);
1367
1368 /**
1369 Closes a directory stream.
1370 @param[in] dir directory stream
1371 @return 0 if success, -1 if failure */
1372 int
1373 os_file_closedir(
1374 os_file_dir_t dir);
1375
1376 /** This function returns information of the next file in the directory. We jump
1377 over the '.' and '..' entries in the directory.
1378 @param[in] dirname directory name or path
1379 @param[in] dir directory stream
1380 @param[out] info buffer where the info is returned
1381 @return 0 if ok, -1 if error, 1 if at the end of the directory */
1382 int
1383 os_file_readdir_next_file(
1384 const char* dirname,
1385 os_file_dir_t dir,
1386 os_file_stat_t* info);
1387
1388 /**
1389 This function attempts to create a directory named pathname. The new directory
1390 gets default permissions. On Unix, the permissions are (0770 & ~umask). If the
1391 directory exists already, nothing is done and the call succeeds, unless the
1392 fail_if_exists arguments is true.
1393
1394 @param[in] pathname directory name as null-terminated string
1395 @param[in] fail_if_exists if true, pre-existing directory is treated
1396 as an error.
1397 @return true if call succeeds, false on error */
1398 bool
1399 os_file_create_directory(
1400 const char* pathname,
1401 bool fail_if_exists);
1402
1403 /** NOTE! Use the corresponding macro os_file_create_simple(), not directly
1404 this function!
1405 A simple function to open or create a file.
1406 @param[in] name name of the file or path as a null-terminated
1407 string
1408 @param[in] create_mode create mode
1409 @param[in] access_type OS_FILE_READ_ONLY or OS_FILE_READ_WRITE
1410 @param[in] read_only if true read only mode checks are enforced
1411 @param[out] success true if succeed, false if error
1412 @return own: handle to the file, not defined if error, error number
1413 can be retrieved with os_file_get_last_error */
1414 pfs_os_file_t
1415 os_file_create_simple_func(
1416 const char* name,
1417 ulint create_mode,
1418 ulint access_type,
1419 bool read_only,
1420 bool* success);
1421
1422 /** NOTE! Use the corresponding macro
1423 os_file_create_simple_no_error_handling(), not directly this function!
1424 A simple function to open or create a file.
1425 @param[in] name name of the file or path as a null-terminated string
1426 @param[in] create_mode create mode
1427 @param[in] access_type OS_FILE_READ_ONLY, OS_FILE_READ_WRITE, or
1428 OS_FILE_READ_ALLOW_DELETE; the last option
1429 is used by a backup program reading the file
1430 @param[in] read_only if true read only mode checks are enforced
1431 @param[out] success true if succeeded
1432 @return own: handle to the file, not defined if error, error number
1433 can be retrieved with os_file_get_last_error */
1434 pfs_os_file_t
1435 os_file_create_simple_no_error_handling_func(
1436 const char* name,
1437 ulint create_mode,
1438 ulint access_type,
1439 bool read_only,
1440 bool* success)
1441 MY_ATTRIBUTE((warn_unused_result));
1442
1443 /** Tries to disable OS caching on an opened file descriptor.
1444 @param[in] fd file descriptor to alter
1445 @param[in] file_name file name, used in the diagnostic message
1446 @param[in] name "open" or "create"; used in the diagnostic
1447 message
1448 @param[in] failure_warning if true (the default), the failure to disable
1449 caching is diagnosed at warning severity, and at note severity otherwise
1450 @return true if operation is success and false */
1451 bool
1452 os_file_set_nocache(
1453 int fd,
1454 const char* file_name,
1455 const char* operation_name,
1456 bool failure_warning = true);
1457
1458 /** Tries to disable OS caching on an opened file file.
1459 @param[in] file file to alter
1460 @param[in] file_name file name, used in the diagnostic message
1461 @param[in] name "open" or "create"; used in the diagnostic
1462 message
1463 @param[in] failure_warning if true (the default), the failure to disable
1464 caching is diagnosed at warning severity, and at note severity otherwise
1465 @return true if operation is success and false */
1466 UNIV_INLINE
1467 bool
1468 os_file_set_nocache(
1469 pfs_os_file_t file,
1470 const char* file_name,
1471 const char* operation_name,
1472 bool failure_warning = true);
1473
1474 /** NOTE! Use the corresponding macro os_file_create(), not directly
1475 this function!
1476 Opens an existing file or creates a new.
1477 @param[in] name name of the file or path as a null-terminated
1478 string
1479 @param[in] create_mode create mode
1480 @param[in] purpose OS_FILE_AIO, if asynchronous, non-buffered I/O
1481 is desired, OS_FILE_NORMAL, if any normal file;
1482 NOTE that it also depends on type, os_aio_..
1483 and srv_.. variables whether we really use
1484 async I/O or unbuffered I/O: look in the
1485 function source code for the exact rules
1486 @param[in] type OS_DATA_FILE or OS_LOG_FILE
1487 @param[in] read_only if true read only mode checks are enforced
1488 @param[in] success true if succeeded
1489 @return own: handle to the file, not defined if error, error number
1490 can be retrieved with os_file_get_last_error */
1491 pfs_os_file_t
1492 os_file_create_func(
1493 const char* name,
1494 ulint create_mode,
1495 ulint purpose,
1496 ulint type,
1497 bool read_only,
1498 bool* success)
1499 MY_ATTRIBUTE((warn_unused_result));
1500
1501 /** Deletes a file. The file has to be closed before calling this.
1502 @param[in] name file path as a null-terminated string
1503 @return true if success */
1504 bool
1505 os_file_delete_func(const char* name);
1506
1507 /** Deletes a file if it exists. The file has to be closed before calling this.
1508 @param[in] name file path as a null-terminated string
1509 @param[out] exist indicate if file pre-exist
1510 @return true if success */
1511 bool
1512 os_file_delete_if_exists_func(const char* name, bool* exist);
1513
1514 /** NOTE! Use the corresponding macro os_file_rename(), not directly
1515 this function!
1516 Renames a file (can also move it to another directory). It is safest that the
1517 file is closed before calling this function.
1518 @param[in] oldpath old file path as a null-terminated string
1519 @param[in] newpath new file path
1520 @return true if success */
1521 bool
1522 os_file_rename_func(const char* oldpath, const char* newpath);
1523
1524 /** NOTE! Use the corresponding macro os_file_close(), not directly this
1525 function!
1526 Closes a file handle. In case of error, error number can be retrieved with
1527 os_file_get_last_error.
1528 @param[in] file own: handle to a file
1529 @return true if success */
1530 bool
1531 os_file_close_func(os_file_t file);
1532
1533 /** NOTE! Use the corresponding macro os_file_close_no_error_handling(), not
1534 directly this function!
1535 Closes a file handle.
1536 @param[in] file handle to a file
1537 @return true if success */
1538 bool
1539 os_file_close_no_error_handling_func(os_file_t file);
1540
1541 #ifdef UNIV_PFS_IO
1542
1543 /* Keys to register InnoDB I/O with performance schema */
1544 extern mysql_pfs_key_t innodb_data_file_key;
1545 extern mysql_pfs_key_t innodb_log_file_key;
1546 extern mysql_pfs_key_t innodb_temp_file_key;
1547 extern mysql_pfs_key_t innodb_bmp_file_key;
1548 extern mysql_pfs_key_t innodb_parallel_dblwrite_file_key;
1549
1550 /* Following four macros are instumentations to register
1551 various file I/O operations with performance schema.
1552 1) register_pfs_file_open_begin() and register_pfs_file_open_end() are
1553 used to register file creation, opening, closing and renaming.
1554 2) register_pfs_file_rename_begin() and register_pfs_file_rename_end()
1555 are used to register file renaming
1556 3) register_pfs_file_io_begin() and register_pfs_file_io_end() are
1557 used to register actual file read, write and flush
1558 3) register_pfs_file_close_begin() and register_pfs_file_close_end()
1559 are used to register file deletion operations*/
1560 # define register_pfs_file_open_begin(state, locker, key, op, name, \
1561 src_file, src_line) \
1562 do { \
1563 locker = PSI_FILE_CALL(get_thread_file_name_locker)( \
1564 state, key.m_value, op, name, &locker); \
1565 if (locker != NULL) { \
1566 PSI_FILE_CALL(start_file_open_wait)( \
1567 locker, src_file, static_cast<uint>(src_line)); \
1568 } \
1569 } while (0)
1570
1571 # define register_pfs_file_open_end(locker, file, result) \
1572 do { \
1573 if (locker != NULL) { \
1574 file.m_psi = PSI_FILE_CALL( \
1575 end_file_open_wait)( \
1576 locker, result); \
1577 } \
1578 } while (0)
1579
1580 # define register_pfs_file_rename_begin(state, locker, key, op, name, \
1581 src_file, src_line) \
1582 register_pfs_file_open_begin( \
1583 state, locker, key, op, name, \
1584 src_file, static_cast<uint>(src_line)) \
1585
1586 # define register_pfs_file_rename_end(locker, from, to, result) \
1587 do { \
1588 if (locker != NULL) { \
1589 PSI_FILE_CALL( \
1590 end_file_rename_wait)( \
1591 locker, from, to, result); \
1592 } \
1593 }while(0)
1594
1595 # define register_pfs_file_close_begin(state, locker, key, op, name, \
1596 src_file, src_line) \
1597 do { \
1598 locker = PSI_FILE_CALL(get_thread_file_name_locker)( \
1599 state, key.m_value, op, name, &locker); \
1600 if (locker != NULL) { \
1601 PSI_FILE_CALL(start_file_close_wait)( \
1602 locker, src_file, static_cast<uint>(src_line)); \
1603 } \
1604 } while (0)
1605
1606 # define register_pfs_file_close_end(locker, result) \
1607 do { \
1608 if (locker != NULL) { \
1609 PSI_FILE_CALL(end_file_close_wait)( \
1610 locker, result); \
1611 } \
1612 } while (0)
1613
1614 # define register_pfs_file_io_begin(state, locker, file, count, op, \
1615 src_file, src_line) \
1616 do { \
1617 locker = PSI_FILE_CALL(get_thread_file_stream_locker)( \
1618 state, file.m_psi, op); \
1619 if (locker != NULL) { \
1620 PSI_FILE_CALL(start_file_wait)( \
1621 locker, count, \
1622 src_file, static_cast<uint>(src_line)); \
1623 } \
1624 } while (0)
1625
1626 # define register_pfs_file_io_end(locker, count) \
1627 do { \
1628 if (locker != NULL) { \
1629 PSI_FILE_CALL(end_file_wait)(locker, count); \
1630 } \
1631 } while (0)
1632
1633 /* Following macros/functions are file I/O APIs that would be performance
1634 schema instrumented if "UNIV_PFS_IO" is defined. They would point to
1635 wrapper functions with performance schema instrumentation in such case.
1636
1637 os_file_create
1638 os_file_create_simple
1639 os_file_create_simple_no_error_handling
1640 os_file_close
1641 os_file_close_no_error_handling
1642 os_file_rename
1643 os_aio
1644 os_file_read
1645 os_file_read_no_error_handling
1646 os_file_read_no_error_handling_int_fd
1647 os_file_write
1648 os_file_set_eof_at
1649
1650 The wrapper functions have the prefix of "innodb_". */
1651
1652 # define os_file_create(key, name, create, purpose, type, read_only, \
1653 success) \
1654 pfs_os_file_create_func(key, name, create, purpose, type, \
1655 read_only, success, __FILE__, __LINE__)
1656
1657 # define os_file_create_simple(key, name, create, access, \
1658 read_only, success) \
1659 pfs_os_file_create_simple_func(key, name, create, access, \
1660 read_only, success, __FILE__, __LINE__)
1661
1662 # define os_file_create_simple_no_error_handling( \
1663 key, name, create_mode, access, read_only, success) \
1664 pfs_os_file_create_simple_no_error_handling_func( \
1665 key, name, create_mode, access, \
1666 read_only, success, __FILE__, __LINE__)
1667
1668 # define os_file_close_pfs(file) \
1669 pfs_os_file_close_func(file, __FILE__, __LINE__)
1670
1671 # define os_file_close_no_error_handling_pfs(file) \
1672 pfs_os_file_close_no_error_handling_func(file, __FILE__, __LINE__)
1673
1674 # define os_aio(type, mode, name, file, buf, offset, \
1675 n, read_only, message1, message2, space_id, trx, \
1676 should_buffer) \
1677 pfs_os_aio_func(type, mode, name, file, buf, offset, \
1678 n, read_only, message1, message2, space_id, \
1679 trx, should_buffer, __FILE__, __LINE__)
1680
1681 # define os_file_read_pfs(type, file, buf, offset, n) \
1682 pfs_os_file_read_func(type, file, buf, offset, n, NULL, \
1683 __FILE__, __LINE__)
1684
1685 # define os_file_read_trx_pfs(file, buf, offset, n, trx) \
1686 pfs_os_file_read_func(file, buf, offset, n, trx, \
1687 __FILE__, __LINE__)
1688
1689 # define os_file_read_no_error_handling_pfs(type, file, buf, offset, n, o) \
1690 pfs_os_file_read_no_error_handling_func( \
1691 type, file, buf, offset, n, o, __FILE__, __LINE__)
1692
1693 # define os_file_read_no_error_handling_int_fd( \
1694 type, file, buf, offset, n, o) \
1695 pfs_os_file_read_no_error_handling_int_fd_func( \
1696 type, file, buf, offset, n, o, __FILE__, __LINE__)
1697
1698 # define os_file_write_pfs(type, name, file, buf, offset, n) \
1699 pfs_os_file_write_func(type, name, file, buf, offset, \
1700 n, __FILE__, __LINE__)
1701
1702 # define os_file_write_int_fd(type, name, file, buf, offset, n) \
1703 pfs_os_file_write_int_fd_func(type, name, file, buf, offset, \
1704 n, __FILE__, __LINE__)
1705
1706 # define os_file_flush_pfs(file) \
1707 pfs_os_file_flush_func(file, __FILE__, __LINE__)
1708
1709 # define os_file_rename(key, oldpath, newpath) \
1710 pfs_os_file_rename_func(key, oldpath, newpath, __FILE__, __LINE__)
1711
1712 # define os_file_delete(key, name) \
1713 pfs_os_file_delete_func(key, name, __FILE__, __LINE__)
1714
1715 # define os_file_delete_if_exists(key, name, exist) \
1716 pfs_os_file_delete_if_exists_func(key, name, exist, __FILE__, __LINE__)
1717
1718 # define os_file_set_eof_at_pfs(file, new_len) \
1719 pfs_os_file_set_eof_at_func(file, new_len, __FILE__, __LINE__)
1720
1721
1722 /** NOTE! Please use the corresponding macro os_file_create_simple(),
1723 not directly this function!
1724 A performance schema instrumented wrapper function for
1725 os_file_create_simple() which opens or creates a file.
1726 @param[in] key Performance Schema Key
1727 @param[in] name name of the file or path as a null-terminated
1728 string
1729 @param[in] create_mode create mode
1730 @param[in] access_type OS_FILE_READ_ONLY or OS_FILE_READ_WRITE
1731 @param[in] read_only if true read only mode checks are enforced
1732 @param[out] success true if succeeded
1733 @param[in] src_file file name where func invoked
1734 @param[in] src_line line where the func invoked
1735 @return own: handle to the file, not defined if error, error number
1736 can be retrieved with os_file_get_last_error */
1737 UNIV_INLINE
1738 pfs_os_file_t
1739 pfs_os_file_create_simple_func(
1740 mysql_pfs_key_t key,
1741 const char* name,
1742 ulint create_mode,
1743 ulint access_type,
1744 bool read_only,
1745 bool* success,
1746 const char* src_file,
1747 ulint src_line)
1748 MY_ATTRIBUTE((warn_unused_result));
1749
1750 /** NOTE! Please use the corresponding macro
1751 os_file_create_simple_no_error_handling(), not directly this function!
1752 A performance schema instrumented wrapper function for
1753 os_file_create_simple_no_error_handling(). Add instrumentation to
1754 monitor file creation/open.
1755 @param[in] key Performance Schema Key
1756 @param[in] name name of the file or path as a null-terminated
1757 string
1758 @param[in] create_mode create mode
1759 @param[in] access_type OS_FILE_READ_ONLY, OS_FILE_READ_WRITE, or
1760 OS_FILE_READ_ALLOW_DELETE; the last option is
1761 used by a backup program reading the file
1762 @param[in] read_only if true read only mode checks are enforced
1763 @param[out] success true if succeeded
1764 @param[in] src_file file name where func invoked
1765 @param[in] src_line line where the func invoked
1766 @return own: handle to the file, not defined if error, error number
1767 can be retrieved with os_file_get_last_error */
1768 UNIV_INLINE
1769 pfs_os_file_t
1770 pfs_os_file_create_simple_no_error_handling_func(
1771 mysql_pfs_key_t key,
1772 const char* name,
1773 ulint create_mode,
1774 ulint access_type,
1775 bool read_only,
1776 bool* success,
1777 const char* src_file,
1778 ulint src_line)
1779 MY_ATTRIBUTE((warn_unused_result));
1780
1781 /** NOTE! Please use the corresponding macro os_file_create(), not directly
1782 this function!
1783 A performance schema wrapper function for os_file_create().
1784 Add instrumentation to monitor file creation/open.
1785 @param[in] key Performance Schema Key
1786 @param[in] name name of the file or path as a null-terminated
1787 string
1788 @param[in] create_mode create mode
1789 @param[in] purpose OS_FILE_AIO, if asynchronous, non-buffered I/O
1790 is desired, OS_FILE_NORMAL, if any normal file;
1791 NOTE that it also depends on type, os_aio_..
1792 and srv_.. variables whether we really use
1793 async I/O or unbuffered I/O: look in the
1794 function source code for the exact rules
1795 @param[in] read_only if true read only mode checks are enforced
1796 @param[out] success true if succeeded
1797 @param[in] src_file file name where func invoked
1798 @param[in] src_line line where the func invoked
1799 @return own: handle to the file, not defined if error, error number
1800 can be retrieved with os_file_get_last_error */
1801 UNIV_INLINE
1802 pfs_os_file_t
1803 pfs_os_file_create_func(
1804 mysql_pfs_key_t key,
1805 const char* name,
1806 ulint create_mode,
1807 ulint purpose,
1808 ulint type,
1809 bool read_only,
1810 bool* success,
1811 const char* src_file,
1812 ulint src_line)
1813 MY_ATTRIBUTE((warn_unused_result));
1814
1815 /** NOTE! Please use the corresponding macro os_file_close(), not directly
1816 this function!
1817 A performance schema instrumented wrapper function for os_file_close().
1818 @param[in] file handle to a file
1819 @param[in] src_file file name where func invoked
1820 @param[in] src_line line where the func invoked
1821 @return true if success */
1822 UNIV_INLINE
1823 bool
1824 pfs_os_file_close_func(
1825 pfs_os_file_t file,
1826 const char* src_file,
1827 ulint src_line);
1828
1829 /** NOTE! Use the corresponding macro os_file_close_no_error_handling(), not
1830 directly this function!
1831 Closes a file handle.
1832 @param[in] file handle to a file
1833 @param[in] src_file file name where func invoked
1834 @param[in] src_line line where the func invoked
1835 @return true if success */
1836 UNIV_INLINE
1837 bool
1838 pfs_os_file_close_no_error_handling_func(
1839 pfs_os_file_t file,
1840 const char* src_file,
1841 ulint src_line);
1842
1843 /** NOTE! Please use the corresponding macro os_file_read(), not directly
1844 this function!
1845 This is the performance schema instrumented wrapper function for
1846 os_file_read() which requests a synchronous read operation.
1847 @param[in, out] type IO request context
1848 @param[in] file Open file handle
1849 @param[out] buf buffer where to read
1850 @param[in] offset file offset where to read
1851 @param[in] n number of bytes to read
1852 @param[in] src_file file name where func invoked
1853 @param[in] src_line line where the func invoked
1854 @return DB_SUCCESS if request was successful */
1855 UNIV_INLINE
1856 dberr_t
1857 pfs_os_file_read_func(
1858 IORequest& type,
1859 pfs_os_file_t file,
1860 void* buf,
1861 os_offset_t offset,
1862 ulint n,
1863 trx_t* trx,
1864 const char* src_file,
1865 ulint src_line);
1866
1867 /** NOTE! Please use the corresponding macro os_file_read_no_error_handling(),
1868 not directly this function!
1869 This is the performance schema instrumented wrapper function for
1870 os_file_read_no_error_handling_func() which requests a synchronous
1871 read operation.
1872 @param[in, out] type IO request context
1873 @param[in] file Open file handle
1874 @param[out] buf buffer where to read
1875 @param[in] offset file offset where to read
1876 @param[in] n number of bytes to read
1877 @param[out] o number of bytes actually read
1878 @param[in] src_file file name where func invoked
1879 @param[in] src_line line where the func invoked
1880 @return DB_SUCCESS if request was successful */
1881 UNIV_INLINE
1882 dberr_t
1883 pfs_os_file_read_no_error_handling_func(
1884 IORequest& type,
1885 pfs_os_file_t file,
1886 void* buf,
1887 os_offset_t offset,
1888 ulint n,
1889 ulint* o,
1890 const char* src_file,
1891 ulint src_line);
1892
1893 /** NOTE! Please use the corresponding macro
1894 os_file_read_no_error_handling_int_fd(), not directly this function!
1895 This is the performance schema instrumented wrapper function for
1896 os_file_read_no_error_handling_int_fd_func() which requests a
1897 synchronous read operation on files with int type descriptors.
1898 @param[in, out] type IO request context
1899 @param[in] file Open file handle
1900 @param[out] buf buffer where to read
1901 @param[in] offset file offset where to read
1902 @param[in] n number of bytes to read
1903 @param[out] o number of bytes actually read
1904 @param[in] src_file file name where func invoked
1905 @param[in] src_line line where the func invoked
1906 @return DB_SUCCESS if request was successful */
1907
1908 UNIV_INLINE
1909 dberr_t
1910 pfs_os_file_read_no_error_handling_int_fd_func(
1911 IORequest& type,
1912 int file,
1913 void* buf,
1914 os_offset_t offset,
1915 ulint n,
1916 ulint* o,
1917 const char* src_file,
1918 ulint src_line);
1919
1920 /** NOTE! Please use the corresponding macro os_aio(), not directly this
1921 function!
1922 Performance schema wrapper function of os_aio() which requests
1923 an asynchronous I/O operation.
1924 @param[in] type IO request context
1925 @param[in] mode IO mode
1926 @param[in] name Name of the file or path as NUL terminated
1927 string
1928 @param[in] file Open file handle
1929 @param[out] buf buffer where to read
1930 @param[in] offset file offset where to read
1931 @param[in] n number of bytes to read
1932 @param[in] read_only if true read only mode checks are enforced
1933 @param[in,out] m1 Message for the AIO handler, (can be used to
1934 identify a completed AIO operation); ignored
1935 if mode is OS_AIO_SYNC
1936 @param[in,out] m2 message for the AIO handler (can be used to
1937 identify a completed AIO operation); ignored
1938 if mode is OS_AIO_SYNC
1939 @param[in] should_buffer Whether to buffer an aio request.
1940 AIO read ahead uses this. If you plan to
1941 use this parameter, make sure you remember to
1942 call os_aio_dispatch_read_array_submit()
1943 when you're ready to commit all your
1944 requests.
1945 @param[in] src_file file name where func invoked
1946 @param[in] src_line line where the func invoked
1947 @return DB_SUCCESS if request was queued successfully, FALSE if fail */
1948 UNIV_INLINE
1949 dberr_t
1950 pfs_os_aio_func(
1951 IORequest& type,
1952 ulint mode,
1953 const char* name,
1954 pfs_os_file_t file,
1955 void* buf,
1956 os_offset_t offset,
1957 ulint n,
1958 bool read_only,
1959 fil_node_t* m1,
1960 void* m2,
1961 ulint space_id,
1962 trx_t* trx,
1963 bool should_buffer,
1964 const char* src_file,
1965 ulint src_line);
1966
1967 /** NOTE! Please use the corresponding macro os_file_write(), not directly
1968 this function!
1969 This is the performance schema instrumented wrapper function for
1970 os_file_write() which requests a synchronous write operation.
1971 @param[in, out] type IO request context
1972 @param[in] name Name of the file or path as NUL terminated
1973 string
1974 @param[in] file Open file handle
1975 @param[out] buf buffer where to read
1976 @param[in] offset file offset where to read
1977 @param[in] n number of bytes to read
1978 @param[in] src_file file name where func invoked
1979 @param[in] src_line line where the func invoked
1980 @return DB_SUCCESS if request was successful */
1981 UNIV_INLINE
1982 dberr_t
1983 pfs_os_file_write_func(
1984 IORequest& type,
1985 const char* name,
1986 pfs_os_file_t file,
1987 const void* buf,
1988 os_offset_t offset,
1989 ulint n,
1990 const char* src_file,
1991 ulint src_line);
1992
1993 /** NOTE! Please use the corresponding macro os_file_write(), not
1994 directly this function!
1995 This is the performance schema instrumented wrapper function for
1996 os_file_write() which requests a synchronous write operation
1997 on files with int type descriptors.
1998 @param[in, out] type IO request context
1999 @param[in] name Name of the file or path as NUL terminated
2000 string
2001 @param[in] file Open file handle
2002 @param[out] buf buffer where to read
2003 @param[in] offset file offset where to read
2004 @param[in] n number of bytes to read
2005 @param[in] src_file file name where func invoked
2006 @param[in] src_line line where the func invoked
2007 @return DB_SUCCESS if request was successful */
2008 UNIV_INLINE
2009 dberr_t
2010 pfs_os_file_write_int_fd_func(
2011 IORequest& type,
2012 const char* name,
2013 int file,
2014 const void* buf,
2015 os_offset_t offset,
2016 ulint n,
2017 const char* src_file,
2018 ulint src_line);
2019
2020 /** NOTE! Please use the corresponding macro os_file_flush(), not directly
2021 this function!
2022 This is the performance schema instrumented wrapper function for
2023 os_file_flush() which flushes the write buffers of a given file to the disk.
2024 Flushes the write buffers of a given file to the disk.
2025 @param[in] file Open file handle
2026 @param[in] src_file file name where func invoked
2027 @param[in] src_line line where the func invoked
2028 @return TRUE if success */
2029 UNIV_INLINE
2030 bool
2031 pfs_os_file_flush_func(
2032 pfs_os_file_t file,
2033 const char* src_file,
2034 ulint src_line);
2035
2036 /** NOTE! Please use the corresponding macro os_file_rename(), not directly
2037 this function!
2038 This is the performance schema instrumented wrapper function for
2039 os_file_rename()
2040 @param[in] key Performance Schema Key
2041 @param[in] oldpath old file path as a null-terminated string
2042 @param[in] newpath new file path
2043 @param[in] src_file file name where func invoked
2044 @param[in] src_line line where the func invoked
2045 @return true if success */
2046 UNIV_INLINE
2047 bool
2048 pfs_os_file_rename_func(
2049 mysql_pfs_key_t key,
2050 const char* oldpath,
2051 const char* newpath,
2052 const char* src_file,
2053 ulint src_line);
2054
2055 /**
2056 NOTE! Please use the corresponding macro os_file_delete(), not directly
2057 this function!
2058 This is the performance schema instrumented wrapper function for
2059 os_file_delete()
2060 @param[in] key Performance Schema Key
2061 @param[in] name old file path as a null-terminated string
2062 @param[in] src_file file name where func invoked
2063 @param[in] src_line line where the func invoked
2064 @return true if success */
2065 UNIV_INLINE
2066 bool
2067 pfs_os_file_delete_func(
2068 mysql_pfs_key_t key,
2069 const char* name,
2070 const char* src_file,
2071 ulint src_line);
2072
2073 /**
2074 NOTE! Please use the corresponding macro os_file_delete_if_exists(), not
2075 directly this function!
2076 This is the performance schema instrumented wrapper function for
2077 os_file_delete_if_exists()
2078 @param[in] key Performance Schema Key
2079 @param[in] name old file path as a null-terminated string
2080 @param[in] exist indicate if file pre-exist
2081 @param[in] src_file file name where func invoked
2082 @param[in] src_line line where the func invoked
2083 @return true if success */
2084 UNIV_INLINE
2085 bool
2086 pfs_os_file_delete_if_exists_func(
2087 mysql_pfs_key_t key,
2088 const char* name,
2089 bool* exist,
2090 const char* src_file,
2091 ulint src_line);
2092
2093 /** NOTE! Use the corresponding macro os_file_flush(), not directly this
2094 function!
2095 Truncates a file at the specified position.
2096 @param[in] file file to truncate
2097 @param[in] new_len new file length
2098 @param[in] src_file file name where func invoked
2099 @param[in] src_line line where the func invoked
2100 @return true if success */
2101 UNIV_INLINE
2102 bool
2103 pfs_os_file_set_eof_at_func(
2104 pfs_os_file_t file,
2105 ib_uint64_t new_len,
2106 const char* src_file,
2107 ulint src_line);
2108
2109 #else /* UNIV_PFS_IO */
2110
2111 /* If UNIV_PFS_IO is not defined, these I/O APIs point
2112 to original un-instrumented file I/O APIs */
2113 # define os_file_create(key, name, create, purpose, type, read_only, \
2114 success) \
2115 os_file_create_func(name, create, purpose, type, read_only, \
2116 success)
2117
2118 # define os_file_create_simple(key, name, create_mode, access, \
2119 read_only, success) \
2120 os_file_create_simple_func(name, create_mode, access, \
2121 read_only, success)
2122
2123 # define os_file_create_simple_no_error_handling( \
2124 key, name, create_mode, access, read_only, success) \
2125 os_file_create_simple_no_error_handling_func( \
2126 name, create_mode, access, read_only, success)
2127
2128 # define os_file_close_pfs(file) os_file_close_func(file)
2129
2130 # define os_file_close_no_error_handling_pfs(file) \
2131 os_file_close_no_error_handling_func(file)
2132
2133 # define os_aio(type, mode, name, file, buf, offset, \
2134 n, read_only, message1, message2, space_id, trx, \
2135 should_buffer) \
2136 os_aio_func(type, mode, name, file, buf, offset, \
2137 n, read_only, message1, message2, space_id, trx, \
2138 should_buffer)
2139
2140 # define os_file_read_pfs(type, file, buf, offset, n) \
2141 os_file_read_func(type, file, buf, offset, n)
2142
2143 # define os_file_read_no_error_handling_pfs(type, file, buf, offset, n, o) \
2144 os_file_read_no_error_handling_func(type, file, buf, offset, n, o)
2145
2146 # define os_file_read_no_error_handling_int_fd(type, file, buf, offset, n, o) \
2147 os_file_read_no_error_handling_func(type, file, buf, offset, n, o)
2148
2149 # define os_file_read_trx_pfs(file, buf, offset, n, trx) \
2150 os_file_read_func(file, buf, offset, n, trx)
2151
2152 # define os_file_write_pfs(type, name, file, buf, offset, n) \
2153 os_file_write_func(type, name, file, buf, offset, n)
2154
2155 # define os_file_write_int_fd(type, name, file, buf, offset, n) \
2156 os_file_write_func(type, name, file, buf, offset, n)
2157
2158 # define os_file_flush_pfs(file) os_file_flush_func(file)
2159
2160 # define os_file_rename(key, oldpath, newpath) \
2161 os_file_rename_func(oldpath, newpath)
2162
2163 # define os_file_delete(key, name) os_file_delete_func(name)
2164
2165 # define os_file_delete_if_exists(key, name, exist) \
2166 os_file_delete_if_exists_func(name, exist)
2167
2168 # define os_file_set_eof_at_pfs(file, new_len) \
2169 os_file_set_eof_at_func(file, new_len)
2170
2171 #endif /* UNIV_PFS_IO */
2172
2173 #ifdef UNIV_PFS_IO
2174 #define os_file_close(file) os_file_close_pfs(file)
2175 #else
2176 #define os_file_close(file) os_file_close_pfs((file).m_file)
2177 #endif
2178
2179 #ifdef UNIV_PFS_IO
2180 #define os_file_close_no_error_handling(file) \
2181 os_file_close_no_error_handling_pfs(file)
2182 #else
2183 #define os_file_close_no_error_handling(file) \
2184 os_file_close_no_error_handling_pfs((file).m_file)
2185 #endif
2186
2187 #ifdef UNIV_PFS_IO
2188 #define os_file_read(type, file, buf, offset, n) \
2189 os_file_read_pfs(type, file, buf, offset, n)
2190 #else
2191 #define os_file_read(type, file, buf, offset, n) \
2192 os_file_read_pfs(type, file.m_file, buf, offset, n)
2193 #endif
2194
2195 #ifdef UNIV_PFS_IO
2196 #define os_file_flush(file) os_file_flush_pfs(file)
2197 #else
2198 #define os_file_flush(file) os_file_flush_pfs(file.m_file)
2199 #endif
2200
2201 #ifdef UNIV_PFS_IO
2202 #define os_file_write(type, name, file, buf, offset, n) \
2203 os_file_write_pfs(type, name, file, buf, offset, n)
2204 #else
2205 #define os_file_write(type, name, file, buf, offset, n) \
2206 os_file_write_pfs(type, name, file.m_file, buf, offset, n)
2207 #endif
2208
2209 #ifdef UNIV_PFS_IO
2210 #define os_file_read_no_error_handling(type, file, buf, offset, n, o) \
2211 os_file_read_no_error_handling_pfs(type, file, buf, offset, n, o)
2212 #else
2213 #define os_file_read_no_error_handling(type, file, buf, offset, n, o) \
2214 os_file_read_no_error_handling_pfs( \
2215 type, file.m_file, buf, offset, n, o)
2216 #endif
2217
2218 #ifdef UNIV_PFS_IO
2219 #define os_file_set_eof_at(file, new_len) \
2220 os_file_set_eof_at_pfs(file, new_len)
2221 #else
2222 #define os_file_set_eof_at(file, new_len) \
2223 os_file_set_eof_at_pfs(file.m_file, new_len)
2224 #endif
2225
2226 /** Announces an intention to access file data in a specific pattern in the
2227 future.
2228 @param[in, own] file handle to a file
2229 @param[in] offset file region offset
2230 @param[in] len file region length
2231 @param[in] advice advice for access pattern
2232 @return true if success */
2233 bool
2234 os_file_advise(pfs_os_file_t file, os_offset_t offset, os_offset_t len,
2235 ulint advice);
2236
2237 /** Gets a file size.
2238 @param[in] file handle to a file
2239 @return file size if OK, else set m_total_size to ~0 and m_alloc_size
2240 to errno */
2241 os_file_size_t
2242 os_file_get_size(
2243 const char* filename)
2244 MY_ATTRIBUTE((warn_unused_result));
2245
2246 /** Gets a file size.
2247 @param[in] file handle to a file
2248 @return file size, or (os_offset_t) -1 on failure */
2249 os_offset_t
2250 os_file_get_size(
2251 pfs_os_file_t file)
2252 MY_ATTRIBUTE((warn_unused_result));
2253
2254 /** Write the specified number of zeros to a newly created file.
2255 @param[in] name name of the file or path as a null-terminated
2256 string
2257 @param[in] file handle to a file
2258 @param[in] size file size
2259 @param[in] read_only Enable read-only checks if true
2260 @return true if success */
2261 bool
2262 os_file_set_size(
2263 const char* name,
2264 pfs_os_file_t file,
2265 os_offset_t size,
2266 bool read_only)
2267 MY_ATTRIBUTE((warn_unused_result));
2268
2269 /** Truncates a file at its current position.
2270 @param[in/out] file file to be truncated
2271 @return true if success */
2272 bool
2273 os_file_set_eof(
2274 FILE* file); /*!< in: file to be truncated */
2275
2276 /** Truncates a file to a specified size in bytes. Do nothing if the size
2277 preserved is smaller or equal than current size of file.
2278 @param[in] pathname file path
2279 @param[in] file file to be truncated
2280 @param[in] size size preserved in bytes
2281 @return true if success */
2282 bool
2283 os_file_truncate(
2284 const char* pathname,
2285 pfs_os_file_t file,
2286 os_offset_t size);
2287
2288 /** NOTE! Use the corresponding macro os_file_flush(), not directly this
2289 function!
2290 Truncates a file at the specified position.
2291 @param[in] file file to truncate
2292 @param[in] new_len new file length
2293 @return true if success */
2294 bool
2295 os_file_set_eof_at_func(
2296 os_file_t file,
2297 ib_uint64_t new_len);
2298
2299 /** NOTE! Use the corresponding macro os_file_flush(), not directly this
2300 function!
2301 Flushes the write buffers of a given file to the disk.
2302 @param[in] file handle to a file
2303 @return true if success */
2304 bool
2305 os_file_flush_func(
2306 os_file_t file);
2307
2308 /** Retrieves the last error number if an error occurs in a file io function.
2309 The number should be retrieved before any other OS calls (because they may
2310 overwrite the error number). If the number is not known to this program,
2311 the OS error number + 100 is returned.
2312 @param[in] report true if we want an error message printed
2313 for all errors
2314 @return error number, or OS error number + 100 */
2315 ulint
2316 os_file_get_last_error(
2317 bool report);
2318
2319 /** NOTE! Use the corresponding macro os_file_read(), not directly this
2320 function!
2321 Requests a synchronous read operation.
2322 @param[in] type IO request context
2323 @param[in] file Open file handle
2324 @param[out] buf buffer where to read
2325 @param[in] offset file offset where to read
2326 @param[in] n number of bytes to read
2327 @return DB_SUCCESS if request was successful */
2328 dberr_t
2329 os_file_read_func(
2330 IORequest& type,
2331 os_file_t file,
2332 void* buf,
2333 os_offset_t offset,
2334 ulint n,
2335 trx_t* trx)
2336 MY_ATTRIBUTE((warn_unused_result));
2337
2338 /** Rewind file to its start, read at most size - 1 bytes from it to str, and
2339 NUL-terminate str. All errors are silently ignored. This function is
2340 mostly meant to be used with temporary files.
2341 @param[in,out] file file to read from
2342 @param[in,out] str buffer where to read
2343 @param[in] size size of buffer */
2344 void
2345 os_file_read_string(
2346 FILE* file,
2347 char* str,
2348 ulint size);
2349
2350 /** NOTE! Use the corresponding macro os_file_read_no_error_handling(),
2351 not directly this function!
2352 Requests a synchronous positioned read operation. This function does not do
2353 any error handling. In case of error it returns FALSE.
2354 @param[in] type IO request context
2355 @param[in] file Open file handle
2356 @param[out] buf buffer where to read
2357 @param[in] offset file offset where to read
2358 @param[in] n number of bytes to read
2359 @param[out] o number of bytes actually read
2360 @return DB_SUCCESS or error code */
2361 dberr_t
2362 os_file_read_no_error_handling_func(
2363 IORequest& type,
2364 os_file_t file,
2365 void* buf,
2366 os_offset_t offset,
2367 ulint n,
2368 ulint* o)
2369 MY_ATTRIBUTE((warn_unused_result));
2370
2371 /** NOTE! Use the corresponding macro os_file_write(), not directly this
2372 function!
2373 Requests a synchronous write operation.
2374 @param[in,out] type IO request context
2375 @param[in] file Open file handle
2376 @param[out] buf buffer where to read
2377 @param[in] offset file offset where to read
2378 @param[in] n number of bytes to read
2379 @return DB_SUCCESS if request was successful */
2380 dberr_t
2381 os_file_write_func(
2382 IORequest& type,
2383 const char* name,
2384 os_file_t file,
2385 const void* buf,
2386 os_offset_t offset,
2387 ulint n)
2388 MY_ATTRIBUTE((warn_unused_result));
2389
2390 /** Check the existence and type of the given file.
2391 @param[in] path pathname of the file
2392 @param[out] exists true if file exists
2393 @param[out] type type of the file (if it exists)
2394 @return true if call succeeded */
2395 bool
2396 os_file_status(
2397 const char* path,
2398 bool* exists,
2399 os_file_type_t* type);
2400
2401 /** This function returns a new path name after replacing the basename
2402 in an old path with a new basename. The old_path is a full path
2403 name including the extension. The tablename is in the normal
2404 form "databasename/tablename". The new base name is found after
2405 the forward slash. Both input strings are null terminated.
2406
2407 This function allocates memory to be returned. It is the callers
2408 responsibility to free the return value after it is no longer needed.
2409
2410 @param[in] old_path pathname
2411 @param[in] new_name new file name
2412 @return own: new full pathname */
2413 char*
2414 os_file_make_new_pathname(
2415 const char* old_path,
2416 const char* new_name);
2417
2418 /** This function reduces a null-terminated full remote path name into
2419 the path that is sent by MySQL for DATA DIRECTORY clause. It replaces
2420 the 'databasename/tablename.ibd' found at the end of the path with just
2421 'tablename'.
2422
2423 Since the result is always smaller than the path sent in, no new memory
2424 is allocated. The caller should allocate memory for the path sent in.
2425 This function manipulates that path in place.
2426
2427 If the path format is not as expected, just return. The result is used
2428 to inform a SHOW CREATE TABLE command.
2429 @param[in,out] data_dir_path Full path/data_dir_path */
2430 void
2431 os_file_make_data_dir_path(
2432 char* data_dir_path);
2433
2434 /** Create all missing subdirectories along the given path.
2435 @return DB_SUCCESS if OK, otherwise error code. */
2436 dberr_t
2437 os_file_create_subdirs_if_needed(
2438 const char* path);
2439
2440 #ifdef UNIV_ENABLE_UNIT_TEST_GET_PARENT_DIR
2441 /* Test the function os_file_get_parent_dir. */
2442 void
2443 unit_test_os_file_get_parent_dir();
2444 #endif /* UNIV_ENABLE_UNIT_TEST_GET_PARENT_DIR */
2445
2446 /** Initializes the asynchronous io system. Creates one array each for ibuf
2447 and log i/o. Also creates one array each for read and write where each
2448 array is divided logically into n_read_segs and n_write_segs
2449 respectively. The caller must create an i/o handler thread for each
2450 segment in these arrays. This function also creates the sync array.
2451 No i/o handler thread needs to be created for that
2452 @param[in] n_read_segs number of reader threads
2453 @param[in] n_write_segs number of writer threads
2454 @param[in] n_slots_sync number of slots in the sync aio array */
2455
2456 bool
2457 os_aio_init(
2458 ulint n_read_segs,
2459 ulint n_write_segs,
2460 ulint n_slots_sync);
2461
2462 /**
2463 Frees the asynchronous io system. */
2464 void
2465 os_aio_free();
2466
2467 /**
2468 NOTE! Use the corresponding macro os_aio(), not directly this function!
2469 Requests an asynchronous i/o operation.
2470 @param[in] type IO request context
2471 @param[in] mode IO mode
2472 @param[in] name Name of the file or path as NUL terminated
2473 string
2474 @param[in] file Open file handle
2475 @param[out] buf buffer where to read
2476 @param[in] offset file offset where to read
2477 @param[in] n number of bytes to read
2478 @param[in] read_only if true read only mode checks are enforced
2479 @param[in,out] m1 Message for the AIO handler, (can be used to
2480 identify a completed AIO operation); ignored
2481 if mode is OS_AIO_SYNC
2482 @param[in,out] m2 message for the AIO handler (can be used to
2483 identify a completed AIO operation); ignored
2484 if mode is OS_AIO_SYNC
2485 @param[in] should_buffer Whether to buffer an aio request.
2486 AIO read ahead uses this. If you plan to
2487 use this parameter, make sure you remember to
2488 call os_aio_dispatch_read_array_submit()
2489 when you're ready to commit all your
2490 requests.
2491 @return DB_SUCCESS or error code */
2492 dberr_t
2493 os_aio_func(
2494 IORequest& type,
2495 ulint mode,
2496 const char* name,
2497 pfs_os_file_t file,
2498 void* buf,
2499 os_offset_t offset,
2500 ulint n,
2501 bool read_only,
2502 fil_node_t* m1,
2503 void* m2,
2504 ulint space_id,
2505 trx_t* trx,
2506 bool should_buffer);
2507 //bool *was_page_read_encrypted = NULL);
2508
2509 /** Wakes up all async i/o threads so that they know to exit themselves in
2510 shutdown. */
2511 void
2512 os_aio_wake_all_threads_at_shutdown();
2513
2514 /** Waits until there are no pending writes in os_aio_write_array. There can
2515 be other, synchronous, pending writes. */
2516 void
2517 os_aio_wait_until_no_pending_writes();
2518
2519 /** Wakes up simulated aio i/o-handler threads if they have something to do. */
2520 void
2521 os_aio_simulated_wake_handler_threads();
2522
2523 /** This function can be called if one wants to post a batch of reads and
2524 prefers an i/o-handler thread to handle them all at once later. You must
2525 call os_aio_simulated_wake_handler_threads later to ensure the threads
2526 are not left sleeping! */
2527 void
2528 os_aio_simulated_put_read_threads_to_sleep();
2529
2530 /** This is the generic AIO handler interface function.
2531 Waits for an aio operation to complete. This function is used to wait the
2532 for completed requests. The AIO array of pending requests is divided
2533 into segments. The thread specifies which segment or slot it wants to wait
2534 for. NOTE: this function will also take care of freeing the aio slot,
2535 therefore no other thread is allowed to do the freeing!
2536 @param[in] segment the number of the segment in the aio arrays to
2537 wait for; segment 0 is the ibuf I/O thread,
2538 segment 1 the log I/O thread, then follow the
2539 non-ibuf read threads, and as the last are the
2540 non-ibuf write threads; if this is
2541 ULINT_UNDEFINED, then it means that sync AIO
2542 is used, and this parameter is ignored
2543 @param[out] m1 the messages passed with the AIO request;
2544 note that also in the case where the AIO
2545 operation failed, these output parameters
2546 are valid and can be used to restart the
2547 operation, for example
2548 @param[out] m2 callback message
2549 @param[out] type OS_FILE_WRITE or ..._READ
2550 @return DB_SUCCESS or error code */
2551 dberr_t
2552 os_aio_handler(
2553 ulint segment,
2554 fil_node_t** m1,
2555 void** m2,
2556 IORequest* type);
2557
2558 /** Prints info of the aio arrays.
2559 @param[in/out] file file where to print */
2560 void
2561 os_aio_print(FILE* file);
2562
2563 /** Refreshes the statistics used to print per-second averages. */
2564 void
2565 os_aio_refresh_stats();
2566
2567 /** Checks that all slots in the system have been freed, that is, there are
2568 no pending io operations. */
2569 bool
2570 os_aio_all_slots_free();
2571
2572 #ifdef UNIV_DEBUG
2573
2574 /** Prints all pending IO
2575 @param[in] file file where to print */
2576 void
2577 os_aio_print_pending_io(FILE* file);
2578
2579 #endif /* UNIV_DEBUG */
2580
2581 /** This function returns information about the specified file
2582 @param[in] path pathname of the file
2583 @param[in] stat_info information of a file in a directory
2584 @param[in] check_rw_perm for testing whether the file can be opened
2585 in RW mode
2586 @param[in] read_only if true read only mode checks are enforced
2587 @return DB_SUCCESS if all OK */
2588 dberr_t
2589 os_file_get_status(
2590 const char* path,
2591 os_file_stat_t* stat_info,
2592 bool check_rw_perm,
2593 bool read_only);
2594
2595 #if !defined(UNIV_HOTBACKUP)
2596 /** return one of the tmpdir path
2597 @return tmporary dir*/
2598 char *innobase_mysql_tmpdir(void);
2599
2600
2601 /** Creates a temporary file in the location specified by the parameter
2602 path. If the path is NULL then it will be created on --tmpdir location.
2603 This function is defined in ha_innodb.cc.
2604 @param[in] path location for creating temporary file
2605 @return temporary file descriptor, or < 0 on error */
2606 int
2607 innobase_mysql_tmpfile(
2608 const char* path);
2609 #endif /* !UNIV_HOTBACKUP */
2610
2611
2612 /** If it is a compressed page return the compressed page data + footer size
2613 @param[in] buf Buffer to check, must include header + 10 bytes
2614 @return ULINT_UNDEFINED if the page is not a compressed page or length
2615 of the compressed data (including footer) if it is a compressed page */
2616 ulint
2617 os_file_compressed_page_size(const byte* buf);
2618
2619 /** If it is a compressed page return the original page data + footer size
2620 @param[in] buf Buffer to check, must include header + 10 bytes
2621 @return ULINT_UNDEFINED if the page is not a compressed page or length
2622 of the original data + footer if it is a compressed page */
2623 ulint
2624 os_file_original_page_size(const byte* buf);
2625
2626 /** Set the file create umask
2627 @param[in] umask The umask to use for file creation. */
2628 void
2629 os_file_set_umask(ulint umask);
2630
2631 /** Free storage space associated with a section of the file.
2632 @param[in] fh Open file handle
2633 @param[in] off Starting offset (SEEK_SET)
2634 @param[in] len Size of the hole
2635 @return DB_SUCCESS or error code */
2636 dberr_t
2637 os_file_punch_hole(
2638 os_file_t fh,
2639 os_offset_t off,
2640 os_offset_t len)
2641 MY_ATTRIBUTE((warn_unused_result));
2642
2643 /** Check if the file system supports sparse files.
2644
2645 Warning: On POSIX systems we try and punch a hole from offset 0 to
2646 the system configured page size. This should only be called on an empty
2647 file.
2648
2649 Note: On Windows we use the name and on Unices we use the file handle.
2650
2651 @param[in] name File name
2652 @param[in] fh File handle for the file - if opened
2653 @return true if the file system supports sparse files */
2654 bool
2655 os_is_sparse_file_supported(
2656 const char* path,
2657 pfs_os_file_t fh)
2658 MY_ATTRIBUTE((warn_unused_result));
2659
2660 /** Decompress the page data contents. Page type must be FIL_PAGE_COMPRESSED, if
2661 not then the source contents are left unchanged and DB_SUCCESS is returned.
2662 @param[in] dblwr_recover true of double write recovery in progress
2663 @param[in,out] src Data read from disk, decompressed data will be
2664 copied to this page
2665 @param[in,out] dst Scratch area to use for decompression
2666 @param[in] dst_len Size of the scratch area in bytes
2667 @return DB_SUCCESS or error code */
2668
2669 dberr_t
2670 os_file_decompress_page(
2671 bool dblwr_recover,
2672 byte* src,
2673 byte* dst,
2674 ulint dst_len)
2675 MY_ATTRIBUTE((warn_unused_result));
2676
2677 /** Normalizes a directory path for the current OS:
2678 On Windows, we convert '/' to '\', else we convert '\' to '/'.
2679 @param[in,out] str A null-terminated directory and file path */
2680 void os_normalize_path(char* str);
2681
2682 /* Determine if a path is an absolute path or not.
2683 @param[in] OS directory or file path to evaluate
2684 @retval true if an absolute path
2685 @retval false if a relative path */
2686 UNIV_INLINE
2687 bool
is_absolute_path(const char * path)2688 is_absolute_path(
2689 const char* path)
2690 {
2691 if (path[0] == OS_PATH_SEPARATOR) {
2692 return(true);
2693 }
2694
2695 #ifdef _WIN32
2696 if (path[1] == ':' && path[2] == OS_PATH_SEPARATOR) {
2697 return(true);
2698 }
2699 #endif /* _WIN32 */
2700
2701 return(false);
2702 }
2703
2704 /** Submit buffered AIO requests on the given segment to the kernel. */
2705 void
2706 os_aio_dispatch_read_array_submit();
2707
2708 struct fil_space_t;
2709
2710 /** Encrypt a doublewrite buffer page. The page is encrypted
2711 using the key of tablespace object provided.
2712 Caller should allocate buffer for encrypted page
2713 @param[in] space tablespace object
2714 @param[in] in_page unencrypted page
2715 @param[in,out] encrypted_buf buffer to hold the encrypted page
2716 @param[in] encrypted_buf_len length of the encrypted buffer
2717 @return true on success, false on failure */
2718 bool
2719 os_dblwr_encrypt_page(
2720 fil_space_t* space,
2721 page_t* in_page,
2722 page_t* encrypted_buf,
2723 ulint encrypted_buf_len);
2724
2725 /** Decrypt a page from doublewrite buffer. Tablespace object
2726 (fil_space_t) must have encryption key, iv set properly.
2727 The decrpyted page will be written in the same buffer of input page.
2728 @param[in] space tablespace obejct
2729 @param[in,out] page in: encrypted page
2730 out: decrypted page
2731 @return DB_SUCCESS on success, others on failure */
2732 dberr_t
2733 os_dblwr_decrypt_page(
2734 fil_space_t* space,
2735 page_t* in_page);
2736
2737 #ifndef UNIV_NONINL
2738 #include "os0file.ic"
2739 #endif /* UNIV_NONINL */
2740
2741 #endif /* os0file_h */
2742