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