1 /***********************************************************************
2
3 Copyright (c) 1995, 2020, Oracle and/or its affiliates.
4 Copyright (c) 2009, 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
53 /** File node of a tablespace or the log data space */
54 struct fil_node_t;
55
56 extern bool os_has_said_disk_full;
57
58 /** Number of pending read operations */
59 extern ulint os_n_pending_reads;
60 /** Number of pending write operations */
61 extern ulint os_n_pending_writes;
62
63 /** File offset in bytes */
64 typedef ib_uint64_t os_offset_t;
65
66 #ifdef _WIN32
67
68 /**
69 Gets the operating system version. Currently works only on Windows.
70 @return OS_WIN95, OS_WIN31, OS_WINNT, OS_WIN2000, OS_WINXP, OS_WINVISTA,
71 OS_WIN7. */
72
73 ulint
74 os_get_os_version();
75
76 typedef HANDLE os_file_dir_t; /*!< directory stream */
77
78 /** We define always WIN_ASYNC_IO, and check at run-time whether
79 the OS actually supports it: Win 95 does not, NT does. */
80 # define WIN_ASYNC_IO
81
82 /** Use unbuffered I/O */
83 # define UNIV_NON_BUFFERED_IO
84
85 /** File handle */
86 # define os_file_t HANDLE
87
88 /** Convert a C file descriptor to a native file handle
89 @param fd file descriptor
90 @return native file handle */
91 # define OS_FILE_FROM_FD(fd) (HANDLE) _get_osfhandle(fd)
92
93 #else /* _WIN32 */
94
95 typedef DIR* os_file_dir_t; /*!< directory stream */
96
97 /** File handle */
98 typedef int os_file_t;
99
100 /** Convert a C file descriptor to a native file handle
101 @param fd file descriptor
102 @return native file handle */
103 # define OS_FILE_FROM_FD(fd) fd
104
105 #endif /* _WIN32 */
106
107 /** Umask for creating files */
108 extern ulint os_innodb_umask;
109
110 /** Common file descriptor for file IO instrumentation with PFS
111 on windows and other platforms */
112 struct pfs_os_file_t
113 {
114 os_file_t m_file;
115 #ifdef UNIV_PFS_IO
116 struct PSI_file *m_psi;
117 #endif
118 };
119
120 static const os_file_t OS_FILE_CLOSED = os_file_t(~0);
121
122 /** The next value should be smaller or equal to the smallest sector size used
123 on any disk. A log block is required to be a portion of disk which is written
124 so that if the start and the end of a block get written to disk, then the
125 whole block gets written. This should be true even in most cases of a crash:
126 if this fails for a log block, then it is equivalent to a media failure in the
127 log. */
128
129 #define OS_FILE_LOG_BLOCK_SIZE srv_log_block_size
130
131 /** Options for os_file_create_func @{ */
132 enum os_file_create_t {
133 OS_FILE_OPEN = 51, /*!< to open an existing file (if
134 doesn't exist, error) */
135 OS_FILE_CREATE, /*!< to create new file (if
136 exists, error) */
137 OS_FILE_OVERWRITE, /*!< to create a new file, if exists
138 the overwrite old file */
139 OS_FILE_OPEN_RAW, /*!< to open a raw device or disk
140 partition */
141 OS_FILE_CREATE_PATH, /*!< to create the directories */
142 OS_FILE_OPEN_RETRY, /*!< open with retry */
143
144 /** Flags that can be combined with the above values. Please ensure
145 that the above values stay below 128. */
146
147 OS_FILE_ON_ERROR_NO_EXIT = 128, /*!< do not exit on unknown errors */
148 OS_FILE_ON_ERROR_SILENT = 256 /*!< don't print diagnostic messages to
149 the log unless it is a fatal error,
150 this flag is only used if
151 ON_ERROR_NO_EXIT is set */
152 };
153
154 static const ulint OS_FILE_READ_ONLY = 333;
155 static const ulint OS_FILE_READ_WRITE = 444;
156
157 /** Used by MySQLBackup */
158 static const ulint OS_FILE_READ_ALLOW_DELETE = 555;
159
160 /* Options for file_create */
161 static const ulint OS_FILE_AIO = 61;
162 static const ulint OS_FILE_NORMAL = 62;
163 /* @} */
164
165 /** Types for file create @{ */
166 static const ulint OS_DATA_FILE = 100;
167 static const ulint OS_LOG_FILE = 101;
168 static const ulint OS_DATA_TEMP_FILE = 102;
169 /* @} */
170
171 /** Error codes from os_file_get_last_error @{ */
172 static const ulint OS_FILE_NOT_FOUND = 71;
173 static const ulint OS_FILE_DISK_FULL = 72;
174 static const ulint OS_FILE_ALREADY_EXISTS = 73;
175 static const ulint OS_FILE_PATH_ERROR = 74;
176
177 /** wait for OS aio resources to become available again */
178 static const ulint OS_FILE_AIO_RESOURCES_RESERVED = 75;
179
180 static const ulint OS_FILE_SHARING_VIOLATION = 76;
181 static const ulint OS_FILE_ERROR_NOT_SPECIFIED = 77;
182 static const ulint OS_FILE_INSUFFICIENT_RESOURCE = 78;
183 static const ulint OS_FILE_AIO_INTERRUPTED = 79;
184 static const ulint OS_FILE_OPERATION_ABORTED = 80;
185 static const ulint OS_FILE_ACCESS_VIOLATION = 81;
186 static const ulint OS_FILE_ERROR_MAX = 100;
187 /* @} */
188
189 /** Compression algorithm. */
190 struct Compression {
191
192 /** Algorithm types supported */
193 enum Type {
194 /* Note: During recovery we don't have the compression type
195 because the .frm file has not been read yet. Therefore
196 we write the recovered pages out without compression. */
197
198 /** No compression */
199 NONE = 0,
200
201 /** Use ZLib */
202 ZLIB = 1,
203
204 /** Use LZ4 faster variant, usually lower compression. */
205 LZ4 = 2
206 };
207
208 /** Compressed page meta-data */
209 struct meta_t {
210
211 /** Version number */
212 uint8_t m_version;
213
214 /** Algorithm type */
215 Type m_algorithm;
216
217 /** Original page type */
218 uint16_t m_original_type;
219
220 /** Original page size, before compression */
221 uint16_t m_original_size;
222
223 /** Size after compression */
224 uint16_t m_compressed_size;
225 };
226
227 /** Default constructor */
CompressionCompression228 Compression() : m_type(NONE) { };
229
230 /** Specific constructor
231 @param[in] type Algorithm type */
CompressionCompression232 explicit Compression(Type type)
233 :
234 m_type(type)
235 {
236 #ifdef UNIV_DEBUG
237 switch (m_type) {
238 case NONE:
239 case ZLIB:
240 case LZ4:
241
242 default:
243 ut_error;
244 }
245 #endif /* UNIV_DEBUG */
246 }
247
248 /** Version of compressed page */
249 static const uint8_t FIL_PAGE_VERSION_1 = 1;
250 static const uint8_t FIL_PAGE_VERSION_2 = 2;
251
252 /** Check the page header type field.
253 @param[in] page Page contents
254 @return true if it is a compressed page */
255 static bool is_compressed_page(const byte* page)
256 MY_ATTRIBUTE((warn_unused_result));
257
258 /** Check the page header type field.
259 @param[in] page Page contents
260 @return true if it is a compressed and encrypted page */
261 static bool is_compressed_encrypted_page(const byte *page)
262 MY_ATTRIBUTE((warn_unused_result));
263
264 /** Check if the version on page is valid.
265 @param[in] version version
266 @return true if version is valid */
267 static bool is_valid_page_version(uint8_t version);
268
269 /** Check wether the compression algorithm is supported.
270 @param[in] algorithm Compression algorithm to check
271 @param[out] type The type that algorithm maps to
272 @return DB_SUCCESS or error code */
273 static dberr_t check(const char* algorithm, Compression* type)
274 MY_ATTRIBUTE((warn_unused_result));
275
276 /** Validate the algorithm string.
277 @param[in] algorithm Compression algorithm to check
278 @return DB_SUCCESS or error code */
279 static dberr_t validate(const char* algorithm)
280 MY_ATTRIBUTE((warn_unused_result));
281
282 /** Convert to a "string".
283 @param[in] type The compression type
284 @return the string representation */
285 static const char* to_string(Type type)
286 MY_ATTRIBUTE((warn_unused_result));
287
288 /** Convert the meta data to a std::string.
289 @param[in] meta Page Meta data
290 @return the string representation */
291 static std::string to_string(const meta_t& meta)
292 MY_ATTRIBUTE((warn_unused_result));
293
294 /** Deserizlise the page header compression meta-data
295 @param[in] header Pointer to the page header
296 @param[out] control Deserialised data */
297 static void deserialize_header(
298 const byte* page,
299 meta_t* control);
300
301 /** Check if the string is "empty" or "none".
302 @param[in] algorithm Compression algorithm to check
303 @return true if no algorithm requested */
304 static bool is_none(const char* algorithm)
305 MY_ATTRIBUTE((warn_unused_result));
306
307 /** Decompress the page data contents. Page type must be
308 FIL_PAGE_COMPRESSED, if not then the source contents are
309 left unchanged and DB_SUCCESS is returned.
310 @param[in] dblwr_recover true of double write recovery
311 in progress
312 @param[in,out] src Data read from disk, decompressed
313 data will be copied to this page
314 @param[in,out] dst Scratch area to use for decompression
315 @param[in] dst_len Size of the scratch area in bytes
316 @return DB_SUCCESS or error code */
317 static dberr_t deserialize(
318 bool dblwr_recover,
319 byte* src,
320 byte* dst,
321 ulint dst_len)
322 MY_ATTRIBUTE((warn_unused_result));
323
324 /** Compression type */
325 Type m_type;
326 };
327
328 /** Encryption key length */
329 static const ulint ENCRYPTION_KEY_LEN = 32;
330
331 /** Encryption magic bytes size */
332 static const ulint ENCRYPTION_MAGIC_SIZE = 3;
333
334 /** Encryption magic bytes for 5.7.11, it's for checking the encryption information
335 version. */
336 static const char ENCRYPTION_KEY_MAGIC_V1[] = "lCA";
337
338 /** Encryption magic bytes for 5.7.12+, it's for checking the encryption information
339 version. */
340 static const char ENCRYPTION_KEY_MAGIC_V2[] = "lCB";
341
342 /** Encryption magic bytes for 5.7.28+, it's for checking the encryption
343 information version. */
344 static const char ENCRYPTION_KEY_MAGIC_V3[] = "lCC";
345
346 /** Encryption magic bytes for not yet flushed page */
347 static const char ENCRYPTION_KEY_MAGIC_EMPTY[] = "\0\0\0";
348
349 /** Encryption master key prifix */
350 static const char ENCRYPTION_MASTER_KEY_PRIFIX[] = "INNODBKey";
351
352 /** Encryption master key prifix size */
353 static const ulint ENCRYPTION_MASTER_KEY_PRIFIX_LEN = 9;
354
355 /** Encryption master key prifix size */
356 static const ulint ENCRYPTION_MASTER_KEY_NAME_MAX_LEN = 100;
357
358 /** UUID of server instance, it's needed for composing master key name */
359 static const ulint ENCRYPTION_SERVER_UUID_LEN = 36;
360
361 /** Encryption information total size for 5.7.11: magic number + master_key_id +
362 key + iv + checksum */
363 static const ulint ENCRYPTION_INFO_SIZE_V1 = (ENCRYPTION_MAGIC_SIZE \
364 + (ENCRYPTION_KEY_LEN * 2) \
365 + 2 * sizeof(ulint));
366
367 /** Encryption information total size: magic number + master_key_id +
368 key + iv + server_uuid + checksum */
369 static const ulint ENCRYPTION_INFO_SIZE_V2 = (ENCRYPTION_MAGIC_SIZE \
370 + (ENCRYPTION_KEY_LEN * 2) \
371 + ENCRYPTION_SERVER_UUID_LEN \
372 + 2 * sizeof(ulint));
373
374 class IORequest;
375
376 /** Encryption algorithm. */
377 struct Encryption {
378
379 /** Algorithm types supported */
380 enum Type {
381
382 /** No encryption */
383 NONE = 0,
384
385 /** Use AES */
386 AES = 1,
387 };
388
389 /** Encryption information format version */
390 enum Version {
391
392 /** Version in 5.7.11 */
393 ENCRYPTION_VERSION_1 = 0,
394
395 /** Version in > 5.7.11 */
396 ENCRYPTION_VERSION_2 = 1,
397
398 /** Version in > 5.7.29 */
399 ENCRYPTION_VERSION_3 = 2,
400 };
401
402 /** Default constructor */
EncryptionEncryption403 Encryption() : m_type(NONE) { };
404
405 /** Specific constructor
406 @param[in] type Algorithm type */
EncryptionEncryption407 explicit Encryption(Type type)
408 :
409 m_type(type)
410 {
411 #ifdef UNIV_DEBUG
412 switch (m_type) {
413 case NONE:
414 case AES:
415
416 default:
417 ut_error;
418 }
419 #endif /* UNIV_DEBUG */
420 }
421
422 /** Copy constructor */
EncryptionEncryption423 Encryption(const Encryption& other)
424 :
425 m_type(other.m_type),
426 m_key(other.m_key),
427 m_klen(other.m_klen),
428 m_iv(other.m_iv)
429 { };
430
431 /** Check if page is encrypted page or not
432 @param[in] page page which need to check
433 @return true if it is a encrypted page */
434 static bool is_encrypted_page(const byte* page)
435 MY_ATTRIBUTE((warn_unused_result));
436
437 /** Check the encryption option and set it
438 @param[in] option encryption option
439 @param[in/out] encryption The encryption type
440 @return DB_SUCCESS or DB_UNSUPPORTED */
441 dberr_t set_algorithm(const char* option, Encryption* type)
442 MY_ATTRIBUTE((warn_unused_result));
443
444 /** Validate the algorithm string.
445 @param[in] algorithm Encryption algorithm to check
446 @return DB_SUCCESS or error code */
447 static dberr_t validate(const char* algorithm)
448 MY_ATTRIBUTE((warn_unused_result));
449
450 /** Convert to a "string".
451 @param[in] type The encryption type
452 @return the string representation */
453 static const char* to_string(Type type)
454 MY_ATTRIBUTE((warn_unused_result));
455
456 /** Check if the string is "empty" or "none".
457 @param[in] algorithm Encryption algorithm to check
458 @return true if no algorithm requested */
459 static bool is_none(const char* algorithm)
460 MY_ATTRIBUTE((warn_unused_result));
461
462 /** Generate random encryption value for key and iv.
463 @param[in,out] value Encryption value */
464 static void random_value(byte* value);
465
466 /** Create new master key for key rotation.
467 @param[in,out] master_key master key */
468 static void create_master_key_v0(byte** master_key);
469
470 /** Create new master key for key rotation.
471 @param[in,out] master_key master key */
472 static void create_master_key(byte** master_key);
473
474 /** Get master key by key id.
475 @param[in] master_key_id master key id
476 @param[in] srv_uuid uuid of server instance
477 @param[in,out] master_key master key */
478 static void get_master_key(ulint master_key_id,
479 char* srv_uuid,
480 byte** master_key);
481
482 /** Get current master key and key id.
483 @param[in,out] master_key_id master key id
484 @param[in,out] master_key master key
485 @param[in,out] version encryption information version */
486 static void get_master_key(ulint* master_key_id,
487 byte** master_key,
488 Encryption::Version* version);
489
490 /** Encrypt the page data contents. Page type can't be
491 FIL_PAGE_ENCRYPTED, FIL_PAGE_COMPRESSED_AND_ENCRYPTED,
492 FIL_PAGE_ENCRYPTED_RTREE.
493 @param[in] type IORequest
494 @param[in,out] src page data which need to encrypt
495 @param[in] src_len Size of the source in bytes
496 @param[in,out] dst destination area
497 @param[in,out] dst_len Size of the destination in bytes
498 @return buffer data, dst_len will have the length of the data */
499 byte* encrypt(
500 const IORequest& type,
501 byte* src,
502 ulint src_len,
503 byte* dst,
504 ulint* dst_len)
505 MY_ATTRIBUTE((warn_unused_result));
506
507 /** Decrypt the page data contents. Page type must be
508 FIL_PAGE_ENCRYPTED, FIL_PAGE_COMPRESSED_AND_ENCRYPTED,
509 FIL_PAGE_ENCRYPTED_RTREE, if not then the source contents are
510 left unchanged and DB_SUCCESS is returned.
511 @param[in] type IORequest
512 @param[in,out] src Data read from disk, decrypt
513 data will be copied to this page
514 @param[in] src_len source data length
515 @param[in,out] dst Scratch area to use for decrypt
516 @param[in] dst_len Size of the scratch area in bytes
517 @return DB_SUCCESS or error code */
518 dberr_t decrypt(
519 const IORequest& type,
520 byte* src,
521 ulint src_len,
522 byte* dst,
523 ulint dst_len)
524 MY_ATTRIBUTE((warn_unused_result));
525
526 /** Encrypt type */
527 Type m_type;
528
529 /** Encrypt key */
530 byte* m_key;
531
532 /** Encrypt key length*/
533 ulint m_klen;
534
535 /** Encrypt initial vector */
536 byte* m_iv;
537
538 /** Current master key id */
539 static ulint master_key_id;
540
541 /** Current uuid of server instance */
542 static char uuid[ENCRYPTION_SERVER_UUID_LEN + 1];
543
544 /** current maximum version, used to avoid writing V3 encryption on
545 old versions that support only upto V2 header */
546 static Version max_version;
547 };
548
549 /** Types for AIO operations @{ */
550
551 /** No transformations during read/write, write as is. */
552 #define IORequestRead IORequest(IORequest::READ)
553 #define IORequestWrite IORequest(IORequest::WRITE)
554 #define IORequestLogRead IORequest(IORequest::LOG | IORequest::READ)
555 #define IORequestLogWrite IORequest(IORequest::LOG | IORequest::WRITE)
556
557 /**
558 The IO Context that is passed down to the low level IO code */
559 class IORequest {
560 public:
561 /** Flags passed in the request, they can be ORred together. */
562 enum {
563 READ = 1,
564 WRITE = 2,
565
566 /** Double write buffer recovery. */
567 DBLWR_RECOVER = 4,
568
569 /** Enumarations below can be ORed to READ/WRITE above*/
570
571 /** Data file */
572 DATA_FILE = 8,
573
574 /** Log file request*/
575 LOG = 16,
576
577 /** Disable partial read warnings */
578 DISABLE_PARTIAL_IO_WARNINGS = 32,
579
580 /** Do not to wake i/o-handler threads, but the caller will do
581 the waking explicitly later, in this way the caller can post
582 several requests in a batch; NOTE that the batch must not be
583 so big that it exhausts the slots in AIO arrays! NOTE that
584 a simulated batch may introduce hidden chances of deadlocks,
585 because I/Os are not actually handled until all
586 have been posted: use with great caution! */
587 DO_NOT_WAKE = 64,
588
589 /** Ignore failed reads of non-existent pages */
590 IGNORE_MISSING = 128,
591
592 /** Use punch hole if available, only makes sense if
593 compression algorithm != NONE. Ignored if not set */
594 PUNCH_HOLE = 256,
595
596 /** Force raw read, do not try to compress/decompress.
597 This can be used to force a read and write without any
598 compression e.g., for redo log, merge sort temporary files
599 and the truncate redo log. */
600 NO_COMPRESSION = 512
601 };
602
603 /** Default constructor */
IORequest()604 IORequest()
605 :
606 m_block_size(UNIV_SECTOR_SIZE),
607 m_type(READ),
608 m_compression(),
609 m_encryption()
610 {
611 /* No op */
612 }
613
614 /**
615 @param[in] type Request type, can be a value that is
616 ORed from the above enum */
IORequest(ulint type)617 explicit IORequest(ulint type)
618 :
619 m_block_size(UNIV_SECTOR_SIZE),
620 m_type(static_cast<uint16_t>(type)),
621 m_compression(),
622 m_encryption()
623 {
624 if (is_log()) {
625 disable_compression();
626 }
627
628 if (!is_punch_hole_supported()) {
629 clear_punch_hole();
630 }
631 }
632
633 /** Destructor */
~IORequest()634 ~IORequest() { }
635
636 /** @return true if ignore missing flag is set */
ignore_missing(ulint type)637 static bool ignore_missing(ulint type)
638 MY_ATTRIBUTE((warn_unused_result))
639 {
640 return((type & IGNORE_MISSING) == IGNORE_MISSING);
641 }
642
643 /** @return true if it is a read request */
is_read()644 bool is_read() const
645 MY_ATTRIBUTE((warn_unused_result))
646 {
647 return((m_type & READ) == READ);
648 }
649
650 /** @return true if it is a write request */
is_write()651 bool is_write() const
652 MY_ATTRIBUTE((warn_unused_result))
653 {
654 return((m_type & WRITE) == WRITE);
655 }
656
657 /** @return true if it is a redo log write */
is_log()658 bool is_log() const
659 MY_ATTRIBUTE((warn_unused_result))
660 {
661 return((m_type & LOG) == LOG);
662 }
663
664 /** @return true if the simulated AIO thread should be woken up */
is_wake()665 bool is_wake() const
666 MY_ATTRIBUTE((warn_unused_result))
667 {
668 return((m_type & DO_NOT_WAKE) == 0);
669 }
670
671 /** @return true if partial read warning disabled */
is_partial_io_warning_disabled()672 bool is_partial_io_warning_disabled() const
673 MY_ATTRIBUTE((warn_unused_result))
674 {
675 return((m_type & DISABLE_PARTIAL_IO_WARNINGS)
676 == DISABLE_PARTIAL_IO_WARNINGS);
677 }
678
679 /** Disable partial read warnings */
disable_partial_io_warnings()680 void disable_partial_io_warnings()
681 {
682 m_type |= DISABLE_PARTIAL_IO_WARNINGS;
683 }
684
685 /** @return true if missing files should be ignored */
ignore_missing()686 bool ignore_missing() const
687 MY_ATTRIBUTE((warn_unused_result))
688 {
689 return(ignore_missing(m_type));
690 }
691
692 /** @return true if punch hole should be used */
punch_hole()693 bool punch_hole() const
694 MY_ATTRIBUTE((warn_unused_result))
695 {
696 return((m_type & PUNCH_HOLE) == PUNCH_HOLE);
697 }
698
699 /** @return true if the read should be validated */
validate()700 bool validate() const
701 MY_ATTRIBUTE((warn_unused_result))
702 {
703 ut_a(is_read() ^ is_write());
704
705 return(!is_read() || !punch_hole());
706 }
707
708 /** Set the punch hole flag */
set_punch_hole()709 void set_punch_hole()
710 {
711 if (is_punch_hole_supported()) {
712 m_type |= PUNCH_HOLE;
713 }
714 }
715
716 /** Clear the do not wake flag */
clear_do_not_wake()717 void clear_do_not_wake()
718 {
719 m_type &= ~DO_NOT_WAKE;
720 }
721
722 /** Clear the punch hole flag */
clear_punch_hole()723 void clear_punch_hole()
724 {
725 m_type &= ~PUNCH_HOLE;
726 }
727
728 /** @return the block size to use for IO */
block_size()729 ulint block_size() const
730 MY_ATTRIBUTE((warn_unused_result))
731 {
732 return(m_block_size);
733 }
734
735 /** Set the block size for IO
736 @param[in] block_size Block size to set */
block_size(ulint block_size)737 void block_size(ulint block_size)
738 {
739 m_block_size = static_cast<uint32_t>(block_size);
740 }
741
742 /** Clear all compression related flags */
clear_compressed()743 void clear_compressed()
744 {
745 clear_punch_hole();
746
747 m_compression.m_type = Compression::NONE;
748 }
749
750 /** Compare two requests
751 @reutrn true if the are equal */
752 bool operator==(const IORequest& rhs) const
753 {
754 return(m_type == rhs.m_type);
755 }
756
757 /** Set compression algorithm
758 @param[in] compression The compression algorithm to use */
compression_algorithm(Compression::Type type)759 void compression_algorithm(Compression::Type type)
760 {
761 if (type == Compression::NONE) {
762 return;
763 }
764
765 set_punch_hole();
766
767 m_compression.m_type = type;
768 }
769
770 /** Get the compression algorithm.
771 @return the compression algorithm */
compression_algorithm()772 Compression compression_algorithm() const
773 MY_ATTRIBUTE((warn_unused_result))
774 {
775 return(m_compression);
776 }
777
778 /** @return true if the page should be compressed */
is_compressed()779 bool is_compressed() const
780 MY_ATTRIBUTE((warn_unused_result))
781 {
782 return(compression_algorithm().m_type != Compression::NONE);
783 }
784
785 /** @return true if the page read should not be transformed. */
is_compression_enabled()786 bool is_compression_enabled() const
787 MY_ATTRIBUTE((warn_unused_result))
788 {
789 return((m_type & NO_COMPRESSION) == 0);
790 }
791
792 /** Disable transformations. */
disable_compression()793 void disable_compression()
794 {
795 m_type |= NO_COMPRESSION;
796 }
797
798 /** Set encryption algorithm
799 @param[in] type The encryption algorithm to use */
encryption_algorithm(Encryption::Type type)800 void encryption_algorithm(Encryption::Type type)
801 {
802 if (type == Encryption::NONE) {
803 return;
804 }
805
806 m_encryption.m_type = type;
807 }
808
809 /** Set encryption key and iv
810 @param[in] key The encryption key to use
811 @param[in] key_len length of the encryption key
812 @param[in] iv The encryption iv to use */
encryption_key(byte * key,ulint key_len,byte * iv)813 void encryption_key(byte* key,
814 ulint key_len,
815 byte* iv)
816 {
817 m_encryption.m_key = key;
818 m_encryption.m_klen = key_len;
819 m_encryption.m_iv = iv;
820 }
821
822 /** Get the encryption algorithm.
823 @return the encryption algorithm */
encryption_algorithm()824 Encryption encryption_algorithm() const
825 MY_ATTRIBUTE((warn_unused_result))
826 {
827 return(m_encryption);
828 }
829
830 /** @return true if the page should be encrypted. */
is_encrypted()831 bool is_encrypted() const
832 MY_ATTRIBUTE((warn_unused_result))
833 {
834 return(m_encryption.m_type != Encryption::NONE);
835 }
836
837 /** Clear all encryption related flags */
clear_encrypted()838 void clear_encrypted()
839 {
840 m_encryption.m_key = NULL;
841 m_encryption.m_klen = 0;
842 m_encryption.m_iv = NULL;
843 m_encryption.m_type = Encryption::NONE;
844 }
845
846 /** Note that the IO is for double write recovery. */
dblwr_recover()847 void dblwr_recover()
848 {
849 m_type |= DBLWR_RECOVER;
850 }
851
852 /** @return true if the request is from the dblwr recovery */
is_dblwr_recover()853 bool is_dblwr_recover() const
854 MY_ATTRIBUTE((warn_unused_result))
855 {
856 return((m_type & DBLWR_RECOVER) == DBLWR_RECOVER);
857 }
858
859 /** @return true if punch hole is supported */
is_punch_hole_supported()860 static bool is_punch_hole_supported()
861 {
862
863 /* In this debugging mode, we act as if punch hole is supported,
864 and then skip any calls to actually punch a hole here.
865 In this way, Transparent Page Compression is still being tested. */
866 DBUG_EXECUTE_IF("ignore_punch_hole",
867 return(true);
868 );
869
870 #if defined(HAVE_FALLOC_PUNCH_HOLE_AND_KEEP_SIZE) || defined(_WIN32)
871 return(true);
872 #else
873 return(false);
874 #endif /* HAVE_FALLOC_PUNCH_HOLE_AND_KEEP_SIZE || _WIN32 */
875 }
876
877 private:
878 /* File system best block size */
879 uint32_t m_block_size;
880
881 /** Request type bit flags */
882 uint16_t m_type;
883
884 /** Compression algorithm */
885 Compression m_compression;
886
887 /** Encryption algorithm */
888 Encryption m_encryption;
889 };
890
891 /* @} */
892
893 /** Sparse file size information. */
894 struct os_file_size_t {
895 /** Total size of file in bytes */
896 os_offset_t m_total_size;
897
898 /** If it is a sparse file then this is the number of bytes
899 actually allocated for the file. */
900 os_offset_t m_alloc_size;
901 };
902
903 /** Win NT does not allow more than 64 */
904 static const ulint OS_AIO_N_PENDING_IOS_PER_THREAD = 32;
905
906 /** Modes for aio operations @{ */
907 /** Normal asynchronous i/o not for ibuf pages or ibuf bitmap pages */
908 static const ulint OS_AIO_NORMAL = 21;
909
910 /** Asynchronous i/o for ibuf pages or ibuf bitmap pages */
911 static const ulint OS_AIO_IBUF = 22;
912
913 /** Asynchronous i/o for the log */
914 static const ulint OS_AIO_LOG = 23;
915
916 /** Asynchronous i/o where the calling thread will itself wait for
917 the i/o to complete, doing also the job of the i/o-handler thread;
918 can be used for any pages, ibuf or non-ibuf. This is used to save
919 CPU time, as we can do with fewer thread switches. Plain synchronous
920 I/O is not as good, because it must serialize the file seek and read
921 or write, causing a bottleneck for parallelism. */
922 static const ulint OS_AIO_SYNC = 24;
923 /* @} */
924
925 extern ulint os_n_file_reads;
926 extern ulint os_n_file_writes;
927 extern ulint os_n_fsyncs;
928
929 #define OS_MIN_LOG_BLOCK_SIZE 512
930
931 extern ulint srv_log_block_size;
932
933 /* File types for directory entry data type */
934
935 enum os_file_type_t {
936 OS_FILE_TYPE_UNKNOWN = 0,
937 OS_FILE_TYPE_FILE, /* regular file */
938 OS_FILE_TYPE_DIR, /* directory */
939 OS_FILE_TYPE_LINK, /* symbolic link */
940 OS_FILE_TYPE_BLOCK /* block device */
941 };
942
943 /* Maximum path string length in bytes when referring to tables with in the
944 './databasename/tablename.ibd' path format; we can allocate at least 2 buffers
945 of this size from the thread stack; that is why this should not be made much
946 bigger than 4000 bytes. The maximum path length used by any storage engine
947 in the server must be at least this big. */
948 #define OS_FILE_MAX_PATH 4000
949 #if (FN_REFLEN_SE < OS_FILE_MAX_PATH)
950 # error "(FN_REFLEN_SE < OS_FILE_MAX_PATH)"
951 #endif
952
953 /** Struct used in fetching information of a file in a directory */
954 struct os_file_stat_t {
955 char name[OS_FILE_MAX_PATH]; /*!< path to a file */
956 os_file_type_t type; /*!< file type */
957 os_offset_t size; /*!< file size in bytes */
958 os_offset_t alloc_size; /*!< Allocated size for
959 sparse files in bytes */
960 size_t block_size; /*!< Block size to use for IO
961 in bytes*/
962 time_t ctime; /*!< creation time */
963 time_t mtime; /*!< modification time */
964 time_t atime; /*!< access time */
965 bool rw_perm; /*!< true if can be opened
966 in read-write mode. Only valid
967 if type == OS_FILE_TYPE_FILE */
968 };
969
970 #ifndef UNIV_HOTBACKUP
971 /** Create a temporary file. This function is like tmpfile(3), but
972 the temporary file is created in the given parameter path. If the path
973 is null then it will create the file in the mysql server configuration
974 parameter (--tmpdir).
975 @param[in] path location for creating temporary file
976 @return temporary file handle, or NULL on error */
977 FILE*
978 os_file_create_tmpfile(
979 const char* path);
980 #endif /* !UNIV_HOTBACKUP */
981
982 /** The os_file_opendir() function opens a directory stream corresponding to the
983 directory named by the dirname argument. The directory stream is positioned
984 at the first entry. In both Unix and Windows we automatically skip the '.'
985 and '..' items at the start of the directory listing.
986
987 @param[in] dirname directory name; it must not contain a trailing
988 '\' or '/'
989 @param[in] is_fatal true if we should treat an error as a fatal
990 error; if we try to open symlinks then we do
991 not wish a fatal error if it happens not to be
992 a directory
993 @return directory stream, NULL if error */
994 os_file_dir_t
995 os_file_opendir(
996 const char* dirname,
997 bool is_fatal);
998
999 /**
1000 Closes a directory stream.
1001 @param[in] dir directory stream
1002 @return 0 if success, -1 if failure */
1003 int
1004 os_file_closedir(
1005 os_file_dir_t dir);
1006
1007 /** This function returns information of the next file in the directory. We jump
1008 over the '.' and '..' entries in the directory.
1009 @param[in] dirname directory name or path
1010 @param[in] dir directory stream
1011 @param[out] info buffer where the info is returned
1012 @return 0 if ok, -1 if error, 1 if at the end of the directory */
1013 int
1014 os_file_readdir_next_file(
1015 const char* dirname,
1016 os_file_dir_t dir,
1017 os_file_stat_t* info);
1018
1019 /**
1020 This function attempts to create a directory named pathname. The new directory
1021 gets default permissions. On Unix, the permissions are (0770 & ~umask). If the
1022 directory exists already, nothing is done and the call succeeds, unless the
1023 fail_if_exists arguments is true.
1024
1025 @param[in] pathname directory name as null-terminated string
1026 @param[in] fail_if_exists if true, pre-existing directory is treated
1027 as an error.
1028 @return true if call succeeds, false on error */
1029 bool
1030 os_file_create_directory(
1031 const char* pathname,
1032 bool fail_if_exists);
1033
1034 /** NOTE! Use the corresponding macro os_file_create_simple(), not directly
1035 this function!
1036 A simple function to open or create a file.
1037 @param[in] name name of the file or path as a null-terminated
1038 string
1039 @param[in] create_mode create mode
1040 @param[in] access_type OS_FILE_READ_ONLY or OS_FILE_READ_WRITE
1041 @param[in] read_only if true read only mode checks are enforced
1042 @param[out] success true if succeed, false if error
1043 @return own: handle to the file, not defined if error, error number
1044 can be retrieved with os_file_get_last_error */
1045 pfs_os_file_t
1046 os_file_create_simple_func(
1047 const char* name,
1048 ulint create_mode,
1049 ulint access_type,
1050 bool read_only,
1051 bool* success);
1052
1053 /** NOTE! Use the corresponding macro
1054 os_file_create_simple_no_error_handling(), not directly this function!
1055 A simple function to open or create a file.
1056 @param[in] name name of the file or path as a null-terminated string
1057 @param[in] create_mode create mode
1058 @param[in] access_type OS_FILE_READ_ONLY, OS_FILE_READ_WRITE, or
1059 OS_FILE_READ_ALLOW_DELETE; the last option
1060 is used by a backup program reading the file
1061 @param[in] read_only if true read only mode checks are enforced
1062 @param[out] success true if succeeded
1063 @return own: handle to the file, not defined if error, error number
1064 can be retrieved with os_file_get_last_error */
1065 pfs_os_file_t
1066 os_file_create_simple_no_error_handling_func(
1067 const char* name,
1068 ulint create_mode,
1069 ulint access_type,
1070 bool read_only,
1071 bool* success)
1072 MY_ATTRIBUTE((warn_unused_result));
1073
1074 /** Tries to disable OS caching on an opened file descriptor.
1075 @param[in] fd file descriptor to alter
1076 @param[in] file_name file name, used in the diagnostic message
1077 @param[in] name "open" or "create"; used in the diagnostic
1078 message */
1079 void
1080 os_file_set_nocache(
1081 int fd,
1082 const char* file_name,
1083 const char* operation_name);
1084
1085 /** NOTE! Use the corresponding macro os_file_create(), not directly
1086 this function!
1087 Opens an existing file or creates a new.
1088 @param[in] name name of the file or path as a null-terminated
1089 string
1090 @param[in] create_mode create mode
1091 @param[in] purpose OS_FILE_AIO, if asynchronous, non-buffered I/O
1092 is desired, OS_FILE_NORMAL, if any normal file;
1093 NOTE that it also depends on type, os_aio_..
1094 and srv_.. variables whether we really use
1095 async I/O or unbuffered I/O: look in the
1096 function source code for the exact rules
1097 @param[in] type OS_DATA_FILE or OS_LOG_FILE
1098 @param[in] read_only if true read only mode checks are enforced
1099 @param[in] success true if succeeded
1100 @return own: handle to the file, not defined if error, error number
1101 can be retrieved with os_file_get_last_error */
1102 pfs_os_file_t
1103 os_file_create_func(
1104 const char* name,
1105 ulint create_mode,
1106 ulint purpose,
1107 ulint type,
1108 bool read_only,
1109 bool* success)
1110 MY_ATTRIBUTE((warn_unused_result));
1111
1112 /** Deletes a file. The file has to be closed before calling this.
1113 @param[in] name file path as a null-terminated string
1114 @return true if success */
1115 bool
1116 os_file_delete_func(const char* name);
1117
1118 /** Deletes a file if it exists. The file has to be closed before calling this.
1119 @param[in] name file path as a null-terminated string
1120 @param[out] exist indicate if file pre-exist
1121 @return true if success */
1122 bool
1123 os_file_delete_if_exists_func(const char* name, bool* exist);
1124
1125 /** NOTE! Use the corresponding macro os_file_rename(), not directly
1126 this function!
1127 Renames a file (can also move it to another directory). It is safest that the
1128 file is closed before calling this function.
1129 @param[in] oldpath old file path as a null-terminated string
1130 @param[in] newpath new file path
1131 @return true if success */
1132 bool
1133 os_file_rename_func(const char* oldpath, const char* newpath);
1134
1135 /** NOTE! Use the corresponding macro os_file_close(), not directly this
1136 function!
1137 Closes a file handle. In case of error, error number can be retrieved with
1138 os_file_get_last_error.
1139 @param[in] file own: handle to a file
1140 @return true if success */
1141 bool
1142 os_file_close_func(os_file_t file);
1143
1144 #ifdef UNIV_PFS_IO
1145
1146 /* Keys to register InnoDB I/O with performance schema */
1147 extern mysql_pfs_key_t innodb_data_file_key;
1148 extern mysql_pfs_key_t innodb_log_file_key;
1149 extern mysql_pfs_key_t innodb_temp_file_key;
1150
1151 /* Following four macros are instumentations to register
1152 various file I/O operations with performance schema.
1153 1) register_pfs_file_open_begin() and register_pfs_file_open_end() are
1154 used to register file creation, opening, closing and renaming.
1155 2) register_pfs_file_rename_begin() and register_pfs_file_rename_end()
1156 are used to register file renaming
1157 3) register_pfs_file_io_begin() and register_pfs_file_io_end() are
1158 used to register actual file read, write and flush
1159 3) register_pfs_file_close_begin() and register_pfs_file_close_end()
1160 are used to register file deletion operations*/
1161 # define register_pfs_file_open_begin(state, locker, key, op, name, \
1162 src_file, src_line) \
1163 do { \
1164 locker = PSI_FILE_CALL(get_thread_file_name_locker)( \
1165 state, key.m_value, op, name, &locker); \
1166 if (locker != NULL) { \
1167 PSI_FILE_CALL(start_file_open_wait)( \
1168 locker, src_file, static_cast<uint>(src_line)); \
1169 } \
1170 } while (0)
1171
1172 # define register_pfs_file_open_end(locker, file, result) \
1173 do { \
1174 if (locker != NULL) { \
1175 file.m_psi = PSI_FILE_CALL( \
1176 end_file_open_wait)( \
1177 locker, result); \
1178 } \
1179 } while (0)
1180
1181 # define register_pfs_file_rename_begin(state, locker, key, op, name, \
1182 src_file, src_line) \
1183 register_pfs_file_open_begin( \
1184 state, locker, key, op, name, \
1185 src_file, static_cast<uint>(src_line)) \
1186
1187 # define register_pfs_file_rename_end(locker, from, to, result) \
1188 do { \
1189 if (locker != NULL) { \
1190 PSI_FILE_CALL( \
1191 end_file_rename_wait)( \
1192 locker, from, to, result); \
1193 } \
1194 }while(0)
1195
1196 # define register_pfs_file_close_begin(state, locker, key, op, name, \
1197 src_file, src_line) \
1198 do { \
1199 locker = PSI_FILE_CALL(get_thread_file_name_locker)( \
1200 state, key.m_value, op, name, &locker); \
1201 if (locker != NULL) { \
1202 PSI_FILE_CALL(start_file_close_wait)( \
1203 locker, src_file, static_cast<uint>(src_line)); \
1204 } \
1205 } while (0)
1206
1207 # define register_pfs_file_close_end(locker, result) \
1208 do { \
1209 if (locker != NULL) { \
1210 PSI_FILE_CALL(end_file_close_wait)( \
1211 locker, result); \
1212 } \
1213 } while (0)
1214
1215 # define register_pfs_file_io_begin(state, locker, file, count, op, \
1216 src_file, src_line) \
1217 do { \
1218 locker = PSI_FILE_CALL(get_thread_file_stream_locker)( \
1219 state, file.m_psi, op); \
1220 if (locker != NULL) { \
1221 PSI_FILE_CALL(start_file_wait)( \
1222 locker, count, \
1223 src_file, static_cast<uint>(src_line)); \
1224 } \
1225 } while (0)
1226
1227 # define register_pfs_file_io_end(locker, count) \
1228 do { \
1229 if (locker != NULL) { \
1230 PSI_FILE_CALL(end_file_wait)(locker, count); \
1231 } \
1232 } while (0)
1233
1234 /* Following macros/functions are file I/O APIs that would be performance
1235 schema instrumented if "UNIV_PFS_IO" is defined. They would point to
1236 wrapper functions with performance schema instrumentation in such case.
1237
1238 os_file_create
1239 os_file_create_simple
1240 os_file_create_simple_no_error_handling
1241 os_file_close
1242 os_file_rename
1243 os_aio
1244 os_file_read
1245 os_file_read_no_error_handling
1246 os_file_read_no_error_handling_int_fd
1247 os_file_write
1248
1249 The wrapper functions have the prefix of "innodb_". */
1250
1251 # define os_file_create(key, name, create, purpose, type, read_only, \
1252 success) \
1253 pfs_os_file_create_func(key, name, create, purpose, type, \
1254 read_only, success, __FILE__, __LINE__)
1255
1256 # define os_file_create_simple(key, name, create, access, \
1257 read_only, success) \
1258 pfs_os_file_create_simple_func(key, name, create, access, \
1259 read_only, success, __FILE__, __LINE__)
1260
1261 # define os_file_create_simple_no_error_handling( \
1262 key, name, create_mode, access, read_only, success) \
1263 pfs_os_file_create_simple_no_error_handling_func( \
1264 key, name, create_mode, access, \
1265 read_only, success, __FILE__, __LINE__)
1266
1267 # define os_file_close_pfs(file) \
1268 pfs_os_file_close_func(file, __FILE__, __LINE__)
1269
1270 # define os_aio(type, mode, name, file, buf, offset, \
1271 n, read_only, message1, message2) \
1272 pfs_os_aio_func(type, mode, name, file, buf, offset, \
1273 n, read_only, message1, message2, \
1274 __FILE__, __LINE__)
1275
1276 # define os_file_read_pfs(type, file, buf, offset, n) \
1277 pfs_os_file_read_func(type, file, buf, offset, n, __FILE__, __LINE__)
1278
1279 # define os_file_read_no_error_handling_pfs(type, file, buf, offset, n, o) \
1280 pfs_os_file_read_no_error_handling_func( \
1281 type, file, buf, offset, n, o, __FILE__, __LINE__)
1282
1283 # define os_file_read_no_error_handling_int_fd( \
1284 type, file, buf, offset, n, o) \
1285 pfs_os_file_read_no_error_handling_int_fd_func( \
1286 type, file, buf, offset, n, o, __FILE__, __LINE__)
1287
1288 # define os_file_write_pfs(type, name, file, buf, offset, n) \
1289 pfs_os_file_write_func(type, name, file, buf, offset, \
1290 n, __FILE__, __LINE__)
1291
1292 # define os_file_write_int_fd(type, name, file, buf, offset, n) \
1293 pfs_os_file_write_int_fd_func(type, name, file, buf, offset, \
1294 n, __FILE__, __LINE__)
1295
1296 # define os_file_flush_pfs(file) \
1297 pfs_os_file_flush_func(file, __FILE__, __LINE__)
1298
1299 # define os_file_rename(key, oldpath, newpath) \
1300 pfs_os_file_rename_func(key, oldpath, newpath, __FILE__, __LINE__)
1301
1302 # define os_file_delete(key, name) \
1303 pfs_os_file_delete_func(key, name, __FILE__, __LINE__)
1304
1305 # define os_file_delete_if_exists(key, name, exist) \
1306 pfs_os_file_delete_if_exists_func(key, name, exist, __FILE__, __LINE__)
1307
1308
1309
1310 /** NOTE! Please use the corresponding macro os_file_create_simple(),
1311 not directly this function!
1312 A performance schema instrumented wrapper function for
1313 os_file_create_simple() which opens or creates a file.
1314 @param[in] key Performance Schema Key
1315 @param[in] name name of the file or path as a null-terminated
1316 string
1317 @param[in] create_mode create mode
1318 @param[in] access_type OS_FILE_READ_ONLY or OS_FILE_READ_WRITE
1319 @param[in] read_only if true read only mode checks are enforced
1320 @param[out] success true if succeeded
1321 @param[in] src_file file name where func invoked
1322 @param[in] src_line line where the func invoked
1323 @return own: handle to the file, not defined if error, error number
1324 can be retrieved with os_file_get_last_error */
1325 UNIV_INLINE
1326 pfs_os_file_t
1327 pfs_os_file_create_simple_func(
1328 mysql_pfs_key_t key,
1329 const char* name,
1330 ulint create_mode,
1331 ulint access_type,
1332 bool read_only,
1333 bool* success,
1334 const char* src_file,
1335 ulint src_line)
1336 MY_ATTRIBUTE((warn_unused_result));
1337
1338 /** NOTE! Please use the corresponding macro
1339 os_file_create_simple_no_error_handling(), not directly this function!
1340 A performance schema instrumented wrapper function for
1341 os_file_create_simple_no_error_handling(). Add instrumentation to
1342 monitor file creation/open.
1343 @param[in] key Performance Schema Key
1344 @param[in] name name of the file or path as a null-terminated
1345 string
1346 @param[in] create_mode create mode
1347 @param[in] access_type OS_FILE_READ_ONLY, OS_FILE_READ_WRITE, or
1348 OS_FILE_READ_ALLOW_DELETE; the last option is
1349 used by a backup program reading the file
1350 @param[in] read_only if true read only mode checks are enforced
1351 @param[out] success true if succeeded
1352 @param[in] src_file file name where func invoked
1353 @param[in] src_line line where the func invoked
1354 @return own: handle to the file, not defined if error, error number
1355 can be retrieved with os_file_get_last_error */
1356 UNIV_INLINE
1357 pfs_os_file_t
1358 pfs_os_file_create_simple_no_error_handling_func(
1359 mysql_pfs_key_t key,
1360 const char* name,
1361 ulint create_mode,
1362 ulint access_type,
1363 bool read_only,
1364 bool* success,
1365 const char* src_file,
1366 ulint src_line)
1367 MY_ATTRIBUTE((warn_unused_result));
1368
1369 /** NOTE! Please use the corresponding macro os_file_create(), not directly
1370 this function!
1371 A performance schema wrapper function for os_file_create().
1372 Add instrumentation to monitor file creation/open.
1373 @param[in] key Performance Schema Key
1374 @param[in] name name of the file or path as a null-terminated
1375 string
1376 @param[in] create_mode create mode
1377 @param[in] purpose OS_FILE_AIO, if asynchronous, non-buffered I/O
1378 is desired, OS_FILE_NORMAL, if any normal file;
1379 NOTE that it also depends on type, os_aio_..
1380 and srv_.. variables whether we really use
1381 async I/O or unbuffered I/O: look in the
1382 function source code for the exact rules
1383 @param[in] read_only if true read only mode checks are enforced
1384 @param[out] success true if succeeded
1385 @param[in] src_file file name where func invoked
1386 @param[in] src_line line where the func invoked
1387 @return own: handle to the file, not defined if error, error number
1388 can be retrieved with os_file_get_last_error */
1389 UNIV_INLINE
1390 pfs_os_file_t
1391 pfs_os_file_create_func(
1392 mysql_pfs_key_t key,
1393 const char* name,
1394 ulint create_mode,
1395 ulint purpose,
1396 ulint type,
1397 bool read_only,
1398 bool* success,
1399 const char* src_file,
1400 ulint src_line)
1401 MY_ATTRIBUTE((warn_unused_result));
1402
1403 /** NOTE! Please use the corresponding macro os_file_close(), not directly
1404 this function!
1405 A performance schema instrumented wrapper function for os_file_close().
1406 @param[in] file handle to a file
1407 @param[in] src_file file name where func invoked
1408 @param[in] src_line line where the func invoked
1409 @return true if success */
1410 UNIV_INLINE
1411 bool
1412 pfs_os_file_close_func(
1413 pfs_os_file_t file,
1414 const char* src_file,
1415 ulint src_line);
1416
1417 /** NOTE! Please use the corresponding macro os_file_read(), not directly
1418 this function!
1419 This is the performance schema instrumented wrapper function for
1420 os_file_read() which requests a synchronous read operation.
1421 @param[in, out] type IO request context
1422 @param[in] file Open file handle
1423 @param[out] buf buffer where to read
1424 @param[in] offset file offset where to read
1425 @param[in] n number of bytes to read
1426 @param[in] src_file file name where func invoked
1427 @param[in] src_line line where the func invoked
1428 @return DB_SUCCESS if request was successful */
1429 UNIV_INLINE
1430 dberr_t
1431 pfs_os_file_read_func(
1432 IORequest& type,
1433 pfs_os_file_t file,
1434 void* buf,
1435 os_offset_t offset,
1436 ulint n,
1437 const char* src_file,
1438 ulint src_line);
1439
1440 /** NOTE! Please use the corresponding macro os_file_read_no_error_handling(),
1441 not directly this function!
1442 This is the performance schema instrumented wrapper function for
1443 os_file_read_no_error_handling_func() which requests a synchronous
1444 read operation.
1445 @param[in, out] type IO request context
1446 @param[in] file Open file handle
1447 @param[out] buf buffer where to read
1448 @param[in] offset file offset where to read
1449 @param[in] n number of bytes to read
1450 @param[out] o number of bytes actually read
1451 @param[in] src_file file name where func invoked
1452 @param[in] src_line line where the func invoked
1453 @return DB_SUCCESS if request was successful */
1454 UNIV_INLINE
1455 dberr_t
1456 pfs_os_file_read_no_error_handling_func(
1457 IORequest& type,
1458 pfs_os_file_t file,
1459 void* buf,
1460 os_offset_t offset,
1461 ulint n,
1462 ulint* o,
1463 const char* src_file,
1464 ulint src_line);
1465
1466 /** NOTE! Please use the corresponding macro
1467 os_file_read_no_error_handling_int_fd(), not directly this function!
1468 This is the performance schema instrumented wrapper function for
1469 os_file_read_no_error_handling_int_fd_func() which requests a
1470 synchronous read operation on files with int type descriptors.
1471 @param[in, out] type IO request context
1472 @param[in] file Open file handle
1473 @param[out] buf buffer where to read
1474 @param[in] offset file offset where to read
1475 @param[in] n number of bytes to read
1476 @param[out] o number of bytes actually read
1477 @param[in] src_file file name where func invoked
1478 @param[in] src_line line where the func invoked
1479 @return DB_SUCCESS if request was successful */
1480
1481 UNIV_INLINE
1482 dberr_t
1483 pfs_os_file_read_no_error_handling_int_fd_func(
1484 IORequest& type,
1485 int file,
1486 void* buf,
1487 os_offset_t offset,
1488 ulint n,
1489 ulint* o,
1490 const char* src_file,
1491 ulint src_line);
1492
1493 /** NOTE! Please use the corresponding macro os_aio(), not directly this
1494 function!
1495 Performance schema wrapper function of os_aio() which requests
1496 an asynchronous I/O operation.
1497 @param[in] type IO request context
1498 @param[in] mode IO mode
1499 @param[in] name Name of the file or path as NUL terminated
1500 string
1501 @param[in] file Open file handle
1502 @param[out] buf buffer where to read
1503 @param[in] offset file offset where to read
1504 @param[in] n number of bytes to read
1505 @param[in] read_only if true read only mode checks are enforced
1506 @param[in,out] m1 Message for the AIO handler, (can be used to
1507 identify a completed AIO operation); ignored
1508 if mode is OS_AIO_SYNC
1509 @param[in,out] m2 message for the AIO handler (can be used to
1510 identify a completed AIO operation); ignored
1511 if mode is OS_AIO_SYNC
1512 @param[in] src_file file name where func invoked
1513 @param[in] src_line line where the func invoked
1514 @return DB_SUCCESS if request was queued successfully, FALSE if fail */
1515 UNIV_INLINE
1516 dberr_t
1517 pfs_os_aio_func(
1518 IORequest& type,
1519 ulint mode,
1520 const char* name,
1521 pfs_os_file_t file,
1522 void* buf,
1523 os_offset_t offset,
1524 ulint n,
1525 bool read_only,
1526 fil_node_t* m1,
1527 void* m2,
1528 const char* src_file,
1529 ulint src_line);
1530
1531 /** NOTE! Please use the corresponding macro os_file_write(), not directly
1532 this function!
1533 This is the performance schema instrumented wrapper function for
1534 os_file_write() which requests a synchronous write operation.
1535 @param[in, out] type IO request context
1536 @param[in] name Name of the file or path as NUL terminated
1537 string
1538 @param[in] file Open file handle
1539 @param[out] buf buffer where to read
1540 @param[in] offset file offset where to read
1541 @param[in] n number of bytes to read
1542 @param[in] src_file file name where func invoked
1543 @param[in] src_line line where the func invoked
1544 @return DB_SUCCESS if request was successful */
1545 UNIV_INLINE
1546 dberr_t
1547 pfs_os_file_write_func(
1548 IORequest& type,
1549 const char* name,
1550 pfs_os_file_t file,
1551 const void* buf,
1552 os_offset_t offset,
1553 ulint n,
1554 const char* src_file,
1555 ulint src_line);
1556
1557 /** NOTE! Please use the corresponding macro os_file_write(), not
1558 directly this function!
1559 This is the performance schema instrumented wrapper function for
1560 os_file_write() which requests a synchronous write operation
1561 on files with int type descriptors.
1562 @param[in, out] type IO request context
1563 @param[in] name Name of the file or path as NUL terminated
1564 string
1565 @param[in] file Open file handle
1566 @param[out] buf buffer where to read
1567 @param[in] offset file offset where to read
1568 @param[in] n number of bytes to read
1569 @param[in] src_file file name where func invoked
1570 @param[in] src_line line where the func invoked
1571 @return DB_SUCCESS if request was successful */
1572 UNIV_INLINE
1573 dberr_t
1574 pfs_os_file_write_int_fd_func(
1575 IORequest& type,
1576 const char* name,
1577 int file,
1578 const void* buf,
1579 os_offset_t offset,
1580 ulint n,
1581 const char* src_file,
1582 ulint src_line);
1583
1584 /** NOTE! Please use the corresponding macro os_file_flush(), not directly
1585 this function!
1586 This is the performance schema instrumented wrapper function for
1587 os_file_flush() which flushes the write buffers of a given file to the disk.
1588 Flushes the write buffers of a given file to the disk.
1589 @param[in] file Open file handle
1590 @param[in] src_file file name where func invoked
1591 @param[in] src_line line where the func invoked
1592 @return TRUE if success */
1593 UNIV_INLINE
1594 bool
1595 pfs_os_file_flush_func(
1596 pfs_os_file_t file,
1597 const char* src_file,
1598 ulint src_line);
1599
1600 /** NOTE! Please use the corresponding macro os_file_rename(), not directly
1601 this function!
1602 This is the performance schema instrumented wrapper function for
1603 os_file_rename()
1604 @param[in] key Performance Schema Key
1605 @param[in] oldpath old file path as a null-terminated string
1606 @param[in] newpath new file path
1607 @param[in] src_file file name where func invoked
1608 @param[in] src_line line where the func invoked
1609 @return true if success */
1610 UNIV_INLINE
1611 bool
1612 pfs_os_file_rename_func(
1613 mysql_pfs_key_t key,
1614 const char* oldpath,
1615 const char* newpath,
1616 const char* src_file,
1617 ulint src_line);
1618
1619 /**
1620 NOTE! Please use the corresponding macro os_file_delete(), not directly
1621 this function!
1622 This is the performance schema instrumented wrapper function for
1623 os_file_delete()
1624 @param[in] key Performance Schema Key
1625 @param[in] name old file path as a null-terminated string
1626 @param[in] src_file file name where func invoked
1627 @param[in] src_line line where the func invoked
1628 @return true if success */
1629 UNIV_INLINE
1630 bool
1631 pfs_os_file_delete_func(
1632 mysql_pfs_key_t key,
1633 const char* name,
1634 const char* src_file,
1635 ulint src_line);
1636
1637 /**
1638 NOTE! Please use the corresponding macro os_file_delete_if_exists(), not
1639 directly this function!
1640 This is the performance schema instrumented wrapper function for
1641 os_file_delete_if_exists()
1642 @param[in] key Performance Schema Key
1643 @param[in] name old file path as a null-terminated string
1644 @param[in] exist indicate if file pre-exist
1645 @param[in] src_file file name where func invoked
1646 @param[in] src_line line where the func invoked
1647 @return true if success */
1648 UNIV_INLINE
1649 bool
1650 pfs_os_file_delete_if_exists_func(
1651 mysql_pfs_key_t key,
1652 const char* name,
1653 bool* exist,
1654 const char* src_file,
1655 ulint src_line);
1656
1657 #else /* UNIV_PFS_IO */
1658
1659 /* If UNIV_PFS_IO is not defined, these I/O APIs point
1660 to original un-instrumented file I/O APIs */
1661 # define os_file_create(key, name, create, purpose, type, read_only, \
1662 success) \
1663 os_file_create_func(name, create, purpose, type, read_only, \
1664 success)
1665
1666 # define os_file_create_simple(key, name, create_mode, access, \
1667 read_only, success) \
1668 os_file_create_simple_func(name, create_mode, access, \
1669 read_only, success)
1670
1671 # define os_file_create_simple_no_error_handling( \
1672 key, name, create_mode, access, read_only, success) \
1673 os_file_create_simple_no_error_handling_func( \
1674 name, create_mode, access, read_only, success)
1675
1676 # define os_file_close_pfs(file) os_file_close_func(file)
1677
1678 # define os_aio(type, mode, name, file, buf, offset, \
1679 n, read_only, message1, message2) \
1680 os_aio_func(type, mode, name, file, buf, offset, \
1681 n, read_only, message1, message2)
1682
1683 # define os_file_read_pfs(type, file, buf, offset, n) \
1684 os_file_read_func(type, file, buf, offset, n)
1685
1686 # define os_file_read_no_error_handling_pfs(type, file, buf, offset, n, o) \
1687 os_file_read_no_error_handling_func(type, file, buf, offset, n, o)
1688
1689 # define os_file_read_no_error_handling_int_fd(type, file, buf, offset, n, o) \
1690 os_file_read_no_error_handling_func(type, file, buf, offset, n, o)
1691
1692 # define os_file_write_pfs(type, name, file, buf, offset, n) \
1693 os_file_write_func(type, name, file, buf, offset, n)
1694
1695 # define os_file_write_int_fd(type, name, file, buf, offset, n) \
1696 os_file_write_func(type, name, file, buf, offset, n)
1697
1698 # define os_file_flush_pfs(file) os_file_flush_func(file)
1699
1700 # define os_file_rename(key, oldpath, newpath) \
1701 os_file_rename_func(oldpath, newpath)
1702
1703 # define os_file_delete(key, name) os_file_delete_func(name)
1704
1705 # define os_file_delete_if_exists(key, name, exist) \
1706 os_file_delete_if_exists_func(name, exist)
1707
1708 #endif /* UNIV_PFS_IO */
1709
1710 #ifdef UNIV_PFS_IO
1711 #define os_file_close(file) os_file_close_pfs(file)
1712 #else
1713 #define os_file_close(file) os_file_close_pfs((file).m_file)
1714 #endif
1715
1716 #ifdef UNIV_PFS_IO
1717 #define os_file_read(type, file, buf, offset, n) \
1718 os_file_read_pfs(type, file, buf, offset, n)
1719 #else
1720 #define os_file_read(type, file, buf, offset, n) \
1721 os_file_read_pfs(type, (file).m_file, buf, offset, n)
1722 #endif
1723
1724 #ifdef UNIV_PFS_IO
1725 #define os_file_flush(file) os_file_flush_pfs(file)
1726 #else
1727 #define os_file_flush(file) os_file_flush_pfs((file).m_file)
1728 #endif
1729
1730 #ifdef UNIV_PFS_IO
1731 #define os_file_write(type, name, file, buf, offset, n) \
1732 os_file_write_pfs(type, name, file, buf, offset, n)
1733 #else
1734 #define os_file_write(type, name, file, buf, offset, n) \
1735 os_file_write_pfs(type, name, (file).m_file, buf, offset, n)
1736 #endif
1737
1738 #ifdef UNIV_PFS_IO
1739 #define os_file_read_no_error_handling(type, file, buf, offset, n, o) \
1740 os_file_read_no_error_handling_pfs(type, file, buf, offset, n, o)
1741 #else
1742 #define os_file_read_no_error_handling(type, file, buf, offset, n, o) \
1743 os_file_read_no_error_handling_pfs( \
1744 type, (file).m_file, buf, offset, n, o)
1745 #endif
1746
1747 #ifdef UNIV_HOTBACKUP
1748 /** Closes a file handle.
1749 @param[in] file handle to a file
1750 @return true if success */
1751 bool
1752 os_file_close_no_error_handling(os_file_t file);
1753 #endif /* UNIV_HOTBACKUP */
1754
1755 /** Gets a file size.
1756 @param[in] file handle to a file
1757 @return file size if OK, else set m_total_size to ~0 and m_alloc_size
1758 to errno */
1759 os_file_size_t
1760 os_file_get_size(
1761 const char* filename)
1762 MY_ATTRIBUTE((warn_unused_result));
1763
1764 /** Gets a file size.
1765 @param[in] file handle to a file
1766 @return file size, or (os_offset_t) -1 on failure */
1767 os_offset_t
1768 os_file_get_size(
1769 pfs_os_file_t file)
1770 MY_ATTRIBUTE((warn_unused_result));
1771
1772 /** Write the specified number of zeros to a newly created file.
1773 @param[in] name name of the file or path as a null-terminated
1774 string
1775 @param[in] file handle to a file
1776 @param[in] size file size
1777 @param[in] read_only Enable read-only checks if true
1778 @return true if success */
1779 bool
1780 os_file_set_size(
1781 const char* name,
1782 pfs_os_file_t file,
1783 os_offset_t size,
1784 bool read_only)
1785 MY_ATTRIBUTE((warn_unused_result));
1786
1787 /** Truncates a file at its current position.
1788 @param[in/out] file file to be truncated
1789 @return true if success */
1790 bool
1791 os_file_set_eof(
1792 FILE* file); /*!< in: file to be truncated */
1793
1794 /** Truncates a file to a specified size in bytes. Do nothing if the size
1795 preserved is smaller or equal than current size of file.
1796 @param[in] pathname file path
1797 @param[in] file file to be truncated
1798 @param[in] size size preserved in bytes
1799 @return true if success */
1800 bool
1801 os_file_truncate(
1802 const char* pathname,
1803 pfs_os_file_t file,
1804 os_offset_t size);
1805
1806 /** NOTE! Use the corresponding macro os_file_flush(), not directly this
1807 function!
1808 Flushes the write buffers of a given file to the disk.
1809 @param[in] file handle to a file
1810 @return true if success */
1811 bool
1812 os_file_flush_func(
1813 os_file_t file);
1814
1815 /** Retrieves the last error number if an error occurs in a file io function.
1816 The number should be retrieved before any other OS calls (because they may
1817 overwrite the error number). If the number is not known to this program,
1818 the OS error number + 100 is returned.
1819 @param[in] report true if we want an error message printed
1820 for all errors
1821 @return error number, or OS error number + 100 */
1822 ulint
1823 os_file_get_last_error(
1824 bool report);
1825
1826 /** NOTE! Use the corresponding macro os_file_read(), not directly this
1827 function!
1828 Requests a synchronous read operation.
1829 @param[in] type IO request context
1830 @param[in] file Open file handle
1831 @param[out] buf buffer where to read
1832 @param[in] offset file offset where to read
1833 @param[in] n number of bytes to read
1834 @return DB_SUCCESS if request was successful */
1835 dberr_t
1836 os_file_read_func(
1837 IORequest& type,
1838 os_file_t file,
1839 void* buf,
1840 os_offset_t offset,
1841 ulint n)
1842 MY_ATTRIBUTE((warn_unused_result));
1843
1844 /** Rewind file to its start, read at most size - 1 bytes from it to str, and
1845 NUL-terminate str. All errors are silently ignored. This function is
1846 mostly meant to be used with temporary files.
1847 @param[in,out] file file to read from
1848 @param[in,out] str buffer where to read
1849 @param[in] size size of buffer */
1850 void
1851 os_file_read_string(
1852 FILE* file,
1853 char* str,
1854 ulint size);
1855
1856 /** NOTE! Use the corresponding macro os_file_read_no_error_handling(),
1857 not directly this function!
1858 Requests a synchronous positioned read operation. This function does not do
1859 any error handling. In case of error it returns FALSE.
1860 @param[in] type IO request context
1861 @param[in] file Open file handle
1862 @param[out] buf buffer where to read
1863 @param[in] offset file offset where to read
1864 @param[in] n number of bytes to read
1865 @param[out] o number of bytes actually read
1866 @return DB_SUCCESS or error code */
1867 dberr_t
1868 os_file_read_no_error_handling_func(
1869 IORequest& type,
1870 os_file_t file,
1871 void* buf,
1872 os_offset_t offset,
1873 ulint n,
1874 ulint* o)
1875 MY_ATTRIBUTE((warn_unused_result));
1876
1877 /** NOTE! Use the corresponding macro os_file_write(), not directly this
1878 function!
1879 Requests a synchronous write operation.
1880 @param[in,out] type IO request context
1881 @param[in] file Open file handle
1882 @param[out] buf buffer where to read
1883 @param[in] offset file offset where to read
1884 @param[in] n number of bytes to read
1885 @return DB_SUCCESS if request was successful */
1886 dberr_t
1887 os_file_write_func(
1888 IORequest& type,
1889 const char* name,
1890 os_file_t file,
1891 const void* buf,
1892 os_offset_t offset,
1893 ulint n)
1894 MY_ATTRIBUTE((warn_unused_result));
1895
1896 /** Check the existence and type of the given file.
1897 @param[in] path pathname of the file
1898 @param[out] exists true if file exists
1899 @param[out] type type of the file (if it exists)
1900 @return true if call succeeded */
1901 bool
1902 os_file_status(
1903 const char* path,
1904 bool* exists,
1905 os_file_type_t* type);
1906
1907 /** This function returns a new path name after replacing the basename
1908 in an old path with a new basename. The old_path is a full path
1909 name including the extension. The tablename is in the normal
1910 form "databasename/tablename". The new base name is found after
1911 the forward slash. Both input strings are null terminated.
1912
1913 This function allocates memory to be returned. It is the callers
1914 responsibility to free the return value after it is no longer needed.
1915
1916 @param[in] old_path pathname
1917 @param[in] new_name new file name
1918 @return own: new full pathname */
1919 char*
1920 os_file_make_new_pathname(
1921 const char* old_path,
1922 const char* new_name);
1923
1924 /** This function reduces a null-terminated full remote path name into
1925 the path that is sent by MySQL for DATA DIRECTORY clause. It replaces
1926 the 'databasename/tablename.ibd' found at the end of the path with just
1927 'tablename'.
1928
1929 Since the result is always smaller than the path sent in, no new memory
1930 is allocated. The caller should allocate memory for the path sent in.
1931 This function manipulates that path in place.
1932
1933 If the path format is not as expected, just return. The result is used
1934 to inform a SHOW CREATE TABLE command.
1935 @param[in,out] data_dir_path Full path/data_dir_path */
1936 void
1937 os_file_make_data_dir_path(
1938 char* data_dir_path);
1939
1940 /** Create all missing subdirectories along the given path.
1941 @return DB_SUCCESS if OK, otherwise error code. */
1942 dberr_t
1943 os_file_create_subdirs_if_needed(
1944 const char* path);
1945
1946 #ifdef UNIV_ENABLE_UNIT_TEST_GET_PARENT_DIR
1947 /* Test the function os_file_get_parent_dir. */
1948 void
1949 unit_test_os_file_get_parent_dir();
1950 #endif /* UNIV_ENABLE_UNIT_TEST_GET_PARENT_DIR */
1951
1952 /** Initializes the asynchronous io system. Creates one array each for ibuf
1953 and log i/o. Also creates one array each for read and write where each
1954 array is divided logically into n_read_segs and n_write_segs
1955 respectively. The caller must create an i/o handler thread for each
1956 segment in these arrays. This function also creates the sync array.
1957 No i/o handler thread needs to be created for that
1958 @param[in] n_read_segs number of reader threads
1959 @param[in] n_write_segs number of writer threads
1960 @param[in] n_slots_sync number of slots in the sync aio array */
1961
1962 bool
1963 os_aio_init(
1964 ulint n_read_segs,
1965 ulint n_write_segs,
1966 ulint n_slots_sync);
1967
1968 /**
1969 Frees the asynchronous io system. */
1970 void
1971 os_aio_free();
1972
1973 /**
1974 NOTE! Use the corresponding macro os_aio(), not directly this function!
1975 Requests an asynchronous i/o operation.
1976 @param[in] type IO request context
1977 @param[in] mode IO mode
1978 @param[in] name Name of the file or path as NUL terminated
1979 string
1980 @param[in] file Open file handle
1981 @param[out] buf buffer where to read
1982 @param[in] offset file offset where to read
1983 @param[in] n number of bytes to read
1984 @param[in] read_only if true read only mode checks are enforced
1985 @param[in,out] m1 Message for the AIO handler, (can be used to
1986 identify a completed AIO operation); ignored
1987 if mode is OS_AIO_SYNC
1988 @param[in,out] m2 message for the AIO handler (can be used to
1989 identify a completed AIO operation); ignored
1990 if mode is OS_AIO_SYNC
1991 @return DB_SUCCESS or error code */
1992 dberr_t
1993 os_aio_func(
1994 IORequest& type,
1995 ulint mode,
1996 const char* name,
1997 pfs_os_file_t file,
1998 void* buf,
1999 os_offset_t offset,
2000 ulint n,
2001 bool read_only,
2002 fil_node_t* m1,
2003 void* m2);
2004
2005 /** Wakes up all async i/o threads so that they know to exit themselves in
2006 shutdown. */
2007 void
2008 os_aio_wake_all_threads_at_shutdown();
2009
2010 /** Waits until there are no pending writes in os_aio_write_array. There can
2011 be other, synchronous, pending writes. */
2012 void
2013 os_aio_wait_until_no_pending_writes();
2014
2015 /** Wakes up simulated aio i/o-handler threads if they have something to do. */
2016 void
2017 os_aio_simulated_wake_handler_threads();
2018
2019 /** This function can be called if one wants to post a batch of reads and
2020 prefers an i/o-handler thread to handle them all at once later. You must
2021 call os_aio_simulated_wake_handler_threads later to ensure the threads
2022 are not left sleeping! */
2023 void
2024 os_aio_simulated_put_read_threads_to_sleep();
2025
2026 /** This is the generic AIO handler interface function.
2027 Waits for an aio operation to complete. This function is used to wait the
2028 for completed requests. The AIO array of pending requests is divided
2029 into segments. The thread specifies which segment or slot it wants to wait
2030 for. NOTE: this function will also take care of freeing the aio slot,
2031 therefore no other thread is allowed to do the freeing!
2032 @param[in] segment the number of the segment in the aio arrays to
2033 wait for; segment 0 is the ibuf I/O thread,
2034 segment 1 the log I/O thread, then follow the
2035 non-ibuf read threads, and as the last are the
2036 non-ibuf write threads; if this is
2037 ULINT_UNDEFINED, then it means that sync AIO
2038 is used, and this parameter is ignored
2039 @param[out] m1 the messages passed with the AIO request;
2040 note that also in the case where the AIO
2041 operation failed, these output parameters
2042 are valid and can be used to restart the
2043 operation, for example
2044 @param[out] m2 callback message
2045 @param[out] type OS_FILE_WRITE or ..._READ
2046 @return DB_SUCCESS or error code */
2047 dberr_t
2048 os_aio_handler(
2049 ulint segment,
2050 fil_node_t** m1,
2051 void** m2,
2052 IORequest* type);
2053
2054 /** Prints info of the aio arrays.
2055 @param[in/out] file file where to print */
2056 void
2057 os_aio_print(FILE* file);
2058
2059 /** Refreshes the statistics used to print per-second averages. */
2060 void
2061 os_aio_refresh_stats();
2062
2063 /** Checks that all slots in the system have been freed, that is, there are
2064 no pending io operations. */
2065 bool
2066 os_aio_all_slots_free();
2067
2068 #ifdef UNIV_DEBUG
2069
2070 /** Prints all pending IO
2071 @param[in] file file where to print */
2072 void
2073 os_aio_print_pending_io(FILE* file);
2074
2075 #endif /* UNIV_DEBUG */
2076
2077 /** This function returns information about the specified file
2078 @param[in] path pathname of the file
2079 @param[in] stat_info information of a file in a directory
2080 @param[in] check_rw_perm for testing whether the file can be opened
2081 in RW mode
2082 @param[in] read_only if true read only mode checks are enforced
2083 @return DB_SUCCESS if all OK */
2084 dberr_t
2085 os_file_get_status(
2086 const char* path,
2087 os_file_stat_t* stat_info,
2088 bool check_rw_perm,
2089 bool read_only);
2090
2091 #if !defined(UNIV_HOTBACKUP)
2092 /** return one of the tmpdir path
2093 @return tmporary dir*/
2094 char *innobase_mysql_tmpdir(void);
2095
2096
2097 /** Creates a temporary file in the location specified by the parameter
2098 path. If the path is NULL then it will be created on --tmpdir location.
2099 This function is defined in ha_innodb.cc.
2100 @param[in] path location for creating temporary file
2101 @return temporary file descriptor, or < 0 on error */
2102 int
2103 innobase_mysql_tmpfile(
2104 const char* path);
2105 #endif /* !UNIV_HOTBACKUP */
2106
2107
2108 /** If it is a compressed page return the compressed page data + footer size
2109 @param[in] buf Buffer to check, must include header + 10 bytes
2110 @return ULINT_UNDEFINED if the page is not a compressed page or length
2111 of the compressed data (including footer) if it is a compressed page */
2112 ulint
2113 os_file_compressed_page_size(const byte* buf);
2114
2115 /** If it is a compressed page return the original page data + footer size
2116 @param[in] buf Buffer to check, must include header + 10 bytes
2117 @return ULINT_UNDEFINED if the page is not a compressed page or length
2118 of the original data + footer if it is a compressed page */
2119 ulint
2120 os_file_original_page_size(const byte* buf);
2121
2122 /** Set the file create umask
2123 @param[in] umask The umask to use for file creation. */
2124 void
2125 os_file_set_umask(ulint umask);
2126
2127 /** Free storage space associated with a section of the file.
2128 @param[in] fh Open file handle
2129 @param[in] off Starting offset (SEEK_SET)
2130 @param[in] len Size of the hole
2131 @return DB_SUCCESS or error code */
2132 dberr_t
2133 os_file_punch_hole(
2134 os_file_t fh,
2135 os_offset_t off,
2136 os_offset_t len)
2137 MY_ATTRIBUTE((warn_unused_result));
2138
2139 /** Check if the file system supports sparse files.
2140
2141 Warning: On POSIX systems we try and punch a hole from offset 0 to
2142 the system configured page size. This should only be called on an empty
2143 file.
2144
2145 Note: On Windows we use the name and on Unices we use the file handle.
2146
2147 @param[in] name File name
2148 @param[in] fh File handle for the file - if opened
2149 @return true if the file system supports sparse files */
2150 bool
2151 os_is_sparse_file_supported(
2152 const char* path,
2153 pfs_os_file_t fh)
2154 MY_ATTRIBUTE((warn_unused_result));
2155
2156 /** Decompress the page data contents. Page type must be FIL_PAGE_COMPRESSED, if
2157 not then the source contents are left unchanged and DB_SUCCESS is returned.
2158 @param[in] dblwr_recover true of double write recovery in progress
2159 @param[in,out] src Data read from disk, decompressed data will be
2160 copied to this page
2161 @param[in,out] dst Scratch area to use for decompression
2162 @param[in] dst_len Size of the scratch area in bytes
2163 @return DB_SUCCESS or error code */
2164
2165 dberr_t
2166 os_file_decompress_page(
2167 bool dblwr_recover,
2168 byte* src,
2169 byte* dst,
2170 ulint dst_len)
2171 MY_ATTRIBUTE((warn_unused_result));
2172
2173 /** Normalizes a directory path for the current OS:
2174 On Windows, we convert '/' to '\', else we convert '\' to '/'.
2175 @param[in,out] str A null-terminated directory and file path */
2176 void os_normalize_path(char* str);
2177
2178 /* Determine if a path is an absolute path or not.
2179 @param[in] OS directory or file path to evaluate
2180 @retval true if an absolute path
2181 @retval false if a relative path */
2182 UNIV_INLINE
2183 bool
is_absolute_path(const char * path)2184 is_absolute_path(
2185 const char* path)
2186 {
2187 if (path[0] == OS_PATH_SEPARATOR) {
2188 return(true);
2189 }
2190
2191 #ifdef _WIN32
2192 if (path[1] == ':' && path[2] == OS_PATH_SEPARATOR) {
2193 return(true);
2194 }
2195 #endif /* _WIN32 */
2196
2197 return(false);
2198 }
2199
2200 #ifndef UNIV_NONINL
2201 #include "os0file.ic"
2202 #endif /* UNIV_NONINL */
2203
2204 #endif /* os0file_h */
2205