1 /***********************************************************************
2
3 Copyright (c) 1995, 2017, Oracle and/or its affiliates. All Rights Reserved.
4 Copyright (c) 2009, Percona Inc.
5 Copyright (c) 2013, 2021, MariaDB Corporation.
6
7 Portions of this file contain modifications contributed and copyrighted
8 by Percona Inc.. Those modifications are
9 gratefully acknowledged and are described briefly in the InnoDB
10 documentation. The contributions by Percona Inc. are incorporated with
11 their permission, and subject to the conditions contained in the file
12 COPYING.Percona.
13
14 This program is free software; you can redistribute it and/or modify it
15 under the terms of the GNU General Public License as published by the
16 Free Software Foundation; version 2 of the License.
17
18 This program is distributed in the hope that it will be useful, but
19 WITHOUT ANY WARRANTY; without even the implied warranty of
20 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
21 Public License for more details.
22
23 You should have received a copy of the GNU General Public License along with
24 this program; if not, write to the Free Software Foundation, Inc.,
25 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335 USA
26
27 ***********************************************************************/
28
29 /**************************************************//**
30 @file include/os0file.h
31 The interface to the operating system file io
32
33 Created 10/21/1995 Heikki Tuuri
34 *******************************************************/
35
36 #ifndef os0file_h
37 #define os0file_h
38
39 #include "fsp0types.h"
40 #include "tpool.h"
41 #include "my_counter.h"
42
43 #ifndef _WIN32
44 #include <dirent.h>
45 #include <sys/stat.h>
46 #include <time.h>
47 #endif /* !_WIN32 */
48
49 extern bool os_has_said_disk_full;
50
51 /** File offset in bytes */
52 typedef ib_uint64_t os_offset_t;
53
54 #ifdef _WIN32
55
56 /** We define always WIN_ASYNC_IO, and check at run-time whether
57 the OS actually supports it: Win 95 does not, NT does. */
58 # define WIN_ASYNC_IO
59
60 /** Use unbuffered I/O */
61 # define UNIV_NON_BUFFERED_IO
62
63 /** File handle */
64 typedef native_file_handle os_file_t;
65
66
67 #else /* _WIN32 */
68
69 /** File handle */
70 typedef int os_file_t;
71
72 #endif /* _WIN32 */
73
74 static const os_file_t OS_FILE_CLOSED = IF_WIN(os_file_t(INVALID_HANDLE_VALUE),-1);
75
76 /** File descriptor with optional PERFORMANCE_SCHEMA instrumentation */
77 struct pfs_os_file_t
78 {
79 /** Default constructor */
m_filepfs_os_file_t80 pfs_os_file_t(os_file_t file = OS_FILE_CLOSED) : m_file(file)
81 #ifdef UNIV_PFS_IO
82 , m_psi(NULL)
83 #endif
84 {}
85
86 /** The wrapped file handle */
87 os_file_t m_file;
88 #ifdef UNIV_PFS_IO
89 /** PERFORMANCE_SCHEMA descriptor */
90 struct PSI_file *m_psi;
91 #endif
92 /** Implicit type conversion.
93 @return the wrapped file handle */
os_file_tpfs_os_file_t94 operator os_file_t() const { return m_file; }
95 /** Assignment operator.
96 @param[in] file file handle to be assigned */
97 void operator=(os_file_t file) { m_file = file; }
98 bool operator==(os_file_t file) const { return m_file == file; }
99 bool operator!=(os_file_t file) const { return !(*this == file); }
100 #ifndef DBUG_OFF
101 friend std::ostream& operator<<(std::ostream& os, pfs_os_file_t f){
102 os << os_file_t(f);
103 return os;
104 }
105 #endif
106 };
107
108 /** The next value should be smaller or equal to the smallest sector size used
109 on any disk. A log block is required to be a portion of disk which is written
110 so that if the start and the end of a block get written to disk, then the
111 whole block gets written. This should be true even in most cases of a crash:
112 if this fails for a log block, then it is equivalent to a media failure in the
113 log. */
114
115 #define OS_FILE_LOG_BLOCK_SIZE 512U
116
117 /** Options for os_file_create_func @{ */
118 enum os_file_create_t {
119 OS_FILE_OPEN = 51, /*!< to open an existing file (if
120 doesn't exist, error) */
121 OS_FILE_CREATE, /*!< to create new file (if
122 exists, error) */
123 OS_FILE_OVERWRITE, /*!< to create a new file, if exists
124 the overwrite old file */
125 OS_FILE_OPEN_RAW, /*!< to open a raw device or disk
126 partition */
127 OS_FILE_CREATE_PATH, /*!< to create the directories */
128 OS_FILE_OPEN_RETRY, /*!< open with retry */
129
130 /** Flags that can be combined with the above values. Please ensure
131 that the above values stay below 128. */
132
133 OS_FILE_ON_ERROR_NO_EXIT = 128, /*!< do not exit on unknown errors */
134 OS_FILE_ON_ERROR_SILENT = 256 /*!< don't print diagnostic messages to
135 the log unless it is a fatal error,
136 this flag is only used if
137 ON_ERROR_NO_EXIT is set */
138 };
139
140 static const ulint OS_FILE_READ_ONLY = 333;
141 static const ulint OS_FILE_READ_WRITE = 444;
142
143 /** Used by MySQLBackup */
144 static const ulint OS_FILE_READ_ALLOW_DELETE = 555;
145
146 /* Options for file_create */
147 static const ulint OS_FILE_AIO = 61;
148 static const ulint OS_FILE_NORMAL = 62;
149 /* @} */
150
151 /** Types for file create @{ */
152 static const ulint OS_DATA_FILE = 100;
153 static const ulint OS_LOG_FILE = 101;
154 static const ulint OS_DATA_FILE_NO_O_DIRECT = 103;
155 /* @} */
156
157 /** Error codes from os_file_get_last_error @{ */
158 static const ulint OS_FILE_NAME_TOO_LONG = 36;
159 static const ulint OS_FILE_NOT_FOUND = 71;
160 static const ulint OS_FILE_DISK_FULL = 72;
161 static const ulint OS_FILE_ALREADY_EXISTS = 73;
162 static const ulint OS_FILE_PATH_ERROR = 74;
163
164 /** wait for OS aio resources to become available again */
165 static const ulint OS_FILE_AIO_RESOURCES_RESERVED = 75;
166
167 static const ulint OS_FILE_SHARING_VIOLATION = 76;
168 static const ulint OS_FILE_ERROR_NOT_SPECIFIED = 77;
169 static const ulint OS_FILE_INSUFFICIENT_RESOURCE = 78;
170 static const ulint OS_FILE_AIO_INTERRUPTED = 79;
171 static const ulint OS_FILE_OPERATION_ABORTED = 80;
172 static const ulint OS_FILE_ACCESS_VIOLATION = 81;
173 static const ulint OS_FILE_OPERATION_NOT_SUPPORTED = 125;
174 static const ulint OS_FILE_ERROR_MAX = 200;
175 /* @} */
176
177 /**
178 The I/O context that is passed down to the low level IO code */
179 class IORequest
180 {
181 public:
182 enum Type
183 {
184 /** Synchronous read */
185 READ_SYNC= 2,
186 /** Asynchronous read; some errors will be ignored */
187 READ_ASYNC= READ_SYNC | 1,
188 /** Possibly partial read; only used with
189 os_file_read_no_error_handling() */
190 READ_MAYBE_PARTIAL= READ_SYNC | 4,
191 /** Read for doublewrite buffer recovery */
192 DBLWR_RECOVER= READ_SYNC | 8,
193 /** Synchronous write */
194 WRITE_SYNC= 16,
195 /** Asynchronous write */
196 WRITE_ASYNC= WRITE_SYNC | 1,
197 /** A doublewrite batch */
198 DBLWR_BATCH= WRITE_ASYNC | 8,
199 /** Write data; evict the block on write completion */
200 WRITE_LRU= WRITE_ASYNC | 32,
201 /** Write data and punch hole for the rest */
202 PUNCH= WRITE_ASYNC | 64,
203 /** Write data and punch hole; evict the block on write completion */
204 PUNCH_LRU= PUNCH | WRITE_LRU,
205 /** Zero out a range of bytes in fil_space_t::io() */
206 PUNCH_RANGE= WRITE_SYNC | 128,
207 };
208
IORequest(buf_page_t * bpage,fil_node_t * node,Type type)209 constexpr IORequest(buf_page_t *bpage, fil_node_t *node, Type type) :
210 bpage(bpage), node(node), type(type) {}
211
212 constexpr IORequest(Type type= READ_SYNC, buf_page_t *bpage= nullptr) :
bpage(bpage)213 bpage(bpage), type(type) {}
214
is_read()215 bool is_read() const { return (type & READ_SYNC) != 0; }
is_write()216 bool is_write() const { return (type & WRITE_SYNC) != 0; }
is_LRU()217 bool is_LRU() const { return (type & (WRITE_LRU ^ WRITE_ASYNC)) != 0; }
is_async()218 bool is_async() const { return (type & (READ_SYNC ^ READ_ASYNC)) != 0; }
219
220 /** If requested, free storage space associated with a section of the file.
221 @param off byte offset from the start (SEEK_SET)
222 @param len size of the hole in bytes
223 @return DB_SUCCESS or error code */
maybe_punch_hole(os_offset_t off,ulint len)224 dberr_t maybe_punch_hole(os_offset_t off, ulint len)
225 {
226 return off && len && node && (type & (PUNCH ^ WRITE_ASYNC))
227 ? punch_hole(off, len)
228 : DB_SUCCESS;
229 }
230
231 private:
232 /** Free storage space associated with a section of the file.
233 @param off byte offset from the start (SEEK_SET)
234 @param len size of the hole in bytes
235 @return DB_SUCCESS or error code */
236 dberr_t punch_hole(os_offset_t off, ulint len) const;
237
238 public:
239 /** Page to be written on write operation */
240 buf_page_t* const bpage= nullptr;
241
242 /** File descriptor */
243 fil_node_t *const node= nullptr;
244
245 /** Request type bit flags */
246 const Type type;
247 };
248
249 constexpr IORequest IORequestRead(IORequest::READ_SYNC);
250 constexpr IORequest IORequestReadPartial(IORequest::READ_MAYBE_PARTIAL);
251 constexpr IORequest IORequestWrite(IORequest::WRITE_SYNC);
252
253 /** Sparse file size information. */
254 struct os_file_size_t {
255 /** Total size of file in bytes */
256 os_offset_t m_total_size;
257
258 /** If it is a sparse file then this is the number of bytes
259 actually allocated for the file. */
260 os_offset_t m_alloc_size;
261 };
262
263 constexpr ulint OS_AIO_N_PENDING_IOS_PER_THREAD= 256;
264
265 extern Atomic_counter<ulint> os_n_file_reads;
266 extern ulint os_n_file_writes;
267 extern ulint os_n_fsyncs;
268
269 /* File types for directory entry data type */
270
271 enum os_file_type_t {
272 OS_FILE_TYPE_UNKNOWN = 0,
273 OS_FILE_TYPE_FILE, /* regular file */
274 OS_FILE_TYPE_DIR, /* directory */
275 OS_FILE_TYPE_LINK, /* symbolic link */
276 OS_FILE_TYPE_BLOCK /* block device */
277 };
278
279 /* Maximum path string length in bytes when referring to tables with in the
280 './databasename/tablename.ibd' path format; we can allocate at least 2 buffers
281 of this size from the thread stack; that is why this should not be made much
282 bigger than 4000 bytes. The maximum path length used by any storage engine
283 in the server must be at least this big. */
284
285 /* MySQL 5.7 my_global.h */
286 #ifndef FN_REFLEN_SE
287 #define FN_REFLEN_SE 4000
288 #endif
289
290 #define OS_FILE_MAX_PATH 4000
291 #if (FN_REFLEN_SE < OS_FILE_MAX_PATH)
292 # error "(FN_REFLEN_SE < OS_FILE_MAX_PATH)"
293 #endif
294
295 /** Struct used in fetching information of a file in a directory */
296 struct os_file_stat_t {
297 char name[OS_FILE_MAX_PATH]; /*!< path to a file */
298 os_file_type_t type; /*!< file type */
299 os_offset_t size; /*!< file size in bytes */
300 os_offset_t alloc_size; /*!< Allocated size for
301 sparse files in bytes */
302 size_t block_size; /*!< Block size to use for IO
303 in bytes*/
304 time_t ctime; /*!< creation time */
305 time_t mtime; /*!< modification time */
306 time_t atime; /*!< access time */
307 bool rw_perm; /*!< true if can be opened
308 in read-write mode. Only valid
309 if type == OS_FILE_TYPE_FILE */
310 };
311
312 /** Create a temporary file. This function is like tmpfile(3), but
313 the temporary file is created in the in the mysql server configuration
314 parameter (--tmpdir).
315 @return temporary file handle, or NULL on error */
316 FILE*
317 os_file_create_tmpfile();
318
319 /**
320 This function attempts to create a directory named pathname. The new directory
321 gets default permissions. On Unix, the permissions are (0770 & ~umask). If the
322 directory exists already, nothing is done and the call succeeds, unless the
323 fail_if_exists arguments is true.
324
325 @param[in] pathname directory name as null-terminated string
326 @param[in] fail_if_exists if true, pre-existing directory is treated
327 as an error.
328 @return true if call succeeds, false on error */
329 bool
330 os_file_create_directory(
331 const char* pathname,
332 bool fail_if_exists);
333
334 /** NOTE! Use the corresponding macro os_file_create_simple(), not directly
335 this function!
336 A simple function to open or create a file.
337 @param[in] name name of the file or path as a null-terminated
338 string
339 @param[in] create_mode create mode
340 @param[in] access_type OS_FILE_READ_ONLY or OS_FILE_READ_WRITE
341 @param[in] read_only if true read only mode checks are enforced
342 @param[out] success true if succeed, false if error
343 @return own: handle to the file, not defined if error, error number
344 can be retrieved with os_file_get_last_error */
345 pfs_os_file_t
346 os_file_create_simple_func(
347 const char* name,
348 ulint create_mode,
349 ulint access_type,
350 bool read_only,
351 bool* success);
352
353 /** NOTE! Use the corresponding macro
354 os_file_create_simple_no_error_handling(), not directly this function!
355 A simple function to open or create a file.
356 @param[in] name name of the file or path as a null-terminated string
357 @param[in] create_mode create mode
358 @param[in] access_type OS_FILE_READ_ONLY, OS_FILE_READ_WRITE, or
359 OS_FILE_READ_ALLOW_DELETE; the last option
360 is used by a backup program reading the file
361 @param[in] read_only if true read only mode checks are enforced
362 @param[out] success true if succeeded
363 @return own: handle to the file, not defined if error, error number
364 can be retrieved with os_file_get_last_error */
365 pfs_os_file_t
366 os_file_create_simple_no_error_handling_func(
367 const char* name,
368 ulint create_mode,
369 ulint access_type,
370 bool read_only,
371 bool* success)
372 MY_ATTRIBUTE((warn_unused_result));
373
374 #ifdef _WIN32
375 #define os_file_set_nocache(fd, file_name, operation_name) do{}while(0)
376 #else
377 /** Tries to disable OS caching on an opened file descriptor.
378 @param[in] fd file descriptor to alter
379 @param[in] file_name file name, used in the diagnostic message
380 @param[in] name "open" or "create"; used in the diagnostic
381 message */
382 void
383 os_file_set_nocache(
384 /*================*/
385 int fd, /*!< in: file descriptor to alter */
386 const char* file_name,
387 const char* operation_name);
388 #endif
389
390 /** NOTE! Use the corresponding macro os_file_create(), not directly
391 this function!
392 Opens an existing file or creates a new.
393 @param[in] name name of the file or path as a null-terminated
394 string
395 @param[in] create_mode create mode
396 @param[in] purpose OS_FILE_AIO, if asynchronous, non-buffered I/O
397 is desired, OS_FILE_NORMAL, if any normal file;
398 NOTE that it also depends on type, os_aio_..
399 and srv_.. variables whether we really use
400 async I/O or unbuffered I/O: look in the
401 function source code for the exact rules
402 @param[in] type OS_DATA_FILE or OS_LOG_FILE
403 @param[in] read_only if true read only mode checks are enforced
404 @param[in] success true if succeeded
405 @return own: handle to the file, not defined if error, error number
406 can be retrieved with os_file_get_last_error */
407 pfs_os_file_t
408 os_file_create_func(
409 const char* name,
410 ulint create_mode,
411 ulint purpose,
412 ulint type,
413 bool read_only,
414 bool* success)
415 MY_ATTRIBUTE((warn_unused_result));
416
417 /** Deletes a file. The file has to be closed before calling this.
418 @param[in] name file path as a null-terminated string
419 @return true if success */
420 bool
421 os_file_delete_func(const char* name);
422
423 /** Deletes a file if it exists. The file has to be closed before calling this.
424 @param[in] name file path as a null-terminated string
425 @param[out] exist indicate if file pre-exist
426 @return true if success */
427 bool
428 os_file_delete_if_exists_func(const char* name, bool* exist);
429
430 /** NOTE! Use the corresponding macro os_file_rename(), not directly
431 this function!
432 Renames a file (can also move it to another directory). It is safest that the
433 file is closed before calling this function.
434 @param[in] oldpath old file path as a null-terminated string
435 @param[in] newpath new file path
436 @return true if success */
437 bool
438 os_file_rename_func(const char* oldpath, const char* newpath);
439
440 /** NOTE! Use the corresponding macro os_file_close(), not directly this
441 function!
442 Closes a file handle. In case of error, error number can be retrieved with
443 os_file_get_last_error.
444 @param[in] file own: handle to a file
445 @return true if success */
446 bool os_file_close_func(os_file_t file);
447
448 #ifdef UNIV_PFS_IO
449
450 /* Keys to register InnoDB I/O with performance schema */
451 extern mysql_pfs_key_t innodb_data_file_key;
452 extern mysql_pfs_key_t innodb_log_file_key;
453 extern mysql_pfs_key_t innodb_temp_file_key;
454
455 /* Following four macros are instumentations to register
456 various file I/O operations with performance schema.
457 1) register_pfs_file_open_begin() and register_pfs_file_open_end() are
458 used to register file creation, opening, closing and renaming.
459 2) register_pfs_file_rename_begin() and register_pfs_file_rename_end()
460 are used to register file renaming
461 2) register_pfs_file_io_begin() and register_pfs_file_io_end() are
462 used to register actual file read, write and flush
463 3) register_pfs_file_close_begin() and register_pfs_file_close_end()
464 are used to register file deletion operations*/
465 # define register_pfs_file_open_begin(state, locker, key, op, name, \
466 src_file, src_line) \
467 do { \
468 locker = PSI_FILE_CALL(get_thread_file_name_locker)( \
469 state, key, op, name, &locker); \
470 if (locker != NULL) { \
471 PSI_FILE_CALL(start_file_open_wait)( \
472 locker, src_file, src_line); \
473 } \
474 } while (0)
475
476 # define register_pfs_file_open_end(locker, file, result) \
477 do { \
478 if (locker != NULL) { \
479 file.m_psi = PSI_FILE_CALL(end_file_open_wait)( \
480 locker, result); \
481 } \
482 } while (0)
483
484 # define register_pfs_file_rename_begin(state, locker, key, op, name, \
485 src_file, src_line) \
486 register_pfs_file_open_begin(state, locker, key, op, name, \
487 src_file, src_line) \
488
489 # define register_pfs_file_rename_end(locker, from, to, result) \
490 do { \
491 if (locker != NULL) { \
492 PSI_FILE_CALL( \
493 end_file_rename_wait)( \
494 locker, from, to, result); \
495 } \
496 } while (0)
497
498 # define register_pfs_file_close_begin(state, locker, key, op, name, \
499 src_file, src_line) \
500 do { \
501 locker = PSI_FILE_CALL(get_thread_file_name_locker)( \
502 state, key, op, name, &locker); \
503 if (locker != NULL) { \
504 PSI_FILE_CALL(start_file_close_wait)( \
505 locker, src_file, src_line); \
506 } \
507 } while (0)
508
509 # define register_pfs_file_close_end(locker, result) \
510 do { \
511 if (locker != NULL) { \
512 PSI_FILE_CALL(end_file_close_wait)( \
513 locker, result); \
514 } \
515 } while (0)
516
517 # define register_pfs_file_io_begin(state, locker, file, count, op, \
518 src_file, src_line) \
519 do { \
520 locker = PSI_FILE_CALL(get_thread_file_stream_locker)( \
521 state, file.m_psi, op); \
522 if (locker != NULL) { \
523 PSI_FILE_CALL(start_file_wait)( \
524 locker, count, src_file, src_line); \
525 } \
526 } while (0)
527
528 # define register_pfs_file_io_end(locker, count) \
529 do { \
530 if (locker != NULL) { \
531 PSI_FILE_CALL(end_file_wait)(locker, count); \
532 } \
533 } while (0)
534
535 /* Following macros/functions are file I/O APIs that would be performance
536 schema instrumented if "UNIV_PFS_IO" is defined. They would point to
537 wrapper functions with performance schema instrumentation in such case.
538
539 os_file_create
540 os_file_create_simple
541 os_file_create_simple_no_error_handling
542 os_file_close
543 os_file_rename
544 os_aio
545 os_file_read
546 os_file_read_no_error_handling
547 os_file_write
548
549 The wrapper functions have the prefix of "innodb_". */
550
551 # define os_file_create(key, name, create, purpose, type, read_only, \
552 success) \
553 pfs_os_file_create_func(key, name, create, purpose, type, \
554 read_only, success, __FILE__, __LINE__)
555
556 # define os_file_create_simple(key, name, create, access, \
557 read_only, success) \
558 pfs_os_file_create_simple_func(key, name, create, access, \
559 read_only, success, __FILE__, __LINE__)
560
561 # define os_file_create_simple_no_error_handling( \
562 key, name, create_mode, access, read_only, success) \
563 pfs_os_file_create_simple_no_error_handling_func( \
564 key, name, create_mode, access, \
565 read_only, success, __FILE__, __LINE__)
566
567 # define os_file_close(file) \
568 pfs_os_file_close_func(file, __FILE__, __LINE__)
569
570 # define os_file_read(type, file, buf, offset, n) \
571 pfs_os_file_read_func(type, file, buf, offset, n, __FILE__, __LINE__)
572
573 # define os_file_read_no_error_handling(type, file, buf, offset, n, o) \
574 pfs_os_file_read_no_error_handling_func( \
575 type, file, buf, offset, n, o, __FILE__, __LINE__)
576
577 # define os_file_write(type, name, file, buf, offset, n) \
578 pfs_os_file_write_func(type, name, file, buf, offset, \
579 n, __FILE__, __LINE__)
580
581 # define os_file_flush(file) \
582 pfs_os_file_flush_func(file, __FILE__, __LINE__)
583
584 # define os_file_rename(key, oldpath, newpath) \
585 pfs_os_file_rename_func(key, oldpath, newpath, __FILE__, __LINE__)
586
587 # define os_file_delete(key, name) \
588 pfs_os_file_delete_func(key, name, __FILE__, __LINE__)
589
590 # define os_file_delete_if_exists(key, name, exist) \
591 pfs_os_file_delete_if_exists_func(key, name, exist, __FILE__, __LINE__)
592
593 /** NOTE! Please use the corresponding macro os_file_create_simple(),
594 not directly this function!
595 A performance schema instrumented wrapper function for
596 os_file_create_simple() which opens or creates a file.
597 @param[in] key Performance Schema Key
598 @param[in] name name of the file or path as a null-terminated
599 string
600 @param[in] create_mode create mode
601 @param[in] access_type OS_FILE_READ_ONLY or OS_FILE_READ_WRITE
602 @param[in] read_only if true read only mode checks are enforced
603 @param[out] success true if succeeded
604 @param[in] src_file file name where func invoked
605 @param[in] src_line line where the func invoked
606 @return own: handle to the file, not defined if error, error number
607 can be retrieved with os_file_get_last_error */
608 UNIV_INLINE
609 pfs_os_file_t
610 pfs_os_file_create_simple_func(
611 mysql_pfs_key_t key,
612 const char* name,
613 ulint create_mode,
614 ulint access_type,
615 bool read_only,
616 bool* success,
617 const char* src_file,
618 uint src_line)
619 MY_ATTRIBUTE((warn_unused_result));
620
621 /** NOTE! Please use the corresponding macro
622 os_file_create_simple_no_error_handling(), not directly this function!
623 A performance schema instrumented wrapper function for
624 os_file_create_simple_no_error_handling(). Add instrumentation to
625 monitor file creation/open.
626 @param[in] key Performance Schema Key
627 @param[in] name name of the file or path as a null-terminated
628 string
629 @param[in] create_mode create mode
630 @param[in] access_type OS_FILE_READ_ONLY, OS_FILE_READ_WRITE, or
631 OS_FILE_READ_ALLOW_DELETE; the last option is
632 used by a backup program reading the file
633 @param[in] read_only if true read only mode checks are enforced
634 @param[out] success true if succeeded
635 @param[in] src_file file name where func invoked
636 @param[in] src_line line where the func invoked
637 @return own: handle to the file, not defined if error, error number
638 can be retrieved with os_file_get_last_error */
639 UNIV_INLINE
640 pfs_os_file_t
641 pfs_os_file_create_simple_no_error_handling_func(
642 mysql_pfs_key_t key,
643 const char* name,
644 ulint create_mode,
645 ulint access_type,
646 bool read_only,
647 bool* success,
648 const char* src_file,
649 uint src_line)
650 MY_ATTRIBUTE((warn_unused_result));
651
652 /** NOTE! Please use the corresponding macro os_file_create(), not directly
653 this function!
654 A performance schema wrapper function for os_file_create().
655 Add instrumentation to monitor file creation/open.
656 @param[in] key Performance Schema Key
657 @param[in] name name of the file or path as a null-terminated
658 string
659 @param[in] create_mode create mode
660 @param[in] purpose OS_FILE_AIO, if asynchronous, non-buffered I/O
661 is desired, OS_FILE_NORMAL, if any normal file;
662 NOTE that it also depends on type, os_aio_..
663 and srv_.. variables whether we really use
664 async I/O or unbuffered I/O: look in the
665 function source code for the exact rules
666 @param[in] read_only if true read only mode checks are enforced
667 @param[out] success true if succeeded
668 @param[in] src_file file name where func invoked
669 @param[in] src_line line where the func invoked
670 @return own: handle to the file, not defined if error, error number
671 can be retrieved with os_file_get_last_error */
672 UNIV_INLINE
673 pfs_os_file_t
674 pfs_os_file_create_func(
675 mysql_pfs_key_t key,
676 const char* name,
677 ulint create_mode,
678 ulint purpose,
679 ulint type,
680 bool read_only,
681 bool* success,
682 const char* src_file,
683 uint src_line)
684 MY_ATTRIBUTE((warn_unused_result));
685
686 /** NOTE! Please use the corresponding macro os_file_close(), not directly
687 this function!
688 A performance schema instrumented wrapper function for os_file_close().
689 @param[in] file handle to a file
690 @param[in] src_file file name where func invoked
691 @param[in] src_line line where the func invoked
692 @return true if success */
693 UNIV_INLINE
694 bool
695 pfs_os_file_close_func(
696 pfs_os_file_t file,
697 const char* src_file,
698 uint src_line);
699
700 /** NOTE! Please use the corresponding macro os_file_read(), not directly
701 this function!
702 This is the performance schema instrumented wrapper function for
703 os_file_read() which requests a synchronous read operation.
704 @param[in] type IO request context
705 @param[in] file Open file handle
706 @param[out] buf buffer where to read
707 @param[in] offset file offset where to read
708 @param[in] n number of bytes to read
709 @param[in] src_file file name where func invoked
710 @param[in] src_line line where the func invoked
711 @return DB_SUCCESS if request was successful */
712 UNIV_INLINE
713 dberr_t
714 pfs_os_file_read_func(
715 const IORequest& type,
716 pfs_os_file_t file,
717 void* buf,
718 os_offset_t offset,
719 ulint n,
720 const char* src_file,
721 uint src_line);
722
723 /** NOTE! Please use the corresponding macro os_file_read_no_error_handling(),
724 not directly this function!
725 This is the performance schema instrumented wrapper function for
726 os_file_read_no_error_handling_func() which requests a synchronous
727 read operation.
728 @param[in] type IO request context
729 @param[in] file Open file handle
730 @param[out] buf buffer where to read
731 @param[in] offset file offset where to read
732 @param[in] n number of bytes to read
733 @param[out] o number of bytes actually read
734 @param[in] src_file file name where func invoked
735 @param[in] src_line line where the func invoked
736 @return DB_SUCCESS if request was successful */
737 UNIV_INLINE
738 dberr_t
739 pfs_os_file_read_no_error_handling_func(
740 const IORequest& type,
741 pfs_os_file_t file,
742 void* buf,
743 os_offset_t offset,
744 ulint n,
745 ulint* o,
746 const char* src_file,
747 uint src_line);
748
749 /** NOTE! Please use the corresponding macro os_file_write(), not directly
750 this function!
751 This is the performance schema instrumented wrapper function for
752 os_file_write() which requests a synchronous write operation.
753 @param[in] type IO request context
754 @param[in] name Name of the file or path as NUL terminated
755 string
756 @param[in] file Open file handle
757 @param[out] buf buffer where to read
758 @param[in] offset file offset where to read
759 @param[in] n number of bytes to read
760 @param[in] src_file file name where func invoked
761 @param[in] src_line line where the func invoked
762 @return DB_SUCCESS if request was successful */
763 UNIV_INLINE
764 dberr_t
765 pfs_os_file_write_func(
766 const IORequest& type,
767 const char* name,
768 pfs_os_file_t file,
769 const void* buf,
770 os_offset_t offset,
771 ulint n,
772 const char* src_file,
773 uint src_line);
774
775 /** NOTE! Please use the corresponding macro os_file_flush(), not directly
776 this function!
777 This is the performance schema instrumented wrapper function for
778 os_file_flush() which flushes the write buffers of a given file to the disk.
779 Flushes the write buffers of a given file to the disk.
780 @param[in] file Open file handle
781 @param[in] src_file file name where func invoked
782 @param[in] src_line line where the func invoked
783 @return TRUE if success */
784 UNIV_INLINE
785 bool
786 pfs_os_file_flush_func(
787 pfs_os_file_t file,
788 const char* src_file,
789 uint src_line);
790
791
792 /** NOTE! Please use the corresponding macro os_file_rename(), not directly
793 this function!
794 This is the performance schema instrumented wrapper function for
795 os_file_rename()
796 @param[in] key Performance Schema Key
797 @param[in] oldpath old file path as a null-terminated string
798 @param[in] newpath new file path
799 @param[in] src_file file name where func invoked
800 @param[in] src_line line where the func invoked
801 @return true if success */
802 UNIV_INLINE
803 bool
804 pfs_os_file_rename_func(
805 mysql_pfs_key_t key,
806 const char* oldpath,
807 const char* newpath,
808 const char* src_file,
809 uint src_line);
810
811 /**
812 NOTE! Please use the corresponding macro os_file_delete(), not directly
813 this function!
814 This is the performance schema instrumented wrapper function for
815 os_file_delete()
816 @param[in] key Performance Schema Key
817 @param[in] name old file path as a null-terminated string
818 @param[in] src_file file name where func invoked
819 @param[in] src_line line where the func invoked
820 @return true if success */
821 UNIV_INLINE
822 bool
823 pfs_os_file_delete_func(
824 mysql_pfs_key_t key,
825 const char* name,
826 const char* src_file,
827 uint src_line);
828
829 /**
830 NOTE! Please use the corresponding macro os_file_delete_if_exists(), not
831 directly this function!
832 This is the performance schema instrumented wrapper function for
833 os_file_delete_if_exists()
834 @param[in] key Performance Schema Key
835 @param[in] name old file path as a null-terminated string
836 @param[in] exist indicate if file pre-exist
837 @param[in] src_file file name where func invoked
838 @param[in] src_line line where the func invoked
839 @return true if success */
840 UNIV_INLINE
841 bool
842 pfs_os_file_delete_if_exists_func(
843 mysql_pfs_key_t key,
844 const char* name,
845 bool* exist,
846 const char* src_file,
847 uint src_line);
848
849 #else /* UNIV_PFS_IO */
850
851 /* If UNIV_PFS_IO is not defined, these I/O APIs point
852 to original un-instrumented file I/O APIs */
853 # define os_file_create(key, name, create, purpose, type, read_only, \
854 success) \
855 os_file_create_func(name, create, purpose, type, read_only, \
856 success)
857
858 # define os_file_create_simple(key, name, create_mode, access, \
859 read_only, success) \
860 os_file_create_simple_func(name, create_mode, access, \
861 read_only, success)
862
863 # define os_file_create_simple_no_error_handling( \
864 key, name, create_mode, access, read_only, success) \
865 os_file_create_simple_no_error_handling_func( \
866 name, create_mode, access, read_only, success)
867
868 # define os_file_close(file) os_file_close_func(file)
869
870 # define os_file_read(type, file, buf, offset, n) \
871 os_file_read_func(type, file, buf, offset, n)
872
873 # define os_file_read_no_error_handling(type, file, buf, offset, n, o) \
874 os_file_read_no_error_handling_func(type, file, buf, offset, n, o)
875
876 # define os_file_write(type, name, file, buf, offset, n) \
877 os_file_write_func(type, name, file, buf, offset, n)
878
879 # define os_file_flush(file) os_file_flush_func(file)
880
881 # define os_file_rename(key, oldpath, newpath) \
882 os_file_rename_func(oldpath, newpath)
883
884 # define os_file_delete(key, name) os_file_delete_func(name)
885
886 # define os_file_delete_if_exists(key, name, exist) \
887 os_file_delete_if_exists_func(name, exist)
888
889 #endif /* UNIV_PFS_IO */
890
891 /** Gets a file size.
892 @param[in] file handle to a file
893 @return file size if OK, else set m_total_size to ~0 and m_alloc_size
894 to errno */
895 os_file_size_t
896 os_file_get_size(
897 const char* filename)
898 MY_ATTRIBUTE((warn_unused_result));
899
900 /** Gets a file size.
901 @param[in] file handle to a file
902 @return file size, or (os_offset_t) -1 on failure */
903 os_offset_t
904 os_file_get_size(
905 os_file_t file)
906 MY_ATTRIBUTE((warn_unused_result));
907
908 /** Extend a file.
909
910 On Windows, extending a file allocates blocks for the file,
911 unless the file is sparse.
912
913 On Unix, we will extend the file with ftruncate(), if
914 file needs to be sparse. Otherwise posix_fallocate() is used
915 when available, and if not, binary zeroes are added to the end
916 of file.
917
918 @param[in] name file name
919 @param[in] file file handle
920 @param[in] size desired file size
921 @param[in] sparse whether to create a sparse file (no preallocating)
922 @return whether the operation succeeded */
923 bool
924 os_file_set_size(
925 const char* name,
926 os_file_t file,
927 os_offset_t size,
928 bool is_sparse = false)
929 MY_ATTRIBUTE((warn_unused_result));
930
931 /** Truncates a file at its current position.
932 @param[in/out] file file to be truncated
933 @return true if success */
934 bool
935 os_file_set_eof(
936 FILE* file); /*!< in: file to be truncated */
937
938 /** Truncate a file to a specified size in bytes.
939 @param[in] pathname file path
940 @param[in] file file to be truncated
941 @param[in] size size preserved in bytes
942 @param[in] allow_shrink whether to allow the file to become smaller
943 @return true if success */
944 bool
945 os_file_truncate(
946 const char* pathname,
947 os_file_t file,
948 os_offset_t size,
949 bool allow_shrink = false);
950
951 /** NOTE! Use the corresponding macro os_file_flush(), not directly this
952 function!
953 Flushes the write buffers of a given file to the disk.
954 @param[in] file handle to a file
955 @return true if success */
956 bool
957 os_file_flush_func(
958 os_file_t file);
959
960 /** Retrieves the last error number if an error occurs in a file io function.
961 The number should be retrieved before any other OS calls (because they may
962 overwrite the error number). If the number is not known to this program,
963 the OS error number + 100 is returned.
964 @param[in] report true if we want an error message printed
965 for all errors
966 @return error number, or OS error number + 100 */
967 ulint
968 os_file_get_last_error(
969 bool report);
970
971 /** NOTE! Use the corresponding macro os_file_read(), not directly this
972 function!
973 Requests a synchronous read operation.
974 @param[in] type IO request context
975 @param[in] file Open file handle
976 @param[out] buf buffer where to read
977 @param[in] offset file offset where to read
978 @param[in] n number of bytes to read
979 @return DB_SUCCESS if request was successful */
980 dberr_t
981 os_file_read_func(
982 const IORequest& type,
983 os_file_t file,
984 void* buf,
985 os_offset_t offset,
986 ulint n)
987 MY_ATTRIBUTE((warn_unused_result));
988
989 /** Rewind file to its start, read at most size - 1 bytes from it to str, and
990 NUL-terminate str. All errors are silently ignored. This function is
991 mostly meant to be used with temporary files.
992 @param[in,out] file file to read from
993 @param[in,out] str buffer where to read
994 @param[in] size size of buffer */
995 void
996 os_file_read_string(
997 FILE* file,
998 char* str,
999 ulint size);
1000
1001 /** NOTE! Use the corresponding macro os_file_read_no_error_handling(),
1002 not directly this function!
1003 Requests a synchronous positioned read operation. This function does not do
1004 any error handling. In case of error it returns FALSE.
1005 @param[in] type IO request context
1006 @param[in] file Open file handle
1007 @param[out] buf buffer where to read
1008 @param[in] offset file offset where to read
1009 @param[in] n number of bytes to read
1010 @param[out] o number of bytes actually read
1011 @return DB_SUCCESS or error code */
1012 dberr_t
1013 os_file_read_no_error_handling_func(
1014 const IORequest& type,
1015 os_file_t file,
1016 void* buf,
1017 os_offset_t offset,
1018 ulint n,
1019 ulint* o)
1020 MY_ATTRIBUTE((warn_unused_result));
1021
1022 /** NOTE! Use the corresponding macro os_file_write(), not directly this
1023 function!
1024 Requests a synchronous write operation.
1025 @param[in] type IO request context
1026 @param[in] file Open file handle
1027 @param[out] buf buffer where to read
1028 @param[in] offset file offset where to read
1029 @param[in] n number of bytes to read
1030 @return DB_SUCCESS if request was successful */
1031 dberr_t
1032 os_file_write_func(
1033 const IORequest& type,
1034 const char* name,
1035 os_file_t file,
1036 const void* buf,
1037 os_offset_t offset,
1038 ulint n)
1039 MY_ATTRIBUTE((warn_unused_result));
1040
1041 /** Check the existence and type of the given file.
1042 @param[in] path pathname of the file
1043 @param[out] exists true if file exists
1044 @param[out] type type of the file (if it exists)
1045 @return true if call succeeded */
1046 bool
1047 os_file_status(
1048 const char* path,
1049 bool* exists,
1050 os_file_type_t* type);
1051
1052 /** This function returns a new path name after replacing the basename
1053 in an old path with a new basename. The old_path is a full path
1054 name including the extension. The tablename is in the normal
1055 form "databasename/tablename". The new base name is found after
1056 the forward slash. Both input strings are null terminated.
1057
1058 This function allocates memory to be returned. It is the callers
1059 responsibility to free the return value after it is no longer needed.
1060
1061 @param[in] old_path pathname
1062 @param[in] new_name new file name
1063 @return own: new full pathname */
1064 char*
1065 os_file_make_new_pathname(
1066 const char* old_path,
1067 const char* new_name);
1068
1069 /** This function reduces a null-terminated full remote path name into
1070 the path that is sent by MySQL for DATA DIRECTORY clause. It replaces
1071 the 'databasename/tablename.ibd' found at the end of the path with just
1072 'tablename'.
1073
1074 Since the result is always smaller than the path sent in, no new memory
1075 is allocated. The caller should allocate memory for the path sent in.
1076 This function manipulates that path in place.
1077
1078 If the path format is not as expected, just return. The result is used
1079 to inform a SHOW CREATE TABLE command.
1080 @param[in,out] data_dir_path Full path/data_dir_path */
1081 void
1082 os_file_make_data_dir_path(
1083 char* data_dir_path);
1084
1085 /** Create all missing subdirectories along the given path.
1086 @return DB_SUCCESS if OK, otherwise error code. */
1087 dberr_t
1088 os_file_create_subdirs_if_needed(
1089 const char* path);
1090
1091 #ifdef UNIV_ENABLE_UNIT_TEST_GET_PARENT_DIR
1092 /* Test the function os_file_get_parent_dir. */
1093 void
1094 unit_test_os_file_get_parent_dir();
1095 #endif /* UNIV_ENABLE_UNIT_TEST_GET_PARENT_DIR */
1096
1097 /**
1098 Initializes the asynchronous io system. */
1099 int os_aio_init();
1100
1101 /**
1102 Frees the asynchronous io system. */
1103 void os_aio_free();
1104
1105 /** Request a read or write.
1106 @param type I/O request
1107 @param buf buffer
1108 @param offset file offset
1109 @param n number of bytes
1110 @retval DB_SUCCESS if request was queued successfully
1111 @retval DB_IO_ERROR on I/O error */
1112 dberr_t os_aio(const IORequest &type, void *buf, os_offset_t offset, size_t n);
1113
1114 /** Wait until there are no pending asynchronous writes. */
1115 void os_aio_wait_until_no_pending_writes();
1116
1117
1118 /** Wait until there are no pending asynchronous reads. */
1119 void os_aio_wait_until_no_pending_reads();
1120
1121
1122 /** Prints info of the aio arrays.
1123 @param[in/out] file file where to print */
1124 void
1125 os_aio_print(FILE* file);
1126
1127 /** Refreshes the statistics used to print per-second averages. */
1128 void
1129 os_aio_refresh_stats();
1130
1131 /** Checks that all slots in the system have been freed, that is, there are
1132 no pending io operations. */
1133 bool
1134 os_aio_all_slots_free();
1135
1136
1137 /** This function returns information about the specified file
1138 @param[in] path pathname of the file
1139 @param[in] stat_info information of a file in a directory
1140 @param[in] check_rw_perm for testing whether the file can be opened
1141 in RW mode
1142 @param[in] read_only if true read only mode checks are enforced
1143 @return DB_SUCCESS if all OK */
1144 dberr_t
1145 os_file_get_status(
1146 const char* path,
1147 os_file_stat_t* stat_info,
1148 bool check_rw_perm,
1149 bool read_only);
1150
1151 /** Set the file create umask
1152 @param[in] umask The umask to use for file creation. */
1153 void
1154 os_file_set_umask(ulint umask);
1155
1156 #ifdef _WIN32
1157
1158 /**
1159 Make file sparse, on Windows.
1160
1161 @param[in] file file handle
1162 @param[in] is_sparse if true, make file sparse,
1163 otherwise "unsparse" the file
1164 @return true on success, false on error */
1165 bool os_file_set_sparse_win32(os_file_t file, bool is_sparse = true);
1166
1167 /**
1168 Changes file size on Windows
1169
1170 If file is extended, following happens the bytes between
1171 old and new EOF are zeros.
1172
1173 If file is sparse, "virtual" block is added at the end of
1174 allocated area.
1175
1176 If file is normal, file system allocates storage.
1177
1178 @param[in] pathname file path
1179 @param[in] file file handle
1180 @param[in] size size to preserve in bytes
1181 @return true if success */
1182 bool
1183 os_file_change_size_win32(
1184 const char* pathname,
1185 os_file_t file,
1186 os_offset_t size);
1187
1188 #endif /*_WIN32 */
1189
1190 /** Free storage space associated with a section of the file.
1191 @param[in] fh Open file handle
1192 @param[in] off Starting offset (SEEK_SET)
1193 @param[in] len Size of the hole
1194 @return DB_SUCCESS or error code */
1195 dberr_t
1196 os_file_punch_hole(
1197 os_file_t fh,
1198 os_offset_t off,
1199 os_offset_t len)
1200 MY_ATTRIBUTE((warn_unused_result));
1201
1202 /** Normalizes a directory path for the current OS:
1203 On Windows, we convert '/' to '\', else we convert '\' to '/'.
1204 @param[in,out] str A null-terminated directory and file path */
1205 void os_normalize_path(char* str);
1206
1207 /* Determine if a path is an absolute path or not.
1208 @param[in] OS directory or file path to evaluate
1209 @retval true if an absolute path
1210 @retval false if a relative path */
1211 UNIV_INLINE
1212 bool
is_absolute_path(const char * path)1213 is_absolute_path(
1214 const char* path)
1215 {
1216 if (path[0] == OS_PATH_SEPARATOR) {
1217 return(true);
1218 }
1219
1220 #ifdef _WIN32
1221 if (path[1] == ':' && path[2] == OS_PATH_SEPARATOR) {
1222 return(true);
1223 }
1224 #endif /* _WIN32 */
1225
1226 return(false);
1227 }
1228
1229 #include "os0file.inl"
1230
1231 #endif /* os0file_h */
1232