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