1/***************************************************************************** 2 3Copyright (c) 2010, 2019, Oracle and/or its affiliates. All Rights Reserved. 4 5This program is free software; you can redistribute it and/or modify it under 6the terms of the GNU General Public License, version 2.0, as published by the 7Free Software Foundation. 8 9This program is also distributed with certain software (including but not 10limited to OpenSSL) that is licensed under separate terms, as designated in a 11particular file or component or in included license documentation. The authors 12of MySQL hereby grant you an additional permission to link the program and 13your derivative works with the separately licensed software that they have 14included with MySQL. 15 16This program is distributed in the hope that it will be useful, but WITHOUT 17ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 18FOR A PARTICULAR PURPOSE. See the GNU General Public License, version 2.0, 19for more details. 20 21You should have received a copy of the GNU General Public License along with 22this program; if not, write to the Free Software Foundation, Inc., 2351 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 24 25*****************************************************************************/ 26 27/** @file include/os0file.ic 28 The interface to the operating system file io 29 30 Created 2/20/2010 Jimmy Yang 31 *******************************************************/ 32 33#include "univ.i" 34 35#ifdef UNIV_PFS_IO 36/** NOTE! Please use the corresponding macro os_file_create_simple(), 37not directly this function! 38A performance schema instrumented wrapper function for 39os_file_create_simple() which opens or creates a file. 40@param[in] key Performance Schema Key 41@param[in] name name of the file or path as a null-terminated 42 string 43@param[in] create_mode create mode 44@param[in] access_type OS_FILE_READ_ONLY or OS_FILE_READ_WRITE 45@param[in] read_only if true read only mode checks are enforced 46@param[out] success true if succeeded 47@param[in] src_file file name where func invoked 48@param[in] src_line line where the func invoked 49@return own: handle to the file, not defined if error, error number 50can be retrieved with os_file_get_last_error */ 51UNIV_INLINE 52pfs_os_file_t pfs_os_file_create_simple_func( 53 mysql_pfs_key_t key, const char *name, ulint create_mode, ulint access_type, 54 bool read_only, bool *success, const char *src_file, uint src_line) { 55 PSI_file_locker_state state; 56 struct PSI_file_locker *locker = nullptr; 57 pfs_os_file_t file; 58 59 /* register a file open or creation depending on "create_mode" */ 60 register_pfs_file_open_begin( 61 &state, locker, key, 62 (create_mode == OS_FILE_CREATE) ? PSI_FILE_CREATE : PSI_FILE_OPEN, name, 63 src_file, src_line); 64 65 file.m_file = os_file_create_simple_func(name, create_mode, access_type, 66 read_only, success); 67 file.m_psi = nullptr; 68 69 /* Regsiter psi value for the file */ 70 register_pfs_file_open_end(locker, file, 71 (*success == TRUE ? success : nullptr)); 72 73 return (file); 74} 75 76/** NOTE! Please use the corresponding macro 77os_file_create_simple_no_error_handling(), not directly this function! 78A performance schema instrumented wrapper function for 79os_file_create_simple_no_error_handling(). Add instrumentation to 80monitor file creation/open. 81@param[in] key Performance Schema Key 82@param[in] name name of the file or path as a null-terminated 83 string 84@param[in] create_mode create mode 85@param[in] access_type OS_FILE_READ_ONLY, OS_FILE_READ_WRITE, or 86 OS_FILE_READ_ALLOW_DELETE; the last option is 87 used by a backup program reading the file 88@param[in] read_only if true read only mode checks are enforced 89@param[out] success true if succeeded 90@param[in] src_file file name where func invoked 91@param[in] src_line line where the func invoked 92@return own: handle to the file, not defined if error, error number 93can be retrieved with os_file_get_last_error */ 94UNIV_INLINE 95pfs_os_file_t pfs_os_file_create_simple_no_error_handling_func( 96 mysql_pfs_key_t key, const char *name, ulint create_mode, ulint access_type, 97 bool read_only, bool *success, const char *src_file, uint src_line) { 98 PSI_file_locker_state state; 99 struct PSI_file_locker *locker = nullptr; 100 pfs_os_file_t file; 101 102 /* register a file open or creation depending on "create_mode" */ 103 register_pfs_file_open_begin( 104 &state, locker, key, 105 create_mode == OS_FILE_CREATE ? PSI_FILE_CREATE : PSI_FILE_OPEN, name, 106 src_file, src_line); 107 108 file = os_file_create_simple_no_error_handling_func( 109 name, create_mode, access_type, read_only, success); 110 111 file.m_psi = nullptr; 112 register_pfs_file_open_end(locker, file, 113 (*success == TRUE ? success : nullptr)); 114 115 return (file); 116} 117 118/** NOTE! Please use the corresponding macro os_file_create(), not directly 119this function! 120A performance schema wrapper function for os_file_create(). 121Add instrumentation to monitor file creation/open. 122@param[in] key Performance Schema Key 123@param[in] name name of the file or path as a null-terminated 124 string 125@param[in] create_mode create mode 126@param[in] purpose OS_FILE_AIO, if asynchronous, non-buffered I/O 127 is desired, OS_FILE_NORMAL, if any normal file; 128 NOTE that it also depends on type, os_aio_.. 129 and srv_.. variables whether we really us 130 async I/O or unbuffered I/O: look in the 131 function source code for the exact rules 132@param[in] type OS_DATA_FILE or OS_LOG_FILE 133@param[in] read_only if true read only mode checks are enforced 134@param[out] success true if succeeded 135@param[in] src_file file name where func invoked 136@param[in] src_line line where the func invoked 137@return own: handle to the file, not defined if error, error number 138can be retrieved with os_file_get_last_error */ 139UNIV_INLINE 140pfs_os_file_t pfs_os_file_create_func(mysql_pfs_key_t key, const char *name, 141 ulint create_mode, ulint purpose, 142 ulint type, bool read_only, bool *success, 143 const char *src_file, uint src_line) { 144 PSI_file_locker_state state; 145 struct PSI_file_locker *locker = nullptr; 146 pfs_os_file_t file; 147 148 /* register a file open or creation depending on "create_mode" */ 149 register_pfs_file_open_begin( 150 &state, locker, key, 151 create_mode == OS_FILE_CREATE ? PSI_FILE_CREATE : PSI_FILE_OPEN, name, 152 src_file, src_line); 153 154 file = 155 os_file_create_func(name, create_mode, purpose, type, read_only, success); 156 157 file.m_psi = nullptr; 158 register_pfs_file_open_end(locker, file, 159 (*success == TRUE ? success : nullptr)); 160 161 return (file); 162} 163/** 164NOTE! Please use the corresponding macro os_file_close(), not directly 165this function! 166A performance schema instrumented wrapper function for os_file_close(). 167@param[in] file handle to a file 168@param[in] src_file file name where func invoked 169@param[in] src_line line where the func invoked 170@return true if success */ 171UNIV_INLINE 172bool pfs_os_file_close_func(pfs_os_file_t file, const char *src_file, 173 uint src_line) { 174 PSI_file_locker_state state; 175 struct PSI_file_locker *locker = nullptr; 176 177 /* register the file close */ 178 register_pfs_file_io_begin(&state, locker, file, 0, PSI_FILE_CLOSE, src_file, 179 src_line); 180 181 bool result = os_file_close_func(file.m_file); 182 183 register_pfs_file_io_end(locker, 0); 184 185 return (result); 186} 187 188#ifndef UNIV_HOTBACKUP 189/** NOTE! Please use the corresponding macro os_aio(), not directly this 190function! 191Performance schema wrapper function of os_aio() which requests 192an asynchronous i/o operation. 193@param[in] type IO request context 194@param[in] aio_mode IO mode 195@param[in] name Name of the file or path as NUL terminated 196 string 197@param[in] file Open file handle 198@param[out] buf buffer where to read 199@param[in] offset file offset where to read 200@param[in] n number of bytes to read 201@param[in] read_only if true read only mode checks are enforced 202@param[in,out] m1 Message for the AIO handler, (can be used to 203 identify a completed AIO operation); ignored 204 if mode is OS_AIO_SYNC 205@param[in,out] m2 message for the AIO handler (can be used to 206 identify a completed AIO operation); ignored 207 if mode is OS_AIO_SYNC 208@param[in] src_file file name where func invoked 209@param[in] src_line line where the func invoked 210@return DB_SUCCESS if request was queued successfully, false if fail */ 211UNIV_INLINE 212dberr_t pfs_os_aio_func(IORequest &type, AIO_mode aio_mode, const char *name, 213 pfs_os_file_t file, void *buf, os_offset_t offset, 214 ulint n, bool read_only, fil_node_t *m1, void *m2, 215 const char *src_file, uint src_line) { 216 PSI_file_locker_state state; 217 struct PSI_file_locker *locker = nullptr; 218 219 ut_ad(type.validate()); 220 221 /* Register the read or write I/O depending on "type" */ 222 register_pfs_file_io_begin(&state, locker, file, n, 223 type.is_write() ? PSI_FILE_WRITE : PSI_FILE_READ, 224 src_file, src_line); 225 226 dberr_t result = os_aio_func(type, aio_mode, name, file, buf, offset, n, 227 read_only, m1, m2); 228 229 register_pfs_file_io_end(locker, n); 230 231 return (result); 232} 233#endif /* UNIV_HOTBACKUP */ 234 235/** NOTE! Please use the corresponding macro os_file_read(), not directly 236this function! 237This is the performance schema instrumented wrapper function for 238os_file_read() which requests a synchronous read operation. 239@param[in, out] type IO request context 240@param[in] file_name file name 241@param[in] file Open file handle 242@param[out] buf buffer where to read 243@param[in] offset file offset where to read 244@param[in] n number of bytes to read 245@param[in] src_file file name where func invoked 246@param[in] src_line line where the func invoked 247@return DB_SUCCESS if request was successful */ 248UNIV_INLINE 249dberr_t pfs_os_file_read_func(IORequest &type, const char *file_name, 250 pfs_os_file_t file, void *buf, os_offset_t offset, 251 ulint n, const char *src_file, uint src_line) { 252 PSI_file_locker_state state; 253 struct PSI_file_locker *locker = nullptr; 254 255 ut_ad(type.validate()); 256 257 register_pfs_file_io_begin(&state, locker, file, n, PSI_FILE_READ, src_file, 258 src_line); 259 260 dberr_t result; 261 262 result = os_file_read_func(type, file_name, file.m_file, buf, offset, n); 263 264 register_pfs_file_io_end(locker, n); 265 266 return (result); 267} 268 269/** NOTE! Please use the corresponding macro os_file_read_first_page(), 270not directly this function! 271This is the performance schema instrumented wrapper function for 272os_file_read() which requests a synchronous read operation. 273@param[in, out] type IO request context 274@param[in] file_name file name 275@param[in] file Open file handle 276@param[out] buf buffer where to read 277@param[in] n number of bytes to read 278@param[in] src_file file name where func invoked 279@param[in] src_line line where the func invoked 280@return DB_SUCCESS if request was successful */ 281UNIV_INLINE 282dberr_t pfs_os_file_read_first_page_func(IORequest &type, const char *file_name, 283 pfs_os_file_t file, void *buf, ulint n, 284 const char *src_file, uint src_line) { 285 PSI_file_locker_state state; 286 struct PSI_file_locker *locker = nullptr; 287 288 ut_ad(type.validate()); 289 290 register_pfs_file_io_begin(&state, locker, file, n, PSI_FILE_READ, src_file, 291 src_line); 292 293 dberr_t result; 294 295 result = os_file_read_first_page_func(type, file_name, file.m_file, buf, n); 296 297 register_pfs_file_io_end(locker, n); 298 299 return (result); 300} 301 302/** Copy data from one file to another file. Data is read/written 303at current file offset. 304@param[in] src file handle to copy from 305@param[in] src_offset offset to copy from 306@param[in] dest file handle to copy to 307@param[in] dest_offset offset to copy to 308@param[in] size number of bytes to copy 309@param[in] src_file file name where func invoked 310@param[in] src_line line where the func invoked 311@return DB_SUCCESS if successful */ 312UNIV_INLINE 313dberr_t pfs_os_file_copy_func(pfs_os_file_t src, os_offset_t src_offset, 314 pfs_os_file_t dest, os_offset_t dest_offset, 315 uint size, const char *src_file, uint src_line) { 316 dberr_t result; 317 318 PSI_file_locker_state state_read; 319 PSI_file_locker_state state_write; 320 321 struct PSI_file_locker *locker_read = nullptr; 322 struct PSI_file_locker *locker_write = nullptr; 323 324 register_pfs_file_io_begin(&state_read, locker_read, src, size, PSI_FILE_READ, 325 src_file, src_line); 326 327 register_pfs_file_io_begin(&state_write, locker_write, dest, size, 328 PSI_FILE_WRITE, src_file, src_line); 329 330 result = 331 os_file_copy_func(src.m_file, src_offset, dest.m_file, dest_offset, size); 332 333 register_pfs_file_io_end(locker_write, size); 334 register_pfs_file_io_end(locker_read, size); 335 336 return (result); 337} 338 339/** NOTE! Please use the corresponding macro os_file_read_no_error_handling(), 340not directly this function! 341This is the performance schema instrumented wrapper function for 342os_file_read_no_error_handling_func() which requests a synchronous 343read operation. 344@param[in, out] type IO request context 345@param[in] file_name file name 346@param[in] file Open file handle 347@param[out] buf buffer where to read 348@param[in] offset file offset where to read 349@param[in] n number of bytes to read 350@param[out] o number of bytes actually read 351@param[in] src_file file name where func invoked 352@param[in] src_line line where the func invoked 353@return DB_SUCCESS if request was successful */ 354UNIV_INLINE 355dberr_t pfs_os_file_read_no_error_handling_func(IORequest &type, 356 const char *file_name, 357 pfs_os_file_t file, void *buf, 358 os_offset_t offset, ulint n, 359 ulint *o, const char *src_file, 360 uint src_line) { 361 PSI_file_locker_state state; 362 struct PSI_file_locker *locker = nullptr; 363 364 register_pfs_file_io_begin(&state, locker, file, n, PSI_FILE_READ, src_file, 365 src_line); 366 367 dberr_t result = os_file_read_no_error_handling_func( 368 type, file_name, file.m_file, buf, offset, n, o); 369 370 register_pfs_file_io_end(locker, n); 371 372 return (result); 373} 374 375/** NOTE! Please use the corresponding macro 376os_file_read_no_error_handling_int_fd(), not directly this function! 377This is the performance schema instrumented wrapper function for 378os_file_read_no_error_handling_int_fd_func() which requests a 379synchronous read operation. 380@param[in, out] type IO request context 381@param[in] file_name file name 382@param[in] file Open file handle 383@param[out] buf buffer where to read 384@param[in] offset file offset where to read 385@param[in] n number of bytes to read 386@param[out] o number of bytes actually read 387@param[in] src_file file name where func invoked 388@param[in] src_line line where the func invoked 389@return DB_SUCCESS if request was successful */ 390 391UNIV_INLINE 392dberr_t pfs_os_file_read_no_error_handling_int_fd_func( 393 IORequest &type, const char *file_name, int file, void *buf, 394 os_offset_t offset, ulint n, ulint *o, const char *src_file, 395 ulint src_line) { 396 PSI_file_locker_state state; 397 struct PSI_file_locker *locker = nullptr; 398 399 locker = PSI_FILE_CALL(get_thread_file_descriptor_locker)(&state, file, 400 PSI_FILE_READ); 401 if (locker != nullptr) { 402 PSI_FILE_CALL(start_file_wait)(locker, n, __FILE__, __LINE__); 403 } 404 dberr_t result = os_file_read_no_error_handling_func( 405 type, file_name, OS_FILE_FROM_FD(file), buf, offset, n, o); 406 407 if (locker != nullptr) { 408 PSI_FILE_CALL(end_file_wait)(locker, n); 409 } 410 411 return (result); 412} 413 414/** NOTE! Please use the corresponding macro os_file_write(), not directly 415this function! 416This is the performance schema instrumented wrapper function for 417os_file_write() which requests a synchronous write operation. 418@param[in, out] type IO request context 419@param[in] name Name of the file or path as NUL terminated 420 string 421@param[in] file Open file handle 422@param[out] buf buffer where to read 423@param[in] offset file offset where to read 424@param[in] n number of bytes to read 425@param[in] src_file file name where func invoked 426@param[in] src_line line where the func invoked 427@return DB_SUCCESS if request was successful */ 428UNIV_INLINE 429dberr_t pfs_os_file_write_func(IORequest &type, const char *name, 430 pfs_os_file_t file, const void *buf, 431 os_offset_t offset, ulint n, 432 const char *src_file, uint src_line) { 433 PSI_file_locker_state state; 434 struct PSI_file_locker *locker = nullptr; 435 436 register_pfs_file_io_begin(&state, locker, file, n, PSI_FILE_WRITE, src_file, 437 src_line); 438 439 dberr_t result; 440 441 result = os_file_write_func(type, name, file.m_file, buf, offset, n); 442 443 register_pfs_file_io_end(locker, n); 444 445 return (result); 446} 447 448/** NOTE! Please use the corresponding macro os_file_write(), not 449directly this function! 450This is the performance schema instrumented wrapper function for 451os_file_write() which requests a synchronous write operation. 452@param[in, out] type IO request context 453@param[in] name Name of the file or path as NUL terminated 454 string 455@param[in] file Open file handle 456@param[out] buf buffer where to read 457@param[in] offset file offset where to read 458@param[in] n number of bytes to read 459@param[in] src_file file name where func invoked 460@param[in] src_line line where the func invoked 461@return DB_SUCCESS if request was successful */ 462UNIV_INLINE 463dberr_t pfs_os_file_write_int_fd_func(IORequest &type, const char *name, 464 int file, const void *buf, 465 os_offset_t offset, ulint n, 466 const char *src_file, ulint src_line) { 467 PSI_file_locker_state state; 468 struct PSI_file_locker *locker = nullptr; 469 470 locker = PSI_FILE_CALL(get_thread_file_descriptor_locker)(&state, file, 471 PSI_FILE_WRITE); 472 if (locker != nullptr) { 473 PSI_FILE_CALL(start_file_wait)(locker, n, __FILE__, __LINE__); 474 } 475 dberr_t result = 476 os_file_write_func(type, name, OS_FILE_FROM_FD(file), buf, offset, n); 477 478 if (locker != nullptr) { 479 PSI_FILE_CALL(end_file_wait)(locker, n); 480 } 481 482 return (result); 483} 484 485/** NOTE! Please use the corresponding macro os_file_flush(), 486 not directly 487this function! 488This is the performance schema instrumented wrapper function for 489os_file_flush() which flushes the write buffers of a given file to the disk. 490Flushes the write buffers of a given file to the disk. 491@param[in] file Open file handle 492@param[in] src_file file name where func invoked 493@param[in] src_line line where the func invoked 494@return true if success */ 495UNIV_INLINE 496bool pfs_os_file_flush_func(pfs_os_file_t file, const char *src_file, 497 uint src_line) { 498 PSI_file_locker_state state; 499 struct PSI_file_locker *locker = nullptr; 500 501 register_pfs_file_io_begin(&state, locker, file, 0, PSI_FILE_SYNC, src_file, 502 src_line); 503 504 bool result = os_file_flush_func(file.m_file); 505 506 register_pfs_file_io_end(locker, 0); 507 508 return (result); 509} 510 511/** NOTE! Please use the corresponding macro os_file_rename(), not directly 512this function! 513This is the performance schema instrumented wrapper function for 514os_file_rename() 515@param[in] key Performance Schema Key 516@param[in] oldpath old file path as a null-terminated string 517@param[in] newpath new file path 518@param[in] src_file file name where func invoked 519@param[in] src_line line where the func invoked 520@return true if success */ 521UNIV_INLINE 522bool pfs_os_file_rename_func(mysql_pfs_key_t key, const char *oldpath, 523 const char *newpath, const char *src_file, 524 uint src_line) 525 526{ 527 PSI_file_locker_state state; 528 struct PSI_file_locker *locker = nullptr; 529 530 register_pfs_file_rename_begin(&state, locker, key, PSI_FILE_RENAME, oldpath, 531 newpath, src_file, src_line); 532 533 bool result = os_file_rename_func(oldpath, newpath); 534 535 register_pfs_file_rename_end(locker, oldpath, newpath, !result); 536 537 return (result); 538} 539 540/** NOTE! Please use the corresponding macro os_file_delete(), not directly 541this function! 542This is the performance schema instrumented wrapper function for 543os_file_delete() 544@param[in] key Performance Schema Key 545@param[in] name old file path as a null-terminated string 546@param[in] src_file file name where func invoked 547@param[in] src_line line where the func invoked 548@return true if success */ 549UNIV_INLINE 550bool pfs_os_file_delete_func(mysql_pfs_key_t key, const char *name, 551 const char *src_file, uint src_line) { 552 PSI_file_locker_state state; 553 struct PSI_file_locker *locker = nullptr; 554 555 register_pfs_file_close_begin(&state, locker, key, PSI_FILE_DELETE, name, 556 src_file, src_line); 557 558 bool result = os_file_delete_func(name); 559 560 register_pfs_file_close_end(locker, 0); 561 562 return (result); 563} 564 565/** 566NOTE! Please use the corresponding macro os_file_delete_if_exists(), not 567directly this function! 568This is the performance schema instrumented wrapper function for 569os_file_delete_if_exists() 570@param[in] key Performance Schema Key 571@param[in] name old file path as a null-terminated string 572@param[in] exist indicate if file pre-exist 573@param[in] src_file file name where func invoked 574@param[in] src_line line where the func invoked 575@return true if success */ 576UNIV_INLINE 577bool pfs_os_file_delete_if_exists_func(mysql_pfs_key_t key, const char *name, 578 bool *exist, const char *src_file, 579 uint src_line) { 580 PSI_file_locker_state state; 581 struct PSI_file_locker *locker = nullptr; 582 583 register_pfs_file_close_begin(&state, locker, key, PSI_FILE_DELETE, name, 584 src_file, src_line); 585 586 bool result = os_file_delete_if_exists_func(name, exist); 587 588 register_pfs_file_close_end(locker, 0); 589 590 return (result); 591} 592#endif /* UNIV_PFS_IO */ 593