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