1 /***********************************************************************
2 
3 Copyright (c) 1995, 2020, Oracle and/or its affiliates. All Rights Reserved.
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
30 along with this program; if not, write to the Free Software
31 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301  USA
32 
33 ***********************************************************************/
34 
35 /** @file include/os0file.h
36  The interface to the operating system file io
37 
38  Created 10/21/1995 Heikki Tuuri
39  *******************************************************/
40 
41 #ifndef os0file_h
42 #define os0file_h
43 
44 #include "my_dbug.h"
45 #include "my_io.h"
46 
47 #include "os/file.h"
48 #include "os0atomic.h"
49 #include "os0enc.h"
50 
51 #ifndef _WIN32
52 #include <dirent.h>
53 #include <sys/stat.h>
54 #include <sys/statvfs.h>
55 #include <time.h>
56 #else
57 #include <Strsafe.h>
58 #include <locale>
59 #include <string>
60 #endif /* !_WIN32 */
61 
62 #include <functional>
63 #include <stack>
64 
65 /** Prefix all files and directory created under data directory with special
66 string so that it never conflicts with MySQL schema directory. */
67 #define OS_FILE_PREFIX "#"
68 
69 /** File node of a tablespace or the log data space */
70 struct fil_node_t;
71 
72 extern bool os_has_said_disk_full;
73 
74 /** Number of pending read operations */
75 extern ulint os_n_pending_reads;
76 /** Number of pending write operations */
77 extern ulint os_n_pending_writes;
78 
79 /* Flush after each os_fsync_threshold bytes */
80 extern unsigned long long os_fsync_threshold;
81 
82 /** File offset in bytes */
83 typedef ib_uint64_t os_offset_t;
84 
85 namespace file {
86 /** Blocks for doing IO, used in the transparent compression
87 and encryption code. */
88 struct Block {
89   /** Default constructor */
BlockBlock90   Block() : m_ptr(), m_in_use() {}
91 
92   byte *m_ptr;
93 
94   byte pad[ut::INNODB_CACHE_LINE_SIZE - sizeof(ulint)];
95   lock_word_t m_in_use;
96 };
97 }  // namespace file
98 
99 #ifdef _WIN32
100 
101 typedef HANDLE os_file_dir_t; /*!< directory stream */
102 
103 /** We define always WIN_ASYNC_IO, and check at run-time whether
104 the OS actually supports it: Win 95 does not, NT does. */
105 #define WIN_ASYNC_IO
106 
107 /** Use unbuffered I/O */
108 #define UNIV_NON_BUFFERED_IO
109 
110 /** File handle */
111 #define os_file_t HANDLE
112 
113 /** Convert a C file descriptor to a native file handle
114 @param fd file descriptor
115 @return native file handle */
116 #define OS_FILE_FROM_FD(fd) (HANDLE) _get_osfhandle(fd)
117 
118 /** Associates a C file descriptor with an existing native file handle
119 @param[in]	file	native file handle
120 @return C file descriptor */
121 #define OS_FD_FROM_FILE(file) _open_osfhandle((intptr_t)file, _O_RDONLY)
122 
123 /** Closes the file associated with C file descriptor fd
124 @param[in]	fd	C file descriptor
125 @return 0 if success */
126 #define OS_FILE_CLOSE_FD(fd) _close(fd)
127 
128 #else /* _WIN32 */
129 
130 /** File handle */
131 typedef int os_file_t;
132 
133 /** Convert a C file descriptor to a native file handle
134 @param fd file descriptor
135 @return native file handle */
136 #define OS_FILE_FROM_FD(fd) fd
137 
138 /** C file descriptor from an existing native file handle
139 @param[in]	file	native file handle
140 @return C file descriptor */
141 #define OS_FD_FROM_FILE(file) file
142 
143 /** Closes the file associated with C file descriptor fd
144 @param[in]	fd	C file descriptor
145 @return 0 if success */
146 #define OS_FILE_CLOSE_FD(fd) (os_file_close(fd) ? 0 : -1)
147 
148 #endif /* _WIN32 */
149 
150 /** Umask for creating files */
151 extern ulint os_innodb_umask;
152 
153 /** Common file descriptor for file IO instrumentation with PFS
154 on windows and other platforms */
155 struct pfs_os_file_t {
156 #ifdef UNIV_PFS_IO
157   struct PSI_file *m_psi;
158 #else  /* UNIV_PFS_IO */
159   pfs_os_file_t &operator=(os_file_t file) {
160     m_file = file;
161     return (*this);
162   }
163 #endif /* UNIV_PFS_IO */
164 
165   os_file_t m_file;
166 };
167 
168 static const os_file_t OS_FILE_CLOSED = os_file_t(~0);
169 
170 /** The next value should be smaller or equal to the smallest sector size used
171 on any disk. A log block is required to be a portion of disk which is written
172 so that if the start and the end of a block get written to disk, then the
173 whole block gets written. This should be true even in most cases of a crash:
174 if this fails for a log block, then it is equivalent to a media failure in the
175 log. */
176 
177 #define OS_FILE_LOG_BLOCK_SIZE 512
178 
179 /** Options for os_file_create_func @{ */
180 enum os_file_create_t {
181   OS_FILE_OPEN = 51,   /*!< to open an existing file (if
182                        doesn't exist, error) */
183   OS_FILE_CREATE,      /*!< to create new file (if
184                        exists, error) */
185   OS_FILE_OPEN_RAW,    /*!< to open a raw device or disk
186                        partition */
187   OS_FILE_CREATE_PATH, /*!< to create the directories */
188   OS_FILE_OPEN_RETRY,  /*!< open with retry */
189 
190   /** Flags that can be combined with the above values. Please ensure
191   that the above values stay below 128. */
192 
193   OS_FILE_ON_ERROR_NO_EXIT = 128, /*!< do not exit on unknown errors */
194   OS_FILE_ON_ERROR_SILENT = 256   /*!< don't print diagnostic messages to
195                                   the log unless it is a fatal error,
196                                   this flag is only used if
197                                   ON_ERROR_NO_EXIT is set */
198 };
199 
200 static const ulint OS_FILE_READ_ONLY = 333;
201 static const ulint OS_FILE_READ_WRITE = 444;
202 
203 /** Used by MySQLBackup */
204 static const ulint OS_FILE_READ_ALLOW_DELETE = 555;
205 
206 /* Options for file_create */
207 static const ulint OS_FILE_AIO = 61;
208 static const ulint OS_FILE_NORMAL = 62;
209 /* @} */
210 
211 /** Types for file create @{ */
212 static const ulint OS_DATA_FILE = 100;
213 static const ulint OS_LOG_FILE = 101;
214 /* Don't use this for Data files, Log files. Use it for smaller files
215 or if number of bytes to write are not multiple of sector size.
216 With this flag, writes to file will be always buffered and ignores the value
217 of innodb_flush_method. */
218 static const ulint OS_BUFFERED_FILE = 102;
219 
220 static const ulint OS_CLONE_DATA_FILE = 103;
221 static const ulint OS_CLONE_LOG_FILE = 104;
222 
223 /** Doublewrite files. */
224 static const ulint OS_DBLWR_FILE = 105;
225 
226 /** Redo log archive file. */
227 static const ulint OS_REDO_LOG_ARCHIVE_FILE = 105;
228 /* @} */
229 
230 /** Error codes from os_file_get_last_error @{ */
231 static const ulint OS_FILE_NOT_FOUND = 71;
232 static const ulint OS_FILE_DISK_FULL = 72;
233 static const ulint OS_FILE_ALREADY_EXISTS = 73;
234 static const ulint OS_FILE_PATH_ERROR = 74;
235 
236 /** wait for OS aio resources to become available again */
237 static const ulint OS_FILE_AIO_RESOURCES_RESERVED = 75;
238 
239 static const ulint OS_FILE_SHARING_VIOLATION = 76;
240 static const ulint OS_FILE_ERROR_NOT_SPECIFIED = 77;
241 static const ulint OS_FILE_INSUFFICIENT_RESOURCE = 78;
242 static const ulint OS_FILE_AIO_INTERRUPTED = 79;
243 static const ulint OS_FILE_OPERATION_ABORTED = 80;
244 static const ulint OS_FILE_ACCESS_VIOLATION = 81;
245 static const ulint OS_FILE_NAME_TOO_LONG = 82;
246 static const ulint OS_FILE_ERROR_MAX = 100;
247 /* @} */
248 
249 /** Types for AIO operations @{ */
250 
251 /** No transformations during read/write, write as is. */
252 #define IORequestRead IORequest(IORequest::READ)
253 #define IORequestWrite IORequest(IORequest::WRITE)
254 #define IORequestLogRead IORequest(IORequest::LOG | IORequest::READ)
255 #define IORequestLogWrite IORequest(IORequest::LOG | IORequest::WRITE)
256 
257 /**
258 The IO Context that is passed down to the low level IO code */
259 class IORequest {
260  public:
261   /** Flags passed in the request, they can be ORred together. */
262   enum {
263     UNSET = 0,
264     READ = 1,
265     WRITE = 2,
266 
267     /** Request for a doublewrite page IO */
268     DBLWR = 4,
269 
270     /** Enumerations below can be ORed to READ/WRITE above*/
271 
272     /** Data file */
273     DATA_FILE = 8,
274 
275     /** Log file request*/
276     LOG = 16,
277 
278     /** Disable partial read warnings */
279     DISABLE_PARTIAL_IO_WARNINGS = 32,
280 
281     /** Do not to wake i/o-handler threads, but the caller will do
282     the waking explicitly later, in this way the caller can post
283     several requests in a batch; NOTE that the batch must not be
284     so big that it exhausts the slots in AIO arrays! NOTE that
285     a simulated batch may introduce hidden chances of deadlocks,
286     because I/Os are not actually handled until all
287     have been posted: use with great caution! */
288     DO_NOT_WAKE = 64,
289 
290     /** Ignore failed reads of non-existent pages */
291     IGNORE_MISSING = 128,
292 
293     /** Use punch hole if available, only makes sense if
294     compression algorithm != NONE. Ignored if not set */
295     PUNCH_HOLE = 256,
296 
297     /** Force raw read, do not try to compress/decompress.
298     This can be used to force a read and write without any
299     compression e.g., for redo log, merge sort temporary files
300     and the truncate redo log. */
301     NO_COMPRESSION = 512
302   };
303 
304   /** Default constructor */
IORequest()305   IORequest()
306       : m_block_size(UNIV_SECTOR_SIZE),
307         m_type(READ),
308         m_compression(),
309         m_encryption() {
310     /* No op */
311   }
312 
313   /**
314   @param[in]	type		Request type, can be a value that is
315                                   ORed from the above enum */
IORequest(ulint type)316   explicit IORequest(ulint type)
317       : m_block_size(UNIV_SECTOR_SIZE),
318         m_type(static_cast<uint16_t>(type)),
319         m_compression(),
320         m_encryption() {
321     if (is_log()) {
322       disable_compression();
323     }
324 
325     if (!is_punch_hole_supported()) {
326       clear_punch_hole();
327     }
328   }
329 
330   /** @return true if ignore missing flag is set */
ignore_missing(ulint type)331   static bool ignore_missing(ulint type) MY_ATTRIBUTE((warn_unused_result)) {
332     return ((type & IGNORE_MISSING) == IGNORE_MISSING);
333   }
334 
335   /** @return true if it is a read request */
is_read()336   bool is_read() const MY_ATTRIBUTE((warn_unused_result)) {
337     return ((m_type & READ) == READ);
338   }
339 
340   /** @return true if it is a write request */
is_write()341   bool is_write() const MY_ATTRIBUTE((warn_unused_result)) {
342     return ((m_type & WRITE) == WRITE);
343   }
344 
345   /** @return true if it is a redo log write */
is_log()346   bool is_log() const MY_ATTRIBUTE((warn_unused_result)) {
347     return ((m_type & LOG) == LOG);
348   }
349 
350   /** @return true if the simulated AIO thread should be woken up */
is_wake()351   bool is_wake() const MY_ATTRIBUTE((warn_unused_result)) {
352     return ((m_type & DO_NOT_WAKE) == 0);
353   }
354 
355   /** @return true if partial read warning disabled */
is_partial_io_warning_disabled()356   bool is_partial_io_warning_disabled() const
357       MY_ATTRIBUTE((warn_unused_result)) {
358     return ((m_type & DISABLE_PARTIAL_IO_WARNINGS) ==
359             DISABLE_PARTIAL_IO_WARNINGS);
360   }
361 
362   /** Disable partial read warnings */
disable_partial_io_warnings()363   void disable_partial_io_warnings() { m_type |= DISABLE_PARTIAL_IO_WARNINGS; }
364 
365   /** @return true if missing files should be ignored */
ignore_missing()366   bool ignore_missing() const MY_ATTRIBUTE((warn_unused_result)) {
367     return (ignore_missing(m_type));
368   }
369 
370   /** @return true if punch hole should be used */
punch_hole()371   bool punch_hole() const MY_ATTRIBUTE((warn_unused_result)) {
372     return ((m_type & PUNCH_HOLE) == PUNCH_HOLE);
373   }
374 
375   /** @return true if the read should be validated */
validate()376   bool validate() const MY_ATTRIBUTE((warn_unused_result)) {
377     ut_ad(is_read() ^ is_write());
378 
379     return (!is_read() || !punch_hole());
380   }
381 
382   /** Set the punch hole flag */
set_punch_hole()383   void set_punch_hole() {
384     if (is_punch_hole_supported()) {
385       m_type |= PUNCH_HOLE;
386     }
387   }
388 
389   /** Clear the do not wake flag */
clear_do_not_wake()390   void clear_do_not_wake() { m_type &= ~DO_NOT_WAKE; }
391 
392   /** Clear the punch hole flag */
clear_punch_hole()393   void clear_punch_hole() { m_type &= ~PUNCH_HOLE; }
394 
395   /** @return the block size to use for IO */
block_size()396   ulint block_size() const MY_ATTRIBUTE((warn_unused_result)) {
397     return (m_block_size);
398   }
399 
400   /** Set the block size for IO
401   @param[in] block_size		Block size to set */
block_size(ulint block_size)402   void block_size(ulint block_size) {
403     m_block_size = static_cast<uint32_t>(block_size);
404   }
405 
406   /** Clear all compression related flags */
clear_compressed()407   void clear_compressed() {
408     clear_punch_hole();
409 
410     m_compression.m_type = Compression::NONE;
411   }
412 
413   /** Compare two requests
414   @return true if the are equal */
415   bool operator==(const IORequest &rhs) const { return (m_type == rhs.m_type); }
416 
417   /** Set compression algorithm
418   @param[in]	type	The compression algorithm to use */
compression_algorithm(Compression::Type type)419   void compression_algorithm(Compression::Type type) {
420     if (type == Compression::NONE) {
421       return;
422     }
423 
424     set_punch_hole();
425 
426     m_compression.m_type = type;
427   }
428 
429   /** Get the compression algorithm.
430   @return the compression algorithm */
compression_algorithm()431   Compression compression_algorithm() const MY_ATTRIBUTE((warn_unused_result)) {
432     return (m_compression);
433   }
434 
435   /** @return true if the page should be compressed */
is_compressed()436   bool is_compressed() const MY_ATTRIBUTE((warn_unused_result)) {
437     return (compression_algorithm().m_type != Compression::NONE);
438   }
439 
440   /** @return true if the page read should not be transformed. */
is_compression_enabled()441   bool is_compression_enabled() const MY_ATTRIBUTE((warn_unused_result)) {
442     return ((m_type & NO_COMPRESSION) == 0);
443   }
444 
445   /** Disable transformations. */
disable_compression()446   void disable_compression() { m_type |= NO_COMPRESSION; }
447 
448   /** Set encryption algorithm
449   @param[in] type		The encryption algorithm to use */
encryption_algorithm(Encryption::Type type)450   void encryption_algorithm(Encryption::Type type) {
451     if (type == Encryption::NONE) {
452       return;
453     }
454 
455     m_encryption.set_type(type);
456   }
457 
458   /** Set encryption key and iv
459   @param[in] key		The encryption key to use
460   @param[in] key_len	length of the encryption key
461   @param[in] iv		The encryption iv to use */
encryption_key(byte * key,ulint key_len,byte * iv)462   void encryption_key(byte *key, ulint key_len, byte *iv) {
463     m_encryption.set_key(key);
464     m_encryption.set_key_length(key_len);
465     m_encryption.set_initial_vector(iv);
466   }
467 
468   /** Get the encryption algorithm.
469   @return the encryption algorithm */
encryption_algorithm()470   Encryption encryption_algorithm() const MY_ATTRIBUTE((warn_unused_result)) {
471     return (m_encryption);
472   }
473 
474   /** @return true if the page should be encrypted. */
is_encrypted()475   bool is_encrypted() const MY_ATTRIBUTE((warn_unused_result)) {
476     return (m_encryption.get_type() != Encryption::NONE);
477   }
478 
479   /** Clear all encryption related flags */
clear_encrypted()480   void clear_encrypted() {
481     m_encryption.set_key(nullptr);
482     m_encryption.set_key_length(0);
483     m_encryption.set_initial_vector(nullptr);
484     m_encryption.set_type(Encryption::NONE);
485   }
486 
487   /** Note that the IO is for double write buffer page write. */
dblwr()488   void dblwr() { m_type |= DBLWR; }
489 
490   /** @return true if the request is for a dblwr page. */
is_dblwr()491   bool is_dblwr() const MY_ATTRIBUTE((warn_unused_result)) {
492     return ((m_type & DBLWR) == DBLWR);
493   }
494 
495   /** @return true if punch hole is supported */
is_punch_hole_supported()496   static bool is_punch_hole_supported() {
497     /* In this debugging mode, we act as if punch hole is supported,
498     and then skip any calls to actually punch a hole here.
499     In this way, Transparent Page Compression is still being tested. */
500     DBUG_EXECUTE_IF("ignore_punch_hole", return (true););
501 
502 #if defined(HAVE_FALLOC_PUNCH_HOLE_AND_KEEP_SIZE) || defined(_WIN32)
503     return (true);
504 #else
505     return (false);
506 #endif /* HAVE_FALLOC_PUNCH_HOLE_AND_KEEP_SIZE || _WIN32 */
507   }
508 
509   /** @return string representation. */
to_string()510   std::string to_string() const {
511     std::ostringstream os;
512 
513     os << "bs: " << m_block_size << " flags:";
514 
515     if (m_type & READ) {
516       os << " READ";
517     } else if (m_type & WRITE) {
518       os << " WRITE";
519     } else if (m_type & DBLWR) {
520       os << " DBLWR";
521     }
522 
523     /** Enumerations below can be ORed to READ/WRITE above*/
524 
525     /** Data file */
526     if (m_type & DATA_FILE) {
527       os << " | DATA_FILE";
528     }
529 
530     if (m_type & LOG) {
531       os << " | LOG";
532     }
533 
534     if (m_type & DISABLE_PARTIAL_IO_WARNINGS) {
535       os << " | DISABLE_PARTIAL_IO_WARNINGS";
536     }
537 
538     if (m_type & DO_NOT_WAKE) {
539       os << " | IGNORE_MISSING";
540     }
541 
542     if (m_type & PUNCH_HOLE) {
543       os << " | PUNCH_HOLE";
544     }
545 
546     if (m_type & NO_COMPRESSION) {
547       os << " | NO_COMPRESSION";
548     }
549 
550     os << ", comp: " << m_compression.to_string();
551     os << ", enc: " << m_encryption.to_string(m_encryption.get_type());
552 
553     return (os.str());
554   }
555 
556  private:
557   /* File system best block size */
558   uint32_t m_block_size;
559 
560   /** Request type bit flags */
561   uint16_t m_type;
562 
563   /** Compression algorithm */
564   Compression m_compression;
565 
566   /** Encryption algorithm */
567   Encryption m_encryption;
568 };
569 
570 /* @} */
571 
572 /** Sparse file size information. */
573 struct os_file_size_t {
574   /** Total size of file in bytes */
575   os_offset_t m_total_size;
576 
577   /** If it is a sparse file then this is the number of bytes
578   actually allocated for the file. */
579   os_offset_t m_alloc_size;
580 };
581 
582 /** Win NT does not allow more than 64 */
583 static const ulint OS_AIO_N_PENDING_IOS_PER_THREAD = 32;
584 
585 /** Modes for aio operations @{ */
586 enum class AIO_mode : size_t {
587   /** Normal asynchronous i/o not for ibuf pages or ibuf bitmap pages */
588   NORMAL = 21,
589 
590   /**  Asynchronous i/o for ibuf pages or ibuf bitmap pages */
591   IBUF = 22,
592 
593   /** Asynchronous i/o for the log */
594   LOG = 23,
595 
596   /** Asynchronous i/o where the calling thread will itself wait for
597   the i/o to complete, doing also the job of the i/o-handler thread;
598   can be used for any pages, ibuf or non-ibuf.  This is used to save
599   CPU time, as we can do with fewer thread switches. Plain synchronous
600   I/O is not as good, because it must serialize the file seek and read
601   or write, causing a bottleneck for parallelism. */
602   SYNC = 24
603 };
604 /* @} */
605 
606 extern ulint os_n_file_reads;
607 extern ulint os_n_file_writes;
608 extern ulint os_n_fsyncs;
609 
610 /* File types for directory entry data type */
611 
612 enum os_file_type_t {
613   /** Get status failed. */
614   OS_FILE_TYPE_FAILED,
615 
616   /** stat() failed, with ENAMETOOLONG */
617   OS_FILE_TYPE_NAME_TOO_LONG,
618 
619   /** stat() failed with EACCESS */
620   OS_FILE_PERMISSION_ERROR,
621 
622   /** File doesn't exist. */
623   OS_FILE_TYPE_MISSING,
624 
625   /** File exists but type is unknown. */
626   OS_FILE_TYPE_UNKNOWN,
627 
628   /** Ordinary file. */
629   OS_FILE_TYPE_FILE,
630 
631   /** Directory. */
632   OS_FILE_TYPE_DIR,
633 
634   /** Symbolic link. */
635   OS_FILE_TYPE_LINK,
636 
637   /** Block device. */
638   OS_FILE_TYPE_BLOCK
639 };
640 
641 /* Maximum path string length in bytes when referring to tables with in the
642 './databasename/tablename.ibd' path format; we can allocate at least 2 buffers
643 of this size from the thread stack; that is why this should not be made much
644 bigger than 4000 bytes.  The maximum path length used by any storage engine
645 in the server must be at least this big. */
646 #define OS_FILE_MAX_PATH 4000
647 #if (FN_REFLEN_SE < OS_FILE_MAX_PATH)
648 #error "(FN_REFLEN_SE < OS_FILE_MAX_PATH)"
649 #endif
650 
651 /** Struct used in fetching information of a file in a directory */
652 struct os_file_stat_t {
653   char name[OS_FILE_MAX_PATH]; /*!< path to a file */
654   os_file_type_t type;         /*!< file type */
655   os_offset_t size;            /*!< file size in bytes */
656   os_offset_t alloc_size;      /*!< Allocated size for
657                                sparse files in bytes */
658   uint32_t block_size;         /*!< Block size to use for IO
659                                in bytes*/
660   time_t ctime;                /*!< creation time */
661   time_t mtime;                /*!< modification time */
662   time_t atime;                /*!< access time */
663   bool rw_perm;                /*!< true if can be opened
664                                in read-write mode. Only valid
665                                if type == OS_FILE_TYPE_FILE */
666 };
667 
668 #ifndef UNIV_HOTBACKUP
669 /** Create a temporary file. This function is like tmpfile(3), but
670 the temporary file is created in the given parameter path. If the path
671 is null then it will create the file in the mysql server configuration
672 parameter (--tmpdir).
673 @param[in]	path	location for creating temporary file
674 @return temporary file handle, or NULL on error */
675 FILE *os_file_create_tmpfile(const char *path);
676 #endif /* !UNIV_HOTBACKUP */
677 
678 /**
679 This function attempts to create a directory named pathname. The new directory
680 gets default permissions. On Unix, the permissions are (0770 & ~umask). If the
681 directory exists already, nothing is done and the call succeeds, unless the
682 fail_if_exists arguments is true.
683 
684 @param[in]	pathname	directory name as null-terminated string
685 @param[in]	fail_if_exists	if true, pre-existing directory is treated
686                                 as an error.
687 @return true if call succeeds, false on error */
688 bool os_file_create_directory(const char *pathname, bool fail_if_exists);
689 
690 /** Callback function type to be implemented by caller. It is called for each
691 entry in directory.
692 @param[in]	path	path to the file
693 @param[in]	name	name of the file */
694 typedef std::function<void(const char *path, const char *name)> os_dir_cbk_t;
695 
696 /** This function scans the contents of a directory and invokes the callback
697 for each entry.
698 @param[in]	path		directory name as null-terminated string
699 @param[in]	scan_cbk	use callback to be called for each entry
700 @param[in]	is_drop		attempt to drop the directory after scan
701 @return true if call succeeds, false on error */
702 bool os_file_scan_directory(const char *path, os_dir_cbk_t scan_cbk,
703                             bool is_drop);
704 
705 /** NOTE! Use the corresponding macro os_file_create_simple(), not directly
706 this function!
707 A simple function to open or create a file.
708 @param[in]	name		name of the file or path as a null-terminated
709                                 string
710 @param[in]	create_mode	create mode
711 @param[in]	access_type	OS_FILE_READ_ONLY or OS_FILE_READ_WRITE
712 @param[in]	read_only	if true read only mode checks are enforced
713 @param[out]	success		true if succeed, false if error
714 @return own: handle to the file, not defined if error, error number
715         can be retrieved with os_file_get_last_error */
716 os_file_t os_file_create_simple_func(const char *name, ulint create_mode,
717                                      ulint access_type, bool read_only,
718                                      bool *success);
719 
720 /** NOTE! Use the corresponding macro
721 os_file_create_simple_no_error_handling(), not directly this function!
722 A simple function to open or create a file.
723 @param[in]	name		name of the file or path as a
724 null-terminated string
725 @param[in]	create_mode	create mode
726 @param[in]	access_type	OS_FILE_READ_ONLY, OS_FILE_READ_WRITE, or
727                                 OS_FILE_READ_ALLOW_DELETE; the last option
728                                 is used by a backup program reading the file
729 @param[in]	read_only	if true read only mode checks are enforced
730 @param[out]	success		true if succeeded
731 @return own: handle to the file, not defined if error, error number
732         can be retrieved with os_file_get_last_error */
733 pfs_os_file_t os_file_create_simple_no_error_handling_func(
734     const char *name, ulint create_mode, ulint access_type, bool read_only,
735     bool *success) MY_ATTRIBUTE((warn_unused_result));
736 
737 /** Tries to disable OS caching on an opened file descriptor.
738 @param[in]	fd		file descriptor to alter
739 @param[in]	file_name	file name, used in the diagnostic message
740 @param[in]	operation_name	"open" or "create"; used in the diagnostic
741                                 message */
742 void os_file_set_nocache(int fd, const char *file_name,
743                          const char *operation_name);
744 
745 /** NOTE! Use the corresponding macro os_file_create(), not directly
746 this function!
747 Opens an existing file or creates a new.
748 @param[in]	name		name of the file or path as a null-terminated
749                                 string
750 @param[in]	create_mode	create mode
751 @param[in]	purpose		OS_FILE_AIO, if asynchronous, non-buffered I/O
752                                 is desired, OS_FILE_NORMAL, if any normal file;
753                                 NOTE that it also depends on type, os_aio_..
754                                 and srv_.. variables whether we really use
755                                 async I/O or unbuffered I/O: look in the
756                                 function source code for the exact rules
757 @param[in]	type		OS_DATA_FILE, OS_LOG_FILE etc.
758 @param[in]	read_only	if true read only mode checks are enforced
759 @param[in]	success		true if succeeded
760 @return own: handle to the file, not defined if error, error number
761         can be retrieved with os_file_get_last_error */
762 pfs_os_file_t os_file_create_func(const char *name, ulint create_mode,
763                                   ulint purpose, ulint type, bool read_only,
764                                   bool *success)
765     MY_ATTRIBUTE((warn_unused_result));
766 
767 /** Deletes a file. The file has to be closed before calling this.
768 @param[in]	name		file path as a null-terminated string
769 @return true if success */
770 bool os_file_delete_func(const char *name);
771 
772 /** Deletes a file if it exists. The file has to be closed before calling this.
773 @param[in]	name		file path as a null-terminated string
774 @param[out]	exist		indicate if file pre-exist
775 @return true if success */
776 bool os_file_delete_if_exists_func(const char *name, bool *exist);
777 
778 /** NOTE! Use the corresponding macro os_file_rename(), not directly
779 this function!
780 Renames a file (can also move it to another directory). It is safest that the
781 file is closed before calling this function.
782 @param[in]	oldpath		old file path as a null-terminated string
783 @param[in]	newpath		new file path
784 @return true if success */
785 bool os_file_rename_func(const char *oldpath, const char *newpath);
786 
787 /** NOTE! Use the corresponding macro os_file_close(), not directly this
788 function!
789 Closes a file handle. In case of error, error number can be retrieved with
790 os_file_get_last_error.
791 @param[in]	file		own: handle to a file
792 @return true if success */
793 bool os_file_close_func(os_file_t file);
794 
795 #ifdef UNIV_PFS_IO
796 
797 /* Keys to register InnoDB I/O with performance schema */
798 extern mysql_pfs_key_t innodb_log_file_key;
799 extern mysql_pfs_key_t innodb_temp_file_key;
800 extern mysql_pfs_key_t innodb_dblwr_file_key;
801 extern mysql_pfs_key_t innodb_arch_file_key;
802 extern mysql_pfs_key_t innodb_clone_file_key;
803 extern mysql_pfs_key_t innodb_data_file_key;
804 extern mysql_pfs_key_t innodb_tablespace_open_file_key;
805 
806 /* Following four macros are instumentations to register
807 various file I/O operations with performance schema.
808 1) register_pfs_file_open_begin() and register_pfs_file_open_end() are
809 used to register file creation, opening and closing.
810 2) register_pfs_file_rename_begin() and  register_pfs_file_rename_end()
811 are used to register file renaming.
812 3) register_pfs_file_io_begin() and register_pfs_file_io_end() are
813 used to register actual file read, write and flush
814 4) register_pfs_file_close_begin() and register_pfs_file_close_end()
815 are used to register file deletion operations*/
816 #define register_pfs_file_open_begin(state, locker, key, op, name, src_file, \
817                                      src_line)                               \
818   do {                                                                       \
819     locker = PSI_FILE_CALL(get_thread_file_name_locker)(state, key.m_value,  \
820                                                         op, name, &locker);  \
821     if (locker != nullptr) {                                                 \
822       PSI_FILE_CALL(start_file_open_wait)                                    \
823       (locker, src_file, static_cast<uint>(src_line));                       \
824     }                                                                        \
825   } while (0)
826 
827 #define register_pfs_file_open_end(locker, file, result)              \
828   do {                                                                \
829     if (locker != nullptr) {                                          \
830       file.m_psi = PSI_FILE_CALL(end_file_open_wait)(locker, result); \
831     }                                                                 \
832   } while (0)
833 
834 #define register_pfs_file_rename_begin(state, locker, key, op, from, to,    \
835                                        src_file, src_line)                  \
836   do {                                                                      \
837     locker = PSI_FILE_CALL(get_thread_file_name_locker)(state, key.m_value, \
838                                                         op, from, &locker); \
839     if (locker != nullptr) {                                                \
840       PSI_FILE_CALL(start_file_rename_wait)                                 \
841       (locker, (size_t)0, from, to, src_file, static_cast<uint>(src_line)); \
842     }                                                                       \
843   } while (0)
844 
845 #define register_pfs_file_rename_end(locker, from, to, result)       \
846   do {                                                               \
847     if (locker != nullptr) {                                         \
848       PSI_FILE_CALL(end_file_rename_wait)(locker, from, to, result); \
849     }                                                                \
850   } while (0)
851 
852 #define register_pfs_file_close_begin(state, locker, key, op, name, src_file, \
853                                       src_line)                               \
854   do {                                                                        \
855     locker = PSI_FILE_CALL(get_thread_file_name_locker)(state, key.m_value,   \
856                                                         op, name, &locker);   \
857     if (locker != nullptr) {                                                  \
858       PSI_FILE_CALL(start_file_close_wait)                                    \
859       (locker, src_file, static_cast<uint>(src_line));                        \
860     }                                                                         \
861   } while (0)
862 
863 #define register_pfs_file_close_end(locker, result)       \
864   do {                                                    \
865     if (locker != nullptr) {                              \
866       PSI_FILE_CALL(end_file_close_wait)(locker, result); \
867     }                                                     \
868   } while (0)
869 
870 #define register_pfs_file_io_begin(state, locker, file, count, op, src_file, \
871                                    src_line)                                 \
872   do {                                                                       \
873     locker =                                                                 \
874         PSI_FILE_CALL(get_thread_file_stream_locker)(state, file.m_psi, op); \
875     if (locker != nullptr) {                                                 \
876       PSI_FILE_CALL(start_file_wait)                                         \
877       (locker, count, src_file, static_cast<uint>(src_line));                \
878     }                                                                        \
879   } while (0)
880 
881 #define register_pfs_file_io_end(locker, count)    \
882   do {                                             \
883     if (locker != nullptr) {                       \
884       PSI_FILE_CALL(end_file_wait)(locker, count); \
885     }                                              \
886   } while (0)
887 
888 /* Following macros/functions are file I/O APIs that would be performance
889 schema instrumented if "UNIV_PFS_IO" is defined. They would point to
890 wrapper functions with performance schema instrumentation in such case.
891 
892 os_file_create
893 os_file_create_simple
894 os_file_create_simple_no_error_handling
895 os_file_close
896 os_file_rename
897 os_aio
898 os_file_read
899 os_file_read_no_error_handling
900 os_file_read_no_error_handling_int_fd
901 os_file_write
902 
903 The wrapper functions have the prefix of "innodb_". */
904 
905 #define os_file_create(key, name, create, purpose, type, read_only, success) \
906   pfs_os_file_create_func(key, name, create, purpose, type, read_only,       \
907                           success, __FILE__, __LINE__)
908 
909 #define os_file_create_simple(key, name, create, access, read_only, success) \
910   pfs_os_file_create_simple_func(key, name, create, access, read_only,       \
911                                  success, __FILE__, __LINE__)
912 
913 #define os_file_create_simple_no_error_handling(key, name, create_mode,     \
914                                                 access, read_only, success) \
915   pfs_os_file_create_simple_no_error_handling_func(                         \
916       key, name, create_mode, access, read_only, success, __FILE__, __LINE__)
917 
918 #define os_file_close_pfs(file) pfs_os_file_close_func(file, __FILE__, __LINE__)
919 
920 #define os_aio(type, mode, name, file, buf, offset, n, read_only, message1,    \
921                message2)                                                       \
922   pfs_os_aio_func(type, mode, name, file, buf, offset, n, read_only, message1, \
923                   message2, __FILE__, __LINE__)
924 
925 #define os_file_read_pfs(type, file_name, file, buf, offset, n)          \
926   pfs_os_file_read_func(type, file_name, file, buf, offset, n, __FILE__, \
927                         __LINE__)
928 
929 #define os_file_read_first_page_pfs(type, file_name, file, buf, n)          \
930   pfs_os_file_read_first_page_func(type, file_name, file, buf, n, __FILE__, \
931                                    __LINE__)
932 
933 #define os_file_copy_pfs(src, src_offset, dest, dest_offset, size)          \
934   pfs_os_file_copy_func(src, src_offset, dest, dest_offset, size, __FILE__, \
935                         __LINE__)
936 
937 #define os_file_read_no_error_handling_pfs(type, file_name, file, buf, offset, \
938                                            n, o)                               \
939   pfs_os_file_read_no_error_handling_func(type, file_name, file, buf, offset,  \
940                                           n, o, __FILE__, __LINE__)
941 
942 #define os_file_read_no_error_handling_int_fd(type, file_name, file, buf, \
943                                               offset, n, o)               \
944   pfs_os_file_read_no_error_handling_int_fd_func(                         \
945       type, file_name, file, buf, offset, n, o, __FILE__, __LINE__)
946 
947 #define os_file_write_pfs(type, name, file, buf, offset, n) \
948   pfs_os_file_write_func(type, name, file, buf, offset, n, __FILE__, __LINE__)
949 
950 #define os_file_write_int_fd(type, name, file, buf, offset, n)              \
951   pfs_os_file_write_int_fd_func(type, name, file, buf, offset, n, __FILE__, \
952                                 __LINE__)
953 
954 #define os_file_flush_pfs(file) pfs_os_file_flush_func(file, __FILE__, __LINE__)
955 
956 #define os_file_rename(key, oldpath, newpath) \
957   pfs_os_file_rename_func(key, oldpath, newpath, __FILE__, __LINE__)
958 
959 #define os_file_delete(key, name) \
960   pfs_os_file_delete_func(key, name, __FILE__, __LINE__)
961 
962 #define os_file_delete_if_exists(key, name, exist) \
963   pfs_os_file_delete_if_exists_func(key, name, exist, __FILE__, __LINE__)
964 
965 /** NOTE! Please use the corresponding macro os_file_create_simple(),
966 not directly this function!
967 A performance schema instrumented wrapper function for
968 os_file_create_simple() which opens or creates a file.
969 @param[in]	key		Performance Schema Key
970 @param[in]	name		name of the file or path as a null-terminated
971                                 string
972 @param[in]	create_mode	create mode
973 @param[in]	access_type	OS_FILE_READ_ONLY or OS_FILE_READ_WRITE
974 @param[in]	read_only	if true read only mode checks are enforced
975 @param[out]	success		true if succeeded
976 @param[in]	src_file	file name where func invoked
977 @param[in]	src_line	line where the func invoked
978 @return own: handle to the file, not defined if error, error number
979         can be retrieved with os_file_get_last_error */
980 UNIV_INLINE
981 pfs_os_file_t pfs_os_file_create_simple_func(
982     mysql_pfs_key_t key, const char *name, ulint create_mode, ulint access_type,
983     bool read_only, bool *success, const char *src_file, uint src_line)
984     MY_ATTRIBUTE((warn_unused_result));
985 
986 /** NOTE! Please use the corresponding macro
987 os_file_create_simple_no_error_handling(), not directly this function!
988 A performance schema instrumented wrapper function for
989 os_file_create_simple_no_error_handling(). Add instrumentation to
990 monitor file creation/open.
991 @param[in]	key		Performance Schema Key
992 @param[in]	name		name of the file or path as a null-terminated
993                                 string
994 @param[in]	create_mode	create mode
995 @param[in]	access_type	OS_FILE_READ_ONLY, OS_FILE_READ_WRITE, or
996                                 OS_FILE_READ_ALLOW_DELETE; the last option is
997                                 used by a backup program reading the file
998 @param[in]	read_only	if true read only mode checks are enforced
999 @param[out]	success		true if succeeded
1000 @param[in]	src_file	file name where func invoked
1001 @param[in]	src_line	line where the func invoked
1002 @return own: handle to the file, not defined if error, error number
1003         can be retrieved with os_file_get_last_error */
1004 UNIV_INLINE
1005 pfs_os_file_t pfs_os_file_create_simple_no_error_handling_func(
1006     mysql_pfs_key_t key, const char *name, ulint create_mode, ulint access_type,
1007     bool read_only, bool *success, const char *src_file, uint src_line)
1008     MY_ATTRIBUTE((warn_unused_result));
1009 
1010 /** NOTE! Please use the corresponding macro os_file_create(), not directly
1011 this function!
1012 A performance schema wrapper function for os_file_create().
1013 Add instrumentation to monitor file creation/open.
1014 @param[in]	key		Performance Schema Key
1015 @param[in]	name		name of the file or path as a null-terminated
1016                                 string
1017 @param[in]	create_mode	create mode
1018 @param[in]	purpose		OS_FILE_AIO, if asynchronous, non-buffered I/O
1019                                 is desired, OS_FILE_NORMAL, if any normal file;
1020                                 NOTE that it also depends on type, os_aio_..
1021                                 and srv_.. variables whether we really use
1022                                 async I/O or unbuffered I/O: look in the
1023                                 function source code for the exact rules
1024 @param[in]	type		OS_DATA_FILE or OS_LOG_FILE
1025 @param[in]	read_only	if true read only mode checks are enforced
1026 @param[out]	success		true if succeeded
1027 @param[in]	src_file	file name where func invoked
1028 @param[in]	src_line	line where the func invoked
1029 @return own: handle to the file, not defined if error, error number
1030         can be retrieved with os_file_get_last_error */
1031 UNIV_INLINE
1032 pfs_os_file_t pfs_os_file_create_func(mysql_pfs_key_t key, const char *name,
1033                                       ulint create_mode, ulint purpose,
1034                                       ulint type, bool read_only, bool *success,
1035                                       const char *src_file, uint src_line)
1036     MY_ATTRIBUTE((warn_unused_result));
1037 
1038 /** NOTE! Please use the corresponding macro os_file_close(), not directly
1039 this function!
1040 A performance schema instrumented wrapper function for os_file_close().
1041 @param[in]	file		handle to a file
1042 @param[in]	src_file	file name where func invoked
1043 @param[in]	src_line	line where the func invoked
1044 @return true if success */
1045 UNIV_INLINE
1046 bool pfs_os_file_close_func(pfs_os_file_t file, const char *src_file,
1047                             uint src_line);
1048 
1049 /** NOTE! Please use the corresponding macro os_file_read(), not directly
1050 this function!
1051 This is the performance schema instrumented wrapper function for
1052 os_file_read() which requests a synchronous read operation.
1053 @param[in, out]	type		IO request context
1054 @param[in]  file_name file name
1055 @param[in]	file		Open file handle
1056 @param[out]	buf		buffer where to read
1057 @param[in]	offset		file offset where to read
1058 @param[in]	n		number of bytes to read
1059 @param[in]	src_file	file name where func invoked
1060 @param[in]	src_line	line where the func invoked
1061 @return DB_SUCCESS if request was successful */
1062 UNIV_INLINE
1063 dberr_t pfs_os_file_read_func(IORequest &type, const char *file_name,
1064                               pfs_os_file_t file, void *buf, os_offset_t offset,
1065                               ulint n, const char *src_file, uint src_line);
1066 
1067 /** NOTE! Please use the corresponding macro os_file_read_first_page(),
1068 not directly this function!
1069 This is the performance schema instrumented wrapper function for
1070 os_file_read_first_page() which requests a synchronous read operation
1071 of page 0 of IBD file
1072 @param[in, out]	type		IO request context
1073 @param[in]  file_name file name
1074 @param[in]	file		Open file handle
1075 @param[out]	buf		buffer where to read
1076 @param[in]	n		number of bytes to read
1077 @param[in]	src_file	file name where func invoked
1078 @param[in]	src_line	line where the func invoked
1079 @return DB_SUCCESS if request was successful */
1080 UNIV_INLINE
1081 dberr_t pfs_os_file_read_first_page_func(IORequest &type, const char *file_name,
1082                                          pfs_os_file_t file, void *buf, ulint n,
1083                                          const char *src_file, uint src_line);
1084 
1085 /** copy data from one file to another file. Data is read/written
1086 at current file offset.
1087 @param[in]	src		file handle to copy from
1088 @param[in]	src_offset	offset to copy from
1089 @param[in]	dest		file handle to copy to
1090 @param[in]	dest_offset	offset to copy to
1091 @param[in]	size		number of bytes to copy
1092 @param[in]	src_file	file name where func invoked
1093 @param[in]	src_line	line where the func invoked
1094 @return DB_SUCCESS if successful */
1095 UNIV_INLINE
1096 dberr_t pfs_os_file_copy_func(pfs_os_file_t src, os_offset_t src_offset,
1097                               pfs_os_file_t dest, os_offset_t dest_offset,
1098                               uint size, const char *src_file, uint src_line);
1099 
1100 /** NOTE! Please use the corresponding macro os_file_read_no_error_handling(),
1101 not directly this function!
1102 This is the performance schema instrumented wrapper function for
1103 os_file_read_no_error_handling_func() which requests a synchronous
1104 read operation.
1105 @param[in, out]	type		IO request context
1106 @param[in]  file_name file name
1107 @param[in]	file		Open file handle
1108 @param[out]	buf		buffer where to read
1109 @param[in]	offset		file offset where to read
1110 @param[in]	n		number of bytes to read
1111 @param[out]	o		number of bytes actually read
1112 @param[in]	src_file	file name where func invoked
1113 @param[in]	src_line	line where the func invoked
1114 @return DB_SUCCESS if request was successful */
1115 UNIV_INLINE
1116 dberr_t pfs_os_file_read_no_error_handling_func(
1117     IORequest &type, const char *file_name, pfs_os_file_t file, void *buf,
1118     os_offset_t offset, ulint n, ulint *o, const char *src_file, uint src_line);
1119 
1120 /** NOTE! Please use the corresponding macro
1121 os_file_read_no_error_handling_int_fd(), not directly this function!
1122 This is the performance schema instrumented wrapper function for
1123 os_file_read_no_error_handling_int_fd_func() which requests a
1124 synchronous read operation on files with int type descriptors.
1125 @param[in, out] type            IO request context
1126 @param[in]      file_name       file name
1127 @param[in]      file            Open file handle
1128 @param[out]     buf             buffer where to read
1129 @param[in]      offset          file offset where to read
1130 @param[in]      n               number of bytes to read
1131 @param[out]     o               number of bytes actually read
1132 @param[in]      src_file        file name where func invoked
1133 @param[in]      src_line        line where the func invoked
1134 @return DB_SUCCESS if request was successful */
1135 
1136 UNIV_INLINE
1137 dberr_t pfs_os_file_read_no_error_handling_int_fd_func(
1138     IORequest &type, const char *file_name, int file, void *buf,
1139     os_offset_t offset, ulint n, ulint *o, const char *src_file,
1140     ulint src_line);
1141 
1142 /** NOTE! Please use the corresponding macro os_aio(), not directly this
1143 function!
1144 Performance schema wrapper function of os_aio() which requests
1145 an asynchronous I/O operation.
1146 @param[in]	type		IO request context
1147 @param[in]	mode		IO mode
1148 @param[in]	name		Name of the file or path as NUL terminated
1149                                 string
1150 @param[in]	file		Open file handle
1151 @param[out]	buf		buffer where to read
1152 @param[in]	offset		file offset where to read
1153 @param[in]	n		number of bytes to read
1154 @param[in]	read_only	if true read only mode checks are enforced
1155 @param[in,out]	m1		Message for the AIO handler, (can be used to
1156                                 identify a completed AIO operation); ignored
1157                                 if mode is OS_AIO_SYNC
1158 @param[in,out]	m2		message for the AIO handler (can be used to
1159                                 identify a completed AIO operation); ignored
1160                                 if mode is OS_AIO_SYNC
1161 @param[in]	src_file	file name where func invoked
1162 @param[in]	src_line	line where the func invoked
1163 @return DB_SUCCESS if request was queued successfully, false if fail */
1164 UNIV_INLINE
1165 dberr_t pfs_os_aio_func(IORequest &type, AIO_mode mode, const char *name,
1166                         pfs_os_file_t file, void *buf, os_offset_t offset,
1167                         ulint n, bool read_only, fil_node_t *m1, void *m2,
1168                         const char *src_file, uint src_line);
1169 
1170 /** NOTE! Please use the corresponding macro os_file_write(), not directly
1171 this function!
1172 This is the performance schema instrumented wrapper function for
1173 os_file_write() which requests a synchronous write operation.
1174 @param[in, out]	type		IO request context
1175 @param[in]	name		Name of the file or path as NUL terminated
1176                                 string
1177 @param[in]	file		Open file handle
1178 @param[out]	buf		buffer where to read
1179 @param[in]	offset		file offset where to read
1180 @param[in]	n		number of bytes to read
1181 @param[in]	src_file	file name where func invoked
1182 @param[in]	src_line	line where the func invoked
1183 @return DB_SUCCESS if request was successful */
1184 UNIV_INLINE
1185 dberr_t pfs_os_file_write_func(IORequest &type, const char *name,
1186                                pfs_os_file_t file, const void *buf,
1187                                os_offset_t offset, ulint n,
1188                                const char *src_file, uint src_line);
1189 
1190 /** NOTE! Please use the corresponding macro os_file_write(), not
1191 directly this function!
1192 This is the performance schema instrumented wrapper function for
1193 os_file_write() which requests a synchronous write operation
1194 on files with int type descriptors.
1195 @param[in, out] type            IO request context
1196 @param[in]      name            Name of the file or path as NUL terminated
1197                                 string
1198 @param[in]      file            Open file handle
1199 @param[out]     buf             buffer where to read
1200 @param[in]      offset          file offset where to read
1201 @param[in]      n		number of bytes to read
1202 @param[in]      src_file        file name where func invoked
1203 @param[in]      src_line        line where the func invoked
1204 @return DB_SUCCESS if request was successful */
1205 UNIV_INLINE
1206 dberr_t pfs_os_file_write_int_fd_func(IORequest &type, const char *name,
1207                                       int file, const void *buf,
1208                                       os_offset_t offset, ulint n,
1209                                       const char *src_file, ulint src_line);
1210 
1211 /** NOTE! Please use the corresponding macro os_file_flush(), not directly
1212 this function!
1213 This is the performance schema instrumented wrapper function for
1214 os_file_flush() which flushes the write buffers of a given file to the disk.
1215 Flushes the write buffers of a given file to the disk.
1216 @param[in]	file		Open file handle
1217 @param[in]	src_file	file name where func invoked
1218 @param[in]	src_line	line where the func invoked
1219 @return true if success */
1220 UNIV_INLINE
1221 bool pfs_os_file_flush_func(pfs_os_file_t file, const char *src_file,
1222                             uint src_line);
1223 
1224 /** NOTE! Please use the corresponding macro os_file_rename(), not directly
1225 this function!
1226 This is the performance schema instrumented wrapper function for
1227 os_file_rename()
1228 @param[in]	key		Performance Schema Key
1229 @param[in]	oldpath		old file path as a null-terminated string
1230 @param[in]	newpath		new file path
1231 @param[in]	src_file	file name where func invoked
1232 @param[in]	src_line	line where the func invoked
1233 @return true if success */
1234 UNIV_INLINE
1235 bool pfs_os_file_rename_func(mysql_pfs_key_t key, const char *oldpath,
1236                              const char *newpath, const char *src_file,
1237                              uint src_line);
1238 
1239 /**
1240 NOTE! Please use the corresponding macro os_file_delete(), not directly
1241 this function!
1242 This is the performance schema instrumented wrapper function for
1243 os_file_delete()
1244 @param[in]	key		Performance Schema Key
1245 @param[in]	name		old file path as a null-terminated string
1246 @param[in]	src_file	file name where func invoked
1247 @param[in]	src_line	line where the func invoked
1248 @return true if success */
1249 UNIV_INLINE
1250 bool pfs_os_file_delete_func(mysql_pfs_key_t key, const char *name,
1251                              const char *src_file, uint src_line);
1252 
1253 /**
1254 NOTE! Please use the corresponding macro os_file_delete_if_exists(), not
1255 directly this function!
1256 This is the performance schema instrumented wrapper function for
1257 os_file_delete_if_exists()
1258 @param[in]	key		Performance Schema Key
1259 @param[in]	name		old file path as a null-terminated string
1260 @param[in]	exist		indicate if file pre-exist
1261 @param[in]	src_file	file name where func invoked
1262 @param[in]	src_line	line where the func invoked
1263 @return true if success */
1264 UNIV_INLINE
1265 bool pfs_os_file_delete_if_exists_func(mysql_pfs_key_t key, const char *name,
1266                                        bool *exist, const char *src_file,
1267                                        uint src_line);
1268 
1269 #else /* UNIV_PFS_IO */
1270 
1271 /* If UNIV_PFS_IO is not defined, these I/O APIs point
1272 to original un-instrumented file I/O APIs */
1273 #define os_file_create(key, name, create, purpose, type, read_only, success) \
1274   os_file_create_func(name, create, purpose, type, read_only, success)
1275 
1276 #define os_file_create_simple(key, name, create_mode, access, read_only, \
1277                               success)                                   \
1278   os_file_create_simple_func(name, create_mode, access, read_only, success)
1279 
1280 #define os_file_create_simple_no_error_handling(key, name, create_mode,     \
1281                                                 access, read_only, success) \
1282   os_file_create_simple_no_error_handling_func(name, create_mode, access,   \
1283                                                read_only, success)
1284 
1285 #define os_file_close_pfs(file) os_file_close_func(file)
1286 
1287 #define os_aio(type, mode, name, file, buf, offset, n, read_only, message1, \
1288                message2)                                                    \
1289   os_aio_func(type, mode, name, file, buf, offset, n, read_only, message1,  \
1290               message2)
1291 
1292 #define os_file_read_pfs(type, file_name, file, buf, offset, n) \
1293   os_file_read_func(type, file_name, file, buf, offset, n)
1294 
1295 #define os_file_read_first_page_pfs(type, file_name, file, buf, n) \
1296   os_file_read_first_page_func(type, file_name, file, buf, n)
1297 
1298 #define os_file_copy_pfs(src, src_offset, dest, dest_offset, size) \
1299   os_file_copy_func(src, src_offset, dest, dest_offset, size)
1300 
1301 #define os_file_read_no_error_handling_pfs(type, file_name, file, buf, offset, \
1302                                            n, o)                               \
1303   os_file_read_no_error_handling_func(type, file_name, file, buf, offset, n, o)
1304 
1305 #define os_file_read_no_error_handling_int_fd(type, file_name, file, buf, \
1306                                               offset, n, o)               \
1307   os_file_read_no_error_handling_func(type, file_name, file, buf, offset, n, o)
1308 
1309 #define os_file_write_pfs(type, name, file, buf, offset, n) \
1310   os_file_write_func(type, name, file, buf, offset, n)
1311 
1312 #define os_file_write_int_fd(type, name, file, buf, offset, n) \
1313   os_file_write_func(type, name, file, buf, offset, n)
1314 
1315 #define os_file_flush_pfs(file) os_file_flush_func(file)
1316 
1317 #define os_file_rename(key, oldpath, newpath) \
1318   os_file_rename_func(oldpath, newpath)
1319 
1320 #define os_file_delete(key, name) os_file_delete_func(name)
1321 
1322 #define os_file_delete_if_exists(key, name, exist) \
1323   os_file_delete_if_exists_func(name, exist)
1324 
1325 #endif /* UNIV_PFS_IO */
1326 
1327 #ifdef UNIV_PFS_IO
1328 #define os_file_close(file) os_file_close_pfs(file)
1329 #else
1330 #define os_file_close(file) os_file_close_pfs((file).m_file)
1331 #endif
1332 
1333 #ifdef UNIV_PFS_IO
1334 #define os_file_read(type, file_name, file, buf, offset, n) \
1335   os_file_read_pfs(type, file_name, file, buf, offset, n)
1336 #else
1337 #define os_file_read(type, file_name, file, buf, offset, n) \
1338   os_file_read_pfs(type, file_name, file.m_file, buf, offset, n)
1339 #endif
1340 
1341 #ifdef UNIV_PFS_IO
1342 #define os_file_read_first_page(type, file_name, file, buf, n) \
1343   os_file_read_first_page_pfs(type, file_name, file, buf, n)
1344 #else
1345 #define os_file_read_first_page(type, file_name, file, buf, n) \
1346   os_file_read_first_page_pfs(type, file_name, file.m_file, buf, n)
1347 #endif
1348 
1349 #ifdef UNIV_PFS_IO
1350 #define os_file_flush(file) os_file_flush_pfs(file)
1351 #else
1352 #define os_file_flush(file) os_file_flush_pfs(file.m_file)
1353 #endif
1354 
1355 #ifdef UNIV_PFS_IO
1356 #define os_file_write(type, name, file, buf, offset, n) \
1357   os_file_write_pfs(type, name, file, buf, offset, n)
1358 #else
1359 #define os_file_write(type, name, file, buf, offset, n) \
1360   os_file_write_pfs(type, name, file.m_file, buf, offset, n)
1361 #endif
1362 
1363 #ifdef UNIV_PFS_IO
1364 #define os_file_copy(src, src_offset, dest, dest_offset, size) \
1365   os_file_copy_pfs(src, src_offset, dest, dest_offset, size)
1366 #else
1367 #define os_file_copy(src, src_offset, dest, dest_offset, size) \
1368   os_file_copy_pfs(src.m_file, src_offset, dest.m_file, dest_offset, size)
1369 #endif
1370 
1371 #ifdef UNIV_PFS_IO
1372 #define os_file_read_no_error_handling(type, file_name, file, buf, offset, n, \
1373                                        o)                                     \
1374   os_file_read_no_error_handling_pfs(type, file_name, file, buf, offset, n, o)
1375 #else
1376 #define os_file_read_no_error_handling(type, file_name, file, buf, offset, n, \
1377                                        o)                                     \
1378   os_file_read_no_error_handling_pfs(type, file_name, file.m_file, buf,       \
1379                                      offset, n, o)
1380 #endif
1381 
1382 #ifdef UNIV_HOTBACKUP
1383 /** Closes a file handle.
1384 @param[in] file		handle to a file
1385 @return true if success */
1386 bool os_file_close_no_error_handling(os_file_t file);
1387 #endif /* UNIV_HOTBACKUP */
1388 
1389 /** Gets a file size.
1390 @param[in]	filename	handle to a file
1391 @return file size if OK, else set m_total_size to ~0 and m_alloc_size
1392         to errno */
1393 os_file_size_t os_file_get_size(const char *filename)
1394     MY_ATTRIBUTE((warn_unused_result));
1395 
1396 /** Gets a file size.
1397 @param[in]	file		handle to a file
1398 @return file size, or (os_offset_t) -1 on failure */
1399 os_offset_t os_file_get_size(pfs_os_file_t file)
1400     MY_ATTRIBUTE((warn_unused_result));
1401 
1402 /** Allocate a block to file using fallocate from the given offset if
1403 fallocate is supported. Falls back to the old slower method of writing
1404 zeros otherwise.
1405 @param[in]	name		name of the file
1406 @param[in]	file		handle to the file
1407 @param[in]	offset		file offset
1408 @param[in]	size		file size
1409 @param[in]	read_only	enable read-only checks if true
1410 @param[in]	flush		flush file content to disk
1411 @return true if success */
1412 bool os_file_set_size_fast(const char *name, pfs_os_file_t file,
1413                            os_offset_t offset, os_offset_t size, bool read_only,
1414                            bool flush) MY_ATTRIBUTE((warn_unused_result));
1415 
1416 /** Write the specified number of zeros to a file from specific offset.
1417 @param[in]	name		name of the file or path as a null-terminated
1418                                 string
1419 @param[in]	file		handle to a file
1420 @param[in]	offset		file offset
1421 @param[in]	size		file size
1422 @param[in]	read_only	enable read-only checks if true
1423 @param[in]	flush		flush file content to disk
1424 @return true if success */
1425 bool os_file_set_size(const char *name, pfs_os_file_t file, os_offset_t offset,
1426                       os_offset_t size, bool read_only, bool flush)
1427     MY_ATTRIBUTE((warn_unused_result));
1428 
1429 /** Truncates a file at its current position.
1430 @param[in,out]	file	file to be truncated
1431 @return true if success */
1432 bool os_file_set_eof(FILE *file); /*!< in: file to be truncated */
1433 
1434 /** Truncates a file to a specified size in bytes. Do nothing if the size
1435 preserved is smaller or equal than current size of file.
1436 @param[in]	pathname	file path
1437 @param[in]	file		file to be truncated
1438 @param[in]	size		size preserved in bytes
1439 @return true if success */
1440 bool os_file_truncate(const char *pathname, pfs_os_file_t file,
1441                       os_offset_t size);
1442 
1443 /** Set read/write position of a file handle to specific offset.
1444 @param[in]	pathname	file path
1445 @param[in]	file		file handle
1446 @param[in]	offset		read/write offset
1447 @return true if success */
1448 bool os_file_seek(const char *pathname, os_file_t file, os_offset_t offset);
1449 
1450 /** NOTE! Use the corresponding macro os_file_flush(), not directly this
1451 function!
1452 Flushes the write buffers of a given file to the disk.
1453 @param[in]	file		handle to a file
1454 @return true if success */
1455 bool os_file_flush_func(os_file_t file);
1456 
1457 /** Retrieves the last error number if an error occurs in a file io function.
1458 The number should be retrieved before any other OS calls (because they may
1459 overwrite the error number). If the number is not known to this program,
1460 the OS error number + 100 is returned.
1461 @param[in]	report_all_errors	true if we want an error message printed
1462                                         for all errors
1463 @return error number, or OS error number + 100 */
1464 ulint os_file_get_last_error(bool report_all_errors);
1465 
1466 /** NOTE! Use the corresponding macro os_file_read(), not directly this
1467 function!
1468 Requests a synchronous read operation.
1469 @param[in]	type		IO request context
1470 @param[in]  file_name file name
1471 @param[in]	file		Open file handle
1472 @param[out]	buf		buffer where to read
1473 @param[in]	offset		file offset where to read
1474 @param[in]	n		number of bytes to read
1475 @return DB_SUCCESS if request was successful */
1476 dberr_t os_file_read_func(IORequest &type, const char *file_name,
1477                           os_file_t file, void *buf, os_offset_t offset,
1478                           ulint n) MY_ATTRIBUTE((warn_unused_result));
1479 
1480 /** NOTE! Use the corresponding macro os_file_read_first_page(),
1481 not directly this function!
1482 Requests a synchronous read operation of page 0 of IBD file
1483 @param[in]	type		IO request context
1484 @param[in]  file_name file name
1485 @param[in]	file		Open file handle
1486 @param[out]	buf		buffer where to read
1487 @param[in]	n		number of bytes to read
1488 @return DB_SUCCESS if request was successful */
1489 dberr_t os_file_read_first_page_func(IORequest &type, const char *file_name,
1490                                      os_file_t file, void *buf, ulint n)
1491     MY_ATTRIBUTE((warn_unused_result));
1492 
1493 /** copy data from one file to another file. Data is read/written
1494 at current file offset.
1495 @param[in]	src_file	file handle to copy from
1496 @param[in]	src_offset	offset to copy from
1497 @param[in]	dest_file	file handle to copy to
1498 @param[in]	dest_offset	offset to copy to
1499 @param[in]	size		number of bytes to copy
1500 @return DB_SUCCESS if successful */
1501 dberr_t os_file_copy_func(os_file_t src_file, os_offset_t src_offset,
1502                           os_file_t dest_file, os_offset_t dest_offset,
1503                           uint size) MY_ATTRIBUTE((warn_unused_result));
1504 
1505 /** Rewind file to its start, read at most size - 1 bytes from it to str, and
1506 NUL-terminate str. All errors are silently ignored. This function is
1507 mostly meant to be used with temporary files.
1508 @param[in,out]	file		file to read from
1509 @param[in,out]	str		buffer where to read
1510 @param[in]	size		size of buffer */
1511 void os_file_read_string(FILE *file, char *str, ulint size);
1512 
1513 /** NOTE! Use the corresponding macro os_file_read_no_error_handling(),
1514 not directly this function!
1515 Requests a synchronous positioned read operation. This function does not do
1516 any error handling. In case of error it returns FALSE.
1517 @param[in]	type		IO request context
1518 @param[in]  file_name file name
1519 @param[in]	file		Open file handle
1520 @param[out]	buf		buffer where to read
1521 @param[in]	offset		file offset where to read
1522 @param[in]	n		number of bytes to read
1523 @param[out]	o		number of bytes actually read
1524 @return DB_SUCCESS or error code */
1525 dberr_t os_file_read_no_error_handling_func(
1526     IORequest &type, const char *file_name, os_file_t file, void *buf,
1527     os_offset_t offset, ulint n, ulint *o) MY_ATTRIBUTE((warn_unused_result));
1528 
1529 /** NOTE! Use the corresponding macro os_file_write(), not directly this
1530 function!
1531 Requests a synchronous write operation.
1532 @param[in,out]	type		IO request context
1533 @param[in]	name		name of the file or path as a null-terminated
1534                                 string
1535 @param[in]	file		Open file handle
1536 @param[out]	buf		buffer where to read
1537 @param[in]	offset		file offset where to read
1538 @param[in]	n		number of bytes to read
1539 @return DB_SUCCESS if request was successful */
1540 dberr_t os_file_write_func(IORequest &type, const char *name, os_file_t file,
1541                            const void *buf, os_offset_t offset, ulint n)
1542     MY_ATTRIBUTE((warn_unused_result));
1543 
1544 /** Check the existence and type of a given path.
1545 @param[in]   path    pathname of the file
1546 @param[out]  exists  true if file exists
1547 @param[out]  type    type of the file (if it exists)
1548 @return true if call succeeded */
1549 bool os_file_status(const char *path, bool *exists, os_file_type_t *type);
1550 
1551 /** Check the existence and usefulness of a given path.
1552 @param[in]  path  path name
1553 @retval true if the path exists and can be used
1554 @retval false if the path does not exist or if the path is
1555 unuseable to get to a possibly existing file or directory. */
1556 bool os_file_exists(const char *path);
1557 
1558 /** Create all missing subdirectories along the given path.
1559 @return DB_SUCCESS if OK, otherwise error code. */
1560 dberr_t os_file_create_subdirs_if_needed(const char *path);
1561 
1562 #ifdef UNIV_ENABLE_UNIT_TEST_GET_PARENT_DIR
1563 /* Test the function os_file_get_parent_dir. */
1564 void unit_test_os_file_get_parent_dir();
1565 #endif /* UNIV_ENABLE_UNIT_TEST_GET_PARENT_DIR */
1566 
1567 #ifdef UNIV_HOTBACKUP
1568 /** Deallocates the "Blocks" in block_cache */
1569 void meb_free_block_cache();
1570 #endif /* UNIV_HOTBACKUP */
1571 
1572 /** Creates and initializes block_cache. Creates array of MAX_BLOCKS
1573 and allocates the memory in each block to hold BUFFER_BLOCK_SIZE
1574 of data.
1575 
1576 This function is called by InnoDB during srv_start().
1577 It is also called by MEB while applying the redo logs on TDE tablespaces,
1578 the "Blocks" allocated in this block_cache are used to hold the decrypted
1579 page data. */
1580 void os_create_block_cache();
1581 
1582 /** Initializes the asynchronous io system. Creates one array each for ibuf
1583 and log i/o. Also creates one array each for read and write where each
1584 array is divided logically into n_read_segs and n_write_segs
1585 respectively. The caller must create an i/o handler thread for each
1586 segment in these arrays. This function also creates the sync array.
1587 No i/o handler thread needs to be created for that
1588 @param[in]	n_readers	number of reader threads
1589 @param[in]	n_writers	number of writer threads
1590 @param[in]	n_slots_sync	number of slots in the dblwr aio array */
1591 
1592 bool os_aio_init(ulint n_readers, ulint n_writers, ulint n_slots_sync);
1593 
1594 /**
1595 Frees the asynchronous io system. */
1596 void os_aio_free();
1597 
1598 /**
1599 NOTE! Use the corresponding macro os_aio(), not directly this function!
1600 Requests an asynchronous i/o operation.
1601 @param[in]	type		IO request context
1602 @param[in]	aio_mode	IO mode
1603 @param[in]	name		Name of the file or path as NUL terminated
1604                                 string
1605 @param[in]	file		Open file handle
1606 @param[out]	buf		buffer where to read
1607 @param[in]	offset		file offset where to read
1608 @param[in]	n		number of bytes to read
1609 @param[in]	read_only	if true read only mode checks are enforced
1610 @param[in,out]	m1		Message for the AIO handler, (can be used to
1611                                 identify a completed AIO operation); ignored
1612                                 if mode is OS_AIO_SYNC
1613 @param[in,out]	m2		message for the AIO handler (can be used to
1614                                 identify a completed AIO operation); ignored
1615                                 if mode is OS_AIO_SYNC
1616 @return DB_SUCCESS or error code */
1617 dberr_t os_aio_func(IORequest &type, AIO_mode aio_mode, const char *name,
1618                     pfs_os_file_t file, void *buf, os_offset_t offset, ulint n,
1619                     bool read_only, fil_node_t *m1, void *m2);
1620 
1621 /** Wakes up all async i/o threads so that they know to exit themselves in
1622 shutdown. */
1623 void os_aio_wake_all_threads_at_shutdown();
1624 
1625 /** Waits until there are no pending writes in os_aio_write_array. There can
1626 be other, synchronous, pending writes. */
1627 void os_aio_wait_until_no_pending_writes();
1628 
1629 /** Wakes up simulated aio i/o-handler threads if they have something to do. */
1630 void os_aio_simulated_wake_handler_threads();
1631 
1632 /** This function can be called if one wants to post a batch of reads and
1633 prefers an i/o-handler thread to handle them all at once later. You must
1634 call os_aio_simulated_wake_handler_threads later to ensure the threads
1635 are not left sleeping! */
1636 void os_aio_simulated_put_read_threads_to_sleep();
1637 
1638 /** This is the generic AIO handler interface function.
1639 Waits for an aio operation to complete. This function is used to wait the
1640 for completed requests. The AIO array of pending requests is divided
1641 into segments. The thread specifies which segment or slot it wants to wait
1642 for. NOTE: this function will also take care of freeing the aio slot,
1643 therefore no other thread is allowed to do the freeing!
1644 @param[in]	segment		the number of the segment in the aio arrays to
1645                                 wait for; segment 0 is the ibuf I/O thread,
1646                                 segment 1 the log I/O thread, then follow the
1647                                 non-ibuf read threads, and as the last are the
1648                                 non-ibuf write threads; if this is
1649                                 ULINT_UNDEFINED, then it means that sync AIO
1650                                 is used, and this parameter is ignored
1651 @param[out]	m1		the messages passed with the AIO request;
1652                                 note that also in the case where the AIO
1653                                 operation failed, these output parameters
1654                                 are valid and can be used to restart the
1655                                 operation, for example
1656 @param[out]	m2		callback message
1657 @param[out]	request		OS_FILE_WRITE or ..._READ
1658 @return DB_SUCCESS or error code */
1659 dberr_t os_aio_handler(ulint segment, fil_node_t **m1, void **m2,
1660                        IORequest *request);
1661 
1662 /** Prints info of the aio arrays.
1663 @param[in,out]	file		file where to print */
1664 void os_aio_print(FILE *file);
1665 
1666 /** Refreshes the statistics used to print per-second averages. */
1667 void os_aio_refresh_stats();
1668 
1669 /** Checks that all slots in the system have been freed, that is, there are
1670 no pending io operations. */
1671 bool os_aio_all_slots_free();
1672 
1673 #ifdef UNIV_DEBUG
1674 
1675 /** Prints all pending IO
1676 @param[in]	file	file where to print */
1677 void os_aio_print_pending_io(FILE *file);
1678 
1679 #endif /* UNIV_DEBUG */
1680 
1681 /** Get available free space on disk
1682 @param[in]	path		pathname of a directory or file in disk
1683 @param[out]	free_space	free space available in bytes
1684 @return DB_SUCCESS if all OK */
1685 dberr_t os_get_free_space(const char *path, uint64_t &free_space);
1686 
1687 /** This function returns information about the specified file
1688 @param[in]	path		pathname of the file
1689 @param[in]	stat_info	information of a file in a directory
1690 @param[in]	check_rw_perm	for testing whether the file can be opened
1691                                 in RW mode
1692 @param[in]	read_only	if true read only mode checks are enforced
1693 @return DB_SUCCESS if all OK */
1694 dberr_t os_file_get_status(const char *path, os_file_stat_t *stat_info,
1695                            bool check_rw_perm, bool read_only);
1696 
1697 #ifndef UNIV_HOTBACKUP
1698 
1699 /** return any of the tmpdir path */
1700 char *innobase_mysql_tmpdir();
1701 /** Creates a temporary file in the location specified by the parameter
1702 path. If the path is NULL then it will be created on --tmpdir location.
1703 This function is defined in ha_innodb.cc.
1704 @param[in]	path	location for creating temporary file
1705 @return temporary file descriptor, or < 0 on error */
1706 int innobase_mysql_tmpfile(const char *path);
1707 #endif /* !UNIV_HOTBACKUP */
1708 
1709 /** If it is a compressed page return the compressed page data + footer size
1710 @param[in]	buf		Buffer to check, must include header + 10 bytes
1711 @return ULINT_UNDEFINED if the page is not a compressed page or length
1712         of the compressed data (including footer) if it is a compressed page */
1713 ulint os_file_compressed_page_size(const byte *buf);
1714 
1715 /** If it is a compressed page return the original page data + footer size
1716 @param[in]	buf		Buffer to check, must include header + 10 bytes
1717 @return ULINT_UNDEFINED if the page is not a compressed page or length
1718         of the original data + footer if it is a compressed page */
1719 ulint os_file_original_page_size(const byte *buf);
1720 
1721 /** Set the file create umask
1722 @param[in]	umask		The umask to use for file creation. */
1723 void os_file_set_umask(ulint umask);
1724 
1725 /** Get the file create umask
1726 @return the umask to use for file creation. */
1727 ulint os_file_get_umask();
1728 
1729 /** Free storage space associated with a section of the file.
1730 @param[in]	fh		Open file handle
1731 @param[in]	off		Starting offset (SEEK_SET)
1732 @param[in]	len		Size of the hole
1733 @return DB_SUCCESS or error code */
1734 dberr_t os_file_punch_hole(os_file_t fh, os_offset_t off, os_offset_t len)
1735     MY_ATTRIBUTE((warn_unused_result));
1736 
1737 /** Check if the file system supports sparse files.
1738 
1739 Warning: On POSIX systems we try and punch a hole from offset 0 to
1740 the system configured page size. This should only be called on an empty
1741 file.
1742 
1743 Note: On Windows we use the name and on Unices we use the file handle.
1744 
1745 @param[in]	path	File name
1746 @param[in]	fh	File handle for the file - if opened
1747 @return true if the file system supports sparse files */
1748 bool os_is_sparse_file_supported(const char *path, pfs_os_file_t fh)
1749     MY_ATTRIBUTE((warn_unused_result));
1750 
1751 /** Decompress the page data contents. Page type must be FIL_PAGE_COMPRESSED, if
1752 not then the source contents are left unchanged and DB_SUCCESS is returned.
1753 @param[in]	dblwr_read	true of double write recovery in progress
1754 @param[in,out]	src		Data read from disk, decompressed data will be
1755                                 copied to this page
1756 @param[in,out]	dst		Scratch area to use for decompression
1757 @param[in]	dst_len		Size of the scratch area in bytes
1758 @return DB_SUCCESS or error code */
1759 dberr_t os_file_decompress_page(bool dblwr_read, byte *src, byte *dst,
1760                                 ulint dst_len)
1761     MY_ATTRIBUTE((warn_unused_result));
1762 
1763 /** Compress a data page
1764 @param[in]	compression	Compression algorithm
1765 @param[in]	block_size	File system block size
1766 @param[in]	src		Source contents to compress
1767 @param[in]	src_len		Length in bytes of the source
1768 @param[out]	dst		Compressed page contents
1769 @param[out]	dst_len		Length in bytes of dst contents
1770 @return buffer data, dst_len will have the length of the data */
1771 byte *os_file_compress_page(Compression compression, ulint block_size,
1772                             byte *src, ulint src_len, byte *dst,
1773                             ulint *dst_len);
1774 
1775 /** Determine if O_DIRECT is supported.
1776 @retval	true	if O_DIRECT is supported.
1777 @retval	false	if O_DIRECT is not supported. */
1778 bool os_is_o_direct_supported() MY_ATTRIBUTE((warn_unused_result));
1779 
1780 /** Fill the pages with NULs
1781 @param[in] file		File handle
1782 @param[in] name		File name
1783 @param[in] page_size	physical page size
1784 @param[in] start	Offset from the start of the file in bytes
1785 @param[in] len		Length in bytes
1786 @param[in] read_only_mode
1787                         if true, then read only mode checks are enforced.
1788 @return DB_SUCCESS or error code */
1789 dberr_t os_file_write_zeros(pfs_os_file_t file, const char *name,
1790                             ulint page_size, os_offset_t start, ulint len,
1791                             bool read_only_mode)
1792     MY_ATTRIBUTE((warn_unused_result));
1793 
1794 #ifndef UNIV_NONINL
1795 /** Class to scan the directory heirarchy using a depth first scan. */
1796 class Dir_Walker {
1797  public:
1798   using Path = std::string;
1799 
1800   /** Check if the path is a directory. The file/directory must exist.
1801   @param[in]	path		The path to check
1802   @return true if it is a directory */
1803   static bool is_directory(const Path &path);
1804 
1805   /** Depth first traversal of the directory starting from basedir
1806   @param[in]  basedir    Start scanning from this directory
1807   @param[in]  recursive  `true` if scan should be recursive
1808   @param[in]  f          Function to call for each entry */
1809   template <typename F>
walk(const Path & basedir,bool recursive,F && f)1810   static void walk(const Path &basedir, bool recursive, F &&f) {
1811 #ifdef _WIN32
1812     walk_win32(basedir, recursive,
1813                [&](const Path &path, size_t depth) { f(path); });
1814 #else
1815     walk_posix(basedir, recursive,
1816                [&](const Path &path, size_t depth) { f(path); });
1817 #endif /* _WIN32 */
1818   }
1819 
1820  private:
1821   /** Directory names for the depth first directory scan. */
1822   struct Entry {
1823     /** Constructor
1824     @param[in]	path		Directory to traverse
1825     @param[in]	depth		Relative depth to the base
1826                                     directory in walk() */
EntryEntry1827     Entry(const Path &path, size_t depth) : m_path(path), m_depth(depth) {}
1828 
1829     /** Path to the directory */
1830     Path m_path;
1831 
1832     /** Relative depth of m_path */
1833     size_t m_depth;
1834   };
1835 
1836   using Function = std::function<void(const Path &, size_t)>;
1837 
1838   /** Depth first traversal of the directory starting from basedir
1839   @param[in]      basedir    Start scanning from this directory
1840   @param[in]      recursive  `true` if scan should be recursive
1841   @param[in]      f          Callback for each entry found */
1842 #ifdef _WIN32
1843   static void walk_win32(const Path &basedir, bool recursive, Function &&f);
1844 #else
1845   static void walk_posix(const Path &basedir, bool recursive, Function &&f);
1846 #endif /* _WIN32 */
1847 };
1848 
1849 /** Allocate a page for sync IO
1850 @return pointer to page */
1851 file::Block *os_alloc_block() noexcept;
1852 
1853 /** Free a page after sync IO
1854 @param[in,out]	block		The block to free/release */
1855 void os_free_block(file::Block *block) noexcept;
1856 
1857 #include "os0file.ic"
1858 #endif /* UNIV_NONINL */
1859 
1860 #endif /* os0file_h */
1861