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, 2017, 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, Suite 500, 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 "page0size.h" |
40 | #include "os0api.h" |
41 | |
42 | #ifndef _WIN32 |
43 | #include <dirent.h> |
44 | #include <sys/stat.h> |
45 | #include <time.h> |
46 | #endif /* !_WIN32 */ |
47 | |
48 | /** File node of a tablespace or the log data space */ |
49 | struct fil_node_t; |
50 | struct fil_space_t; |
51 | |
52 | extern bool os_has_said_disk_full; |
53 | |
54 | /** File offset in bytes */ |
55 | typedef ib_uint64_t os_offset_t; |
56 | |
57 | #ifdef _WIN32 |
58 | |
59 | typedef HANDLE os_file_dir_t; /*!< directory stream */ |
60 | |
61 | /** We define always WIN_ASYNC_IO, and check at run-time whether |
62 | the OS actually supports it: Win 95 does not, NT does. */ |
63 | # define WIN_ASYNC_IO |
64 | |
65 | /** Use unbuffered I/O */ |
66 | # define UNIV_NON_BUFFERED_IO |
67 | |
68 | /** File handle */ |
69 | typedef HANDLE os_file_t; |
70 | |
71 | |
72 | #else /* _WIN32 */ |
73 | |
74 | typedef DIR* os_file_dir_t; /*!< directory stream */ |
75 | |
76 | /** File handle */ |
77 | typedef int os_file_t; |
78 | |
79 | #endif /* _WIN32 */ |
80 | |
81 | static const os_file_t OS_FILE_CLOSED = IF_WIN(os_file_t(INVALID_HANDLE_VALUE),-1); |
82 | |
83 | /** File descriptor with optional PERFORMANCE_SCHEMA instrumentation */ |
84 | struct pfs_os_file_t |
85 | { |
86 | /** Default constructor */ |
87 | pfs_os_file_t(os_file_t file = OS_FILE_CLOSED) : m_file(file) |
88 | #ifdef UNIV_PFS_IO |
89 | , m_psi(NULL) |
90 | #endif |
91 | {} |
92 | |
93 | /** The wrapped file handle */ |
94 | os_file_t m_file; |
95 | #ifdef UNIV_PFS_IO |
96 | /** PERFORMANCE_SCHEMA descriptor */ |
97 | struct PSI_file *m_psi; |
98 | #endif |
99 | /** Implicit type conversion. |
100 | @return the wrapped file handle */ |
101 | operator os_file_t() const { return m_file; } |
102 | /** Assignment operator. |
103 | @param[in] file file handle to be assigned */ |
104 | void operator=(os_file_t file) { m_file = file; } |
105 | }; |
106 | |
107 | /** The next value should be smaller or equal to the smallest sector size used |
108 | on any disk. A log block is required to be a portion of disk which is written |
109 | so that if the start and the end of a block get written to disk, then the |
110 | whole block gets written. This should be true even in most cases of a crash: |
111 | if this fails for a log block, then it is equivalent to a media failure in the |
112 | log. */ |
113 | |
114 | #define OS_FILE_LOG_BLOCK_SIZE 512U |
115 | |
116 | /** Options for os_file_create_func @{ */ |
117 | enum os_file_create_t { |
118 | OS_FILE_OPEN = 51, /*!< to open an existing file (if |
119 | doesn't exist, error) */ |
120 | OS_FILE_CREATE, /*!< to create new file (if |
121 | exists, error) */ |
122 | OS_FILE_OVERWRITE, /*!< to create a new file, if exists |
123 | the overwrite old file */ |
124 | OS_FILE_OPEN_RAW, /*!< to open a raw device or disk |
125 | partition */ |
126 | OS_FILE_CREATE_PATH, /*!< to create the directories */ |
127 | OS_FILE_OPEN_RETRY, /*!< open with retry */ |
128 | |
129 | /** Flags that can be combined with the above values. Please ensure |
130 | that the above values stay below 128. */ |
131 | |
132 | OS_FILE_ON_ERROR_NO_EXIT = 128, /*!< do not exit on unknown errors */ |
133 | OS_FILE_ON_ERROR_SILENT = 256 /*!< don't print diagnostic messages to |
134 | the log unless it is a fatal error, |
135 | this flag is only used if |
136 | ON_ERROR_NO_EXIT is set */ |
137 | }; |
138 | |
139 | static const ulint OS_FILE_READ_ONLY = 333; |
140 | static const ulint OS_FILE_READ_WRITE = 444; |
141 | |
142 | /** Used by MySQLBackup */ |
143 | static const ulint OS_FILE_READ_ALLOW_DELETE = 555; |
144 | |
145 | /* Options for file_create */ |
146 | static const ulint OS_FILE_AIO = 61; |
147 | static const ulint OS_FILE_NORMAL = 62; |
148 | /* @} */ |
149 | |
150 | /** Types for file create @{ */ |
151 | static const ulint OS_DATA_FILE = 100; |
152 | static const ulint OS_LOG_FILE = 101; |
153 | static const ulint OS_DATA_TEMP_FILE = 102; |
154 | /* @} */ |
155 | |
156 | /** Error codes from os_file_get_last_error @{ */ |
157 | static const ulint OS_FILE_NAME_TOO_LONG = 36; |
158 | static const ulint OS_FILE_NOT_FOUND = 71; |
159 | static const ulint OS_FILE_DISK_FULL = 72; |
160 | static const ulint OS_FILE_ALREADY_EXISTS = 73; |
161 | static const ulint OS_FILE_PATH_ERROR = 74; |
162 | |
163 | /** wait for OS aio resources to become available again */ |
164 | static const ulint OS_FILE_AIO_RESOURCES_RESERVED = 75; |
165 | |
166 | static const ulint OS_FILE_SHARING_VIOLATION = 76; |
167 | static const ulint OS_FILE_ERROR_NOT_SPECIFIED = 77; |
168 | static const ulint OS_FILE_INSUFFICIENT_RESOURCE = 78; |
169 | static const ulint OS_FILE_AIO_INTERRUPTED = 79; |
170 | static const ulint OS_FILE_OPERATION_ABORTED = 80; |
171 | static const ulint OS_FILE_ACCESS_VIOLATION = 81; |
172 | static const ulint OS_FILE_OPERATION_NOT_SUPPORTED = 125; |
173 | static const ulint OS_FILE_ERROR_MAX = 200; |
174 | /* @} */ |
175 | |
176 | /** Types for AIO operations @{ */ |
177 | |
178 | /** No transformations during read/write, write as is. */ |
179 | #define IORequestRead IORequest(IORequest::READ) |
180 | #define IORequestWrite IORequest(IORequest::WRITE) |
181 | #define IORequestLogRead IORequest(IORequest::LOG | IORequest::READ) |
182 | #define IORequestLogWrite IORequest(IORequest::LOG | IORequest::WRITE) |
183 | |
184 | |
185 | |
186 | /** |
187 | The IO Context that is passed down to the low level IO code */ |
188 | class IORequest { |
189 | public: |
190 | /** Flags passed in the request, they can be ORred together. */ |
191 | enum { |
192 | READ = 1, |
193 | WRITE = 2, |
194 | |
195 | /** Double write buffer recovery. */ |
196 | DBLWR_RECOVER = 4, |
197 | |
198 | /** Enumarations below can be ORed to READ/WRITE above*/ |
199 | |
200 | /** Data file */ |
201 | DATA_FILE = 8, |
202 | |
203 | /** Log file request*/ |
204 | LOG = 16, |
205 | |
206 | /** Disable partial read warnings */ |
207 | DISABLE_PARTIAL_IO_WARNINGS = 32, |
208 | |
209 | /** Do not to wake i/o-handler threads, but the caller will do |
210 | the waking explicitly later, in this way the caller can post |
211 | several requests in a batch; NOTE that the batch must not be |
212 | so big that it exhausts the slots in AIO arrays! NOTE that |
213 | a simulated batch may introduce hidden chances of deadlocks, |
214 | because I/Os are not actually handled until all |
215 | have been posted: use with great caution! */ |
216 | DO_NOT_WAKE = 64, |
217 | |
218 | /** Ignore failed reads of non-existent pages */ |
219 | IGNORE_MISSING = 128, |
220 | |
221 | /** Use punch hole if available*/ |
222 | PUNCH_HOLE = 256, |
223 | }; |
224 | |
225 | /** Default constructor */ |
226 | IORequest() |
227 | : |
228 | m_bpage(NULL), |
229 | m_fil_node(NULL), |
230 | m_type(READ) |
231 | { |
232 | /* No op */ |
233 | } |
234 | |
235 | /** |
236 | @param[in] type Request type, can be a value that is |
237 | ORed from the above enum */ |
238 | explicit IORequest(ulint type) |
239 | : |
240 | m_bpage(NULL), |
241 | m_fil_node(NULL), |
242 | m_type(static_cast<uint16_t>(type)) |
243 | { |
244 | if (!is_punch_hole_supported()) { |
245 | clear_punch_hole(); |
246 | } |
247 | } |
248 | |
249 | /** |
250 | @param[in] type Request type, can be a value that is |
251 | ORed from the above enum |
252 | @param[in] bpage Page to be written */ |
253 | IORequest(ulint type, buf_page_t* bpage) |
254 | : |
255 | m_bpage(bpage), |
256 | m_fil_node(NULL), |
257 | m_type(static_cast<uint16_t>(type)) |
258 | { |
259 | if (bpage && buf_page_should_punch_hole(bpage)) { |
260 | set_punch_hole(); |
261 | } |
262 | |
263 | if (!is_punch_hole_supported()) { |
264 | clear_punch_hole(); |
265 | } |
266 | } |
267 | |
268 | /** Destructor */ |
269 | ~IORequest() { } |
270 | |
271 | /** @return true if ignore missing flag is set */ |
272 | static bool ignore_missing(ulint type) |
273 | MY_ATTRIBUTE((warn_unused_result)) |
274 | { |
275 | return((type & IGNORE_MISSING) == IGNORE_MISSING); |
276 | } |
277 | |
278 | /** @return true if it is a read request */ |
279 | bool is_read() const |
280 | MY_ATTRIBUTE((warn_unused_result)) |
281 | { |
282 | return((m_type & READ) == READ); |
283 | } |
284 | |
285 | /** @return true if it is a write request */ |
286 | bool is_write() const |
287 | MY_ATTRIBUTE((warn_unused_result)) |
288 | { |
289 | return((m_type & WRITE) == WRITE); |
290 | } |
291 | |
292 | /** @return true if it is a redo log write */ |
293 | bool is_log() const |
294 | MY_ATTRIBUTE((warn_unused_result)) |
295 | { |
296 | return((m_type & LOG) == LOG); |
297 | } |
298 | |
299 | /** @return true if the simulated AIO thread should be woken up */ |
300 | bool is_wake() const |
301 | MY_ATTRIBUTE((warn_unused_result)) |
302 | { |
303 | return((m_type & DO_NOT_WAKE) == 0); |
304 | } |
305 | |
306 | /** Clear the punch hole flag */ |
307 | void clear_punch_hole() |
308 | { |
309 | m_type &= ~PUNCH_HOLE; |
310 | } |
311 | |
312 | /** @return true if partial read warning disabled */ |
313 | bool is_partial_io_warning_disabled() const |
314 | MY_ATTRIBUTE((warn_unused_result)) |
315 | { |
316 | return((m_type & DISABLE_PARTIAL_IO_WARNINGS) |
317 | == DISABLE_PARTIAL_IO_WARNINGS); |
318 | } |
319 | |
320 | /** Disable partial read warnings */ |
321 | void disable_partial_io_warnings() |
322 | { |
323 | m_type |= DISABLE_PARTIAL_IO_WARNINGS; |
324 | } |
325 | |
326 | /** @return true if missing files should be ignored */ |
327 | bool ignore_missing() const |
328 | MY_ATTRIBUTE((warn_unused_result)) |
329 | { |
330 | return(ignore_missing(m_type)); |
331 | } |
332 | |
333 | /** @return true if punch hole should be used */ |
334 | bool punch_hole() const |
335 | MY_ATTRIBUTE((warn_unused_result)) |
336 | { |
337 | return((m_type & PUNCH_HOLE) == PUNCH_HOLE); |
338 | } |
339 | |
340 | /** @return true if the read should be validated */ |
341 | bool validate() const |
342 | MY_ATTRIBUTE((warn_unused_result)) |
343 | { |
344 | return(is_read() ^ is_write()); |
345 | } |
346 | |
347 | /** Set the punch hole flag */ |
348 | void set_punch_hole() |
349 | { |
350 | if (is_punch_hole_supported()) { |
351 | m_type |= PUNCH_HOLE; |
352 | } |
353 | } |
354 | |
355 | /** Clear the do not wake flag */ |
356 | void clear_do_not_wake() |
357 | { |
358 | m_type &= ~DO_NOT_WAKE; |
359 | } |
360 | |
361 | /** Set the pointer to file node for IO |
362 | @param[in] node File node */ |
363 | void set_fil_node(fil_node_t* node) |
364 | { |
365 | if (node && !fil_node_should_punch_hole(node)) { |
366 | clear_punch_hole(); |
367 | } |
368 | |
369 | m_fil_node = node; |
370 | } |
371 | |
372 | /** Compare two requests |
373 | @reutrn true if the are equal */ |
374 | bool operator==(const IORequest& rhs) const |
375 | { |
376 | return(m_type == rhs.m_type); |
377 | } |
378 | |
379 | /** Note that the IO is for double write recovery. */ |
380 | void dblwr_recover() |
381 | { |
382 | m_type |= DBLWR_RECOVER; |
383 | } |
384 | |
385 | /** @return true if the request is from the dblwr recovery */ |
386 | bool is_dblwr_recover() const |
387 | MY_ATTRIBUTE((warn_unused_result)) |
388 | { |
389 | return((m_type & DBLWR_RECOVER) == DBLWR_RECOVER); |
390 | } |
391 | |
392 | /** @return true if punch hole is supported */ |
393 | static bool is_punch_hole_supported() |
394 | { |
395 | |
396 | /* In this debugging mode, we act as if punch hole is supported, |
397 | and then skip any calls to actually punch a hole here. |
398 | In this way, Transparent Page Compression is still being tested. */ |
399 | DBUG_EXECUTE_IF("ignore_punch_hole" , |
400 | return(true); |
401 | ); |
402 | |
403 | #if defined(HAVE_FALLOC_PUNCH_HOLE_AND_KEEP_SIZE) || defined(_WIN32) |
404 | return(true); |
405 | #else |
406 | return(false); |
407 | #endif /* HAVE_FALLOC_PUNCH_HOLE_AND_KEEP_SIZE || _WIN32 */ |
408 | } |
409 | |
410 | ulint get_trim_length(ulint write_length) const |
411 | { |
412 | return (m_bpage ? |
413 | buf_page_get_trim_length(m_bpage, write_length) |
414 | : 0); |
415 | } |
416 | |
417 | bool should_punch_hole() const { |
418 | return (m_fil_node ? |
419 | fil_node_should_punch_hole(m_fil_node) |
420 | : false); |
421 | } |
422 | |
423 | void space_no_punch_hole() const { |
424 | if (m_fil_node) { |
425 | fil_space_set_punch_hole(m_fil_node, false); |
426 | } |
427 | } |
428 | |
429 | /** Free storage space associated with a section of the file. |
430 | @param[in] fh Open file handle |
431 | @param[in] off Starting offset (SEEK_SET) |
432 | @param[in] len Size of the hole |
433 | @return DB_SUCCESS or error code */ |
434 | dberr_t punch_hole(os_file_t fh, os_offset_t off, ulint len); |
435 | |
436 | private: |
437 | /** Page to be written on write operation. */ |
438 | buf_page_t* m_bpage; |
439 | |
440 | /** File node */ |
441 | fil_node_t* m_fil_node; |
442 | |
443 | /** Request type bit flags */ |
444 | uint16_t m_type; |
445 | }; |
446 | |
447 | /* @} */ |
448 | |
449 | /** Sparse file size information. */ |
450 | struct os_file_size_t { |
451 | /** Total size of file in bytes */ |
452 | os_offset_t m_total_size; |
453 | |
454 | /** If it is a sparse file then this is the number of bytes |
455 | actually allocated for the file. */ |
456 | os_offset_t m_alloc_size; |
457 | }; |
458 | |
459 | /** Win NT does not allow more than 64 */ |
460 | static const ulint OS_AIO_N_PENDING_IOS_PER_THREAD = 32; |
461 | |
462 | /** Modes for aio operations @{ */ |
463 | /** Normal asynchronous i/o not for ibuf pages or ibuf bitmap pages */ |
464 | static const ulint OS_AIO_NORMAL = 21; |
465 | |
466 | /** Asynchronous i/o for ibuf pages or ibuf bitmap pages */ |
467 | static const ulint OS_AIO_IBUF = 22; |
468 | |
469 | /** Asynchronous i/o for the log */ |
470 | static const ulint OS_AIO_LOG = 23; |
471 | |
472 | /** Asynchronous i/o where the calling thread will itself wait for |
473 | the i/o to complete, doing also the job of the i/o-handler thread; |
474 | can be used for any pages, ibuf or non-ibuf. This is used to save |
475 | CPU time, as we can do with fewer thread switches. Plain synchronous |
476 | I/O is not as good, because it must serialize the file seek and read |
477 | or write, causing a bottleneck for parallelism. */ |
478 | static const ulint OS_AIO_SYNC = 24; |
479 | /* @} */ |
480 | |
481 | extern ulint os_n_file_reads; |
482 | extern ulint os_n_file_writes; |
483 | extern ulint os_n_fsyncs; |
484 | |
485 | /* File types for directory entry data type */ |
486 | |
487 | enum os_file_type_t { |
488 | OS_FILE_TYPE_UNKNOWN = 0, |
489 | OS_FILE_TYPE_FILE, /* regular file */ |
490 | OS_FILE_TYPE_DIR, /* directory */ |
491 | OS_FILE_TYPE_LINK, /* symbolic link */ |
492 | OS_FILE_TYPE_BLOCK /* block device */ |
493 | }; |
494 | |
495 | /* Maximum path string length in bytes when referring to tables with in the |
496 | './databasename/tablename.ibd' path format; we can allocate at least 2 buffers |
497 | of this size from the thread stack; that is why this should not be made much |
498 | bigger than 4000 bytes. The maximum path length used by any storage engine |
499 | in the server must be at least this big. */ |
500 | |
501 | /* MySQL 5.7 my_global.h */ |
502 | #ifndef FN_REFLEN_SE |
503 | #define FN_REFLEN_SE 4000 |
504 | #endif |
505 | |
506 | #define OS_FILE_MAX_PATH 4000 |
507 | #if (FN_REFLEN_SE < OS_FILE_MAX_PATH) |
508 | # error "(FN_REFLEN_SE < OS_FILE_MAX_PATH)" |
509 | #endif |
510 | |
511 | /** Struct used in fetching information of a file in a directory */ |
512 | struct os_file_stat_t { |
513 | char name[OS_FILE_MAX_PATH]; /*!< path to a file */ |
514 | os_file_type_t type; /*!< file type */ |
515 | os_offset_t size; /*!< file size in bytes */ |
516 | os_offset_t alloc_size; /*!< Allocated size for |
517 | sparse files in bytes */ |
518 | size_t block_size; /*!< Block size to use for IO |
519 | in bytes*/ |
520 | time_t ctime; /*!< creation time */ |
521 | time_t mtime; /*!< modification time */ |
522 | time_t atime; /*!< access time */ |
523 | bool rw_perm; /*!< true if can be opened |
524 | in read-write mode. Only valid |
525 | if type == OS_FILE_TYPE_FILE */ |
526 | }; |
527 | |
528 | /** Create a temporary file. This function is like tmpfile(3), but |
529 | the temporary file is created in the in the mysql server configuration |
530 | parameter (--tmpdir). |
531 | @return temporary file handle, or NULL on error */ |
532 | FILE* |
533 | os_file_create_tmpfile(); |
534 | |
535 | /** The os_file_opendir() function opens a directory stream corresponding to the |
536 | directory named by the dirname argument. The directory stream is positioned |
537 | at the first entry. In both Unix and Windows we automatically skip the '.' |
538 | and '..' items at the start of the directory listing. |
539 | |
540 | @param[in] dirname directory name; it must not contain a trailing |
541 | '\' or '/' |
542 | @param[in] is_fatal true if we should treat an error as a fatal |
543 | error; if we try to open symlinks then we do |
544 | not wish a fatal error if it happens not to be |
545 | a directory |
546 | @return directory stream, NULL if error */ |
547 | os_file_dir_t |
548 | os_file_opendir( |
549 | const char* dirname, |
550 | bool is_fatal); |
551 | |
552 | /** |
553 | Closes a directory stream. |
554 | @param[in] dir directory stream |
555 | @return 0 if success, -1 if failure */ |
556 | int |
557 | os_file_closedir( |
558 | os_file_dir_t dir); |
559 | |
560 | /** This function returns information of the next file in the directory. We jump |
561 | over the '.' and '..' entries in the directory. |
562 | @param[in] dirname directory name or path |
563 | @param[in] dir directory stream |
564 | @param[out] info buffer where the info is returned |
565 | @return 0 if ok, -1 if error, 1 if at the end of the directory */ |
566 | int |
567 | os_file_readdir_next_file( |
568 | const char* dirname, |
569 | os_file_dir_t dir, |
570 | os_file_stat_t* info); |
571 | |
572 | /** |
573 | This function attempts to create a directory named pathname. The new directory |
574 | gets default permissions. On Unix, the permissions are (0770 & ~umask). If the |
575 | directory exists already, nothing is done and the call succeeds, unless the |
576 | fail_if_exists arguments is true. |
577 | |
578 | @param[in] pathname directory name as null-terminated string |
579 | @param[in] fail_if_exists if true, pre-existing directory is treated |
580 | as an error. |
581 | @return true if call succeeds, false on error */ |
582 | bool |
583 | os_file_create_directory( |
584 | const char* pathname, |
585 | bool fail_if_exists); |
586 | |
587 | /** NOTE! Use the corresponding macro os_file_create_simple(), not directly |
588 | this function! |
589 | A simple function to open or create a file. |
590 | @param[in] name name of the file or path as a null-terminated |
591 | string |
592 | @param[in] create_mode create mode |
593 | @param[in] access_type OS_FILE_READ_ONLY or OS_FILE_READ_WRITE |
594 | @param[in] read_only if true read only mode checks are enforced |
595 | @param[out] success true if succeed, false if error |
596 | @return own: handle to the file, not defined if error, error number |
597 | can be retrieved with os_file_get_last_error */ |
598 | pfs_os_file_t |
599 | os_file_create_simple_func( |
600 | const char* name, |
601 | ulint create_mode, |
602 | ulint access_type, |
603 | bool read_only, |
604 | bool* success); |
605 | |
606 | /** NOTE! Use the corresponding macro |
607 | os_file_create_simple_no_error_handling(), not directly this function! |
608 | A simple function to open or create a file. |
609 | @param[in] name name of the file or path as a null-terminated string |
610 | @param[in] create_mode create mode |
611 | @param[in] access_type OS_FILE_READ_ONLY, OS_FILE_READ_WRITE, or |
612 | OS_FILE_READ_ALLOW_DELETE; the last option |
613 | is used by a backup program reading the file |
614 | @param[in] read_only if true read only mode checks are enforced |
615 | @param[out] success true if succeeded |
616 | @return own: handle to the file, not defined if error, error number |
617 | can be retrieved with os_file_get_last_error */ |
618 | pfs_os_file_t |
619 | os_file_create_simple_no_error_handling_func( |
620 | const char* name, |
621 | ulint create_mode, |
622 | ulint access_type, |
623 | bool read_only, |
624 | bool* success) |
625 | MY_ATTRIBUTE((warn_unused_result)); |
626 | |
627 | #ifdef _WIN32 |
628 | #define os_file_set_nocache(fd, file_name, operation_name) do{}while(0) |
629 | #else |
630 | /** Tries to disable OS caching on an opened file descriptor. |
631 | @param[in] fd file descriptor to alter |
632 | @param[in] file_name file name, used in the diagnostic message |
633 | @param[in] name "open" or "create"; used in the diagnostic |
634 | message */ |
635 | void |
636 | os_file_set_nocache( |
637 | /*================*/ |
638 | int fd, /*!< in: file descriptor to alter */ |
639 | const char* file_name, |
640 | const char* operation_name); |
641 | #endif |
642 | |
643 | /** NOTE! Use the corresponding macro os_file_create(), not directly |
644 | this function! |
645 | Opens an existing file or creates a new. |
646 | @param[in] name name of the file or path as a null-terminated |
647 | string |
648 | @param[in] create_mode create mode |
649 | @param[in] purpose OS_FILE_AIO, if asynchronous, non-buffered I/O |
650 | is desired, OS_FILE_NORMAL, if any normal file; |
651 | NOTE that it also depends on type, os_aio_.. |
652 | and srv_.. variables whether we really use |
653 | async I/O or unbuffered I/O: look in the |
654 | function source code for the exact rules |
655 | @param[in] type OS_DATA_FILE or OS_LOG_FILE |
656 | @param[in] read_only if true read only mode checks are enforced |
657 | @param[in] success true if succeeded |
658 | @return own: handle to the file, not defined if error, error number |
659 | can be retrieved with os_file_get_last_error */ |
660 | pfs_os_file_t |
661 | os_file_create_func( |
662 | const char* name, |
663 | ulint create_mode, |
664 | ulint purpose, |
665 | ulint type, |
666 | bool read_only, |
667 | bool* success) |
668 | MY_ATTRIBUTE((warn_unused_result)); |
669 | |
670 | /** Deletes a file. The file has to be closed before calling this. |
671 | @param[in] name file path as a null-terminated string |
672 | @return true if success */ |
673 | bool |
674 | os_file_delete_func(const char* name); |
675 | |
676 | /** Deletes a file if it exists. The file has to be closed before calling this. |
677 | @param[in] name file path as a null-terminated string |
678 | @param[out] exist indicate if file pre-exist |
679 | @return true if success */ |
680 | bool |
681 | os_file_delete_if_exists_func(const char* name, bool* exist); |
682 | |
683 | /** NOTE! Use the corresponding macro os_file_rename(), not directly |
684 | this function! |
685 | Renames a file (can also move it to another directory). It is safest that the |
686 | file is closed before calling this function. |
687 | @param[in] oldpath old file path as a null-terminated string |
688 | @param[in] newpath new file path |
689 | @return true if success */ |
690 | bool |
691 | os_file_rename_func(const char* oldpath, const char* newpath); |
692 | |
693 | /** NOTE! Use the corresponding macro os_file_close(), not directly this |
694 | function! |
695 | Closes a file handle. In case of error, error number can be retrieved with |
696 | os_file_get_last_error. |
697 | @param[in] file own: handle to a file |
698 | @return true if success */ |
699 | bool |
700 | os_file_close_func(os_file_t file); |
701 | |
702 | #ifdef UNIV_PFS_IO |
703 | |
704 | /* Keys to register InnoDB I/O with performance schema */ |
705 | extern mysql_pfs_key_t innodb_data_file_key; |
706 | extern mysql_pfs_key_t innodb_log_file_key; |
707 | extern mysql_pfs_key_t innodb_temp_file_key; |
708 | |
709 | /* Following four macros are instumentations to register |
710 | various file I/O operations with performance schema. |
711 | 1) register_pfs_file_open_begin() and register_pfs_file_open_end() are |
712 | used to register file creation, opening, closing and renaming. |
713 | 2) register_pfs_file_rename_begin() and register_pfs_file_rename_end() |
714 | are used to register file renaming |
715 | 2) register_pfs_file_io_begin() and register_pfs_file_io_end() are |
716 | used to register actual file read, write and flush |
717 | 3) register_pfs_file_close_begin() and register_pfs_file_close_end() |
718 | are used to register file deletion operations*/ |
719 | # define register_pfs_file_open_begin(state, locker, key, op, name, \ |
720 | src_file, src_line) \ |
721 | do { \ |
722 | locker = PSI_FILE_CALL(get_thread_file_name_locker)( \ |
723 | state, key, op, name, &locker); \ |
724 | if (locker != NULL) { \ |
725 | PSI_FILE_CALL(start_file_open_wait)( \ |
726 | locker, src_file, src_line); \ |
727 | } \ |
728 | } while (0) |
729 | |
730 | # define register_pfs_file_open_end(locker, file, result) \ |
731 | do { \ |
732 | if (locker != NULL) { \ |
733 | file.m_psi = PSI_FILE_CALL(end_file_open_wait)( \ |
734 | locker, result); \ |
735 | } \ |
736 | } while (0) |
737 | |
738 | # define register_pfs_file_rename_begin(state, locker, key, op, name, \ |
739 | src_file, src_line) \ |
740 | register_pfs_file_open_begin(state, locker, key, op, name, \ |
741 | src_file, src_line) \ |
742 | |
743 | # define register_pfs_file_rename_end(locker, result) \ |
744 | do { \ |
745 | if (locker != NULL) { \ |
746 | PSI_FILE_CALL(end_file_open_wait)(locker, result); \ |
747 | } \ |
748 | } while (0) |
749 | |
750 | # define register_pfs_file_close_begin(state, locker, key, op, name, \ |
751 | src_file, src_line) \ |
752 | do { \ |
753 | locker = PSI_FILE_CALL(get_thread_file_name_locker)( \ |
754 | state, key, op, name, &locker); \ |
755 | if (locker != NULL) { \ |
756 | PSI_FILE_CALL(start_file_close_wait)( \ |
757 | locker, src_file, src_line); \ |
758 | } \ |
759 | } while (0) |
760 | |
761 | # define register_pfs_file_close_end(locker, result) \ |
762 | do { \ |
763 | if (locker != NULL) { \ |
764 | PSI_FILE_CALL(end_file_close_wait)( \ |
765 | locker, result); \ |
766 | } \ |
767 | } while (0) |
768 | |
769 | # define register_pfs_file_io_begin(state, locker, file, count, op, \ |
770 | src_file, src_line) \ |
771 | do { \ |
772 | locker = PSI_FILE_CALL(get_thread_file_stream_locker)( \ |
773 | state, file.m_psi, op); \ |
774 | if (locker != NULL) { \ |
775 | PSI_FILE_CALL(start_file_wait)( \ |
776 | locker, count, src_file, src_line); \ |
777 | } \ |
778 | } while (0) |
779 | |
780 | # define register_pfs_file_io_end(locker, count) \ |
781 | do { \ |
782 | if (locker != NULL) { \ |
783 | PSI_FILE_CALL(end_file_wait)(locker, count); \ |
784 | } \ |
785 | } while (0) |
786 | |
787 | /* Following macros/functions are file I/O APIs that would be performance |
788 | schema instrumented if "UNIV_PFS_IO" is defined. They would point to |
789 | wrapper functions with performance schema instrumentation in such case. |
790 | |
791 | os_file_create |
792 | os_file_create_simple |
793 | os_file_create_simple_no_error_handling |
794 | os_file_close |
795 | os_file_rename |
796 | os_aio |
797 | os_file_read |
798 | os_file_read_no_error_handling |
799 | os_file_read_no_error_handling_int_fd |
800 | os_file_write |
801 | os_file_write_int_fd |
802 | |
803 | The wrapper functions have the prefix of "innodb_". */ |
804 | |
805 | # define os_file_create(key, name, create, purpose, type, read_only, \ |
806 | success) \ |
807 | pfs_os_file_create_func(key, name, create, purpose, type, \ |
808 | read_only, success, __FILE__, __LINE__) |
809 | |
810 | # define os_file_create_simple(key, name, create, access, \ |
811 | read_only, success) \ |
812 | pfs_os_file_create_simple_func(key, name, create, access, \ |
813 | read_only, success, __FILE__, __LINE__) |
814 | |
815 | # define os_file_create_simple_no_error_handling( \ |
816 | key, name, create_mode, access, read_only, success) \ |
817 | pfs_os_file_create_simple_no_error_handling_func( \ |
818 | key, name, create_mode, access, \ |
819 | read_only, success, __FILE__, __LINE__) |
820 | |
821 | # define os_file_close(file) \ |
822 | pfs_os_file_close_func(file, __FILE__, __LINE__) |
823 | |
824 | # define os_aio(type, mode, name, file, buf, offset, \ |
825 | n, read_only, message1, message2) \ |
826 | pfs_os_aio_func(type, mode, name, file, buf, offset, \ |
827 | n, read_only, message1, message2, \ |
828 | __FILE__, __LINE__) |
829 | |
830 | # define os_file_read(type, file, buf, offset, n) \ |
831 | pfs_os_file_read_func(type, file, buf, offset, n, __FILE__, __LINE__) |
832 | |
833 | # define os_file_read_no_error_handling(type, file, buf, offset, n, o) \ |
834 | pfs_os_file_read_no_error_handling_func( \ |
835 | type, file, buf, offset, n, o, __FILE__, __LINE__) |
836 | |
837 | # define os_file_write(type, name, file, buf, offset, n) \ |
838 | pfs_os_file_write_func(type, name, file, buf, offset, \ |
839 | n, __FILE__, __LINE__) |
840 | |
841 | # define os_file_flush(file) \ |
842 | pfs_os_file_flush_func(file, __FILE__, __LINE__) |
843 | |
844 | # define os_file_rename(key, oldpath, newpath) \ |
845 | pfs_os_file_rename_func(key, oldpath, newpath, __FILE__, __LINE__) |
846 | |
847 | # define os_file_delete(key, name) \ |
848 | pfs_os_file_delete_func(key, name, __FILE__, __LINE__) |
849 | |
850 | # define os_file_delete_if_exists(key, name, exist) \ |
851 | pfs_os_file_delete_if_exists_func(key, name, exist, __FILE__, __LINE__) |
852 | |
853 | /** NOTE! Please use the corresponding macro os_file_create_simple(), |
854 | not directly this function! |
855 | A performance schema instrumented wrapper function for |
856 | os_file_create_simple() which opens or creates a file. |
857 | @param[in] key Performance Schema Key |
858 | @param[in] name name of the file or path as a null-terminated |
859 | string |
860 | @param[in] create_mode create mode |
861 | @param[in] access_type OS_FILE_READ_ONLY or OS_FILE_READ_WRITE |
862 | @param[in] read_only if true read only mode checks are enforced |
863 | @param[out] success true if succeeded |
864 | @param[in] src_file file name where func invoked |
865 | @param[in] src_line line where the func invoked |
866 | @return own: handle to the file, not defined if error, error number |
867 | can be retrieved with os_file_get_last_error */ |
868 | UNIV_INLINE |
869 | pfs_os_file_t |
870 | pfs_os_file_create_simple_func( |
871 | mysql_pfs_key_t key, |
872 | const char* name, |
873 | ulint create_mode, |
874 | ulint access_type, |
875 | bool read_only, |
876 | bool* success, |
877 | const char* src_file, |
878 | uint src_line) |
879 | MY_ATTRIBUTE((warn_unused_result)); |
880 | |
881 | /** NOTE! Please use the corresponding macro |
882 | os_file_create_simple_no_error_handling(), not directly this function! |
883 | A performance schema instrumented wrapper function for |
884 | os_file_create_simple_no_error_handling(). Add instrumentation to |
885 | monitor file creation/open. |
886 | @param[in] key Performance Schema Key |
887 | @param[in] name name of the file or path as a null-terminated |
888 | string |
889 | @param[in] create_mode create mode |
890 | @param[in] access_type OS_FILE_READ_ONLY, OS_FILE_READ_WRITE, or |
891 | OS_FILE_READ_ALLOW_DELETE; the last option is |
892 | used by a backup program reading the file |
893 | @param[in] read_only if true read only mode checks are enforced |
894 | @param[out] success true if succeeded |
895 | @param[in] src_file file name where func invoked |
896 | @param[in] src_line line where the func invoked |
897 | @return own: handle to the file, not defined if error, error number |
898 | can be retrieved with os_file_get_last_error */ |
899 | UNIV_INLINE |
900 | pfs_os_file_t |
901 | pfs_os_file_create_simple_no_error_handling_func( |
902 | mysql_pfs_key_t key, |
903 | const char* name, |
904 | ulint create_mode, |
905 | ulint access_type, |
906 | bool read_only, |
907 | bool* success, |
908 | const char* src_file, |
909 | uint src_line) |
910 | MY_ATTRIBUTE((warn_unused_result)); |
911 | |
912 | /** NOTE! Please use the corresponding macro os_file_create(), not directly |
913 | this function! |
914 | A performance schema wrapper function for os_file_create(). |
915 | Add instrumentation to monitor file creation/open. |
916 | @param[in] key Performance Schema Key |
917 | @param[in] name name of the file or path as a null-terminated |
918 | string |
919 | @param[in] create_mode create mode |
920 | @param[in] purpose OS_FILE_AIO, if asynchronous, non-buffered I/O |
921 | is desired, OS_FILE_NORMAL, if any normal file; |
922 | NOTE that it also depends on type, os_aio_.. |
923 | and srv_.. variables whether we really use |
924 | async I/O or unbuffered I/O: look in the |
925 | function source code for the exact rules |
926 | @param[in] read_only if true read only mode checks are enforced |
927 | @param[out] success true if succeeded |
928 | @param[in] src_file file name where func invoked |
929 | @param[in] src_line line where the func invoked |
930 | @return own: handle to the file, not defined if error, error number |
931 | can be retrieved with os_file_get_last_error */ |
932 | UNIV_INLINE |
933 | pfs_os_file_t |
934 | pfs_os_file_create_func( |
935 | mysql_pfs_key_t key, |
936 | const char* name, |
937 | ulint create_mode, |
938 | ulint purpose, |
939 | ulint type, |
940 | bool read_only, |
941 | bool* success, |
942 | const char* src_file, |
943 | uint src_line) |
944 | MY_ATTRIBUTE((warn_unused_result)); |
945 | |
946 | /** NOTE! Please use the corresponding macro os_file_close(), not directly |
947 | this function! |
948 | A performance schema instrumented wrapper function for os_file_close(). |
949 | @param[in] file handle to a file |
950 | @param[in] src_file file name where func invoked |
951 | @param[in] src_line line where the func invoked |
952 | @return true if success */ |
953 | UNIV_INLINE |
954 | bool |
955 | pfs_os_file_close_func( |
956 | pfs_os_file_t file, |
957 | const char* src_file, |
958 | uint src_line); |
959 | |
960 | /** NOTE! Please use the corresponding macro os_file_read(), not directly |
961 | this function! |
962 | This is the performance schema instrumented wrapper function for |
963 | os_file_read() which requests a synchronous read operation. |
964 | @param[in] type IO request context |
965 | @param[in] file Open file handle |
966 | @param[out] buf buffer where to read |
967 | @param[in] offset file offset where to read |
968 | @param[in] n number of bytes to read |
969 | @param[in] src_file file name where func invoked |
970 | @param[in] src_line line where the func invoked |
971 | @return DB_SUCCESS if request was successful */ |
972 | UNIV_INLINE |
973 | dberr_t |
974 | pfs_os_file_read_func( |
975 | const IORequest& type, |
976 | pfs_os_file_t file, |
977 | void* buf, |
978 | os_offset_t offset, |
979 | ulint n, |
980 | const char* src_file, |
981 | uint src_line); |
982 | |
983 | /** NOTE! Please use the corresponding macro os_file_read_no_error_handling(), |
984 | not directly this function! |
985 | This is the performance schema instrumented wrapper function for |
986 | os_file_read_no_error_handling_func() which requests a synchronous |
987 | read operation. |
988 | @param[in] type IO request context |
989 | @param[in] file Open file handle |
990 | @param[out] buf buffer where to read |
991 | @param[in] offset file offset where to read |
992 | @param[in] n number of bytes to read |
993 | @param[out] o number of bytes actually read |
994 | @param[in] src_file file name where func invoked |
995 | @param[in] src_line line where the func invoked |
996 | @return DB_SUCCESS if request was successful */ |
997 | UNIV_INLINE |
998 | dberr_t |
999 | pfs_os_file_read_no_error_handling_func( |
1000 | const IORequest& type, |
1001 | pfs_os_file_t file, |
1002 | void* buf, |
1003 | os_offset_t offset, |
1004 | ulint n, |
1005 | ulint* o, |
1006 | const char* src_file, |
1007 | uint src_line); |
1008 | |
1009 | /** NOTE! Please use the corresponding macro os_aio(), not directly this |
1010 | function! |
1011 | Performance schema wrapper function of os_aio() which requests |
1012 | an asynchronous I/O operation. |
1013 | @param[in,out] type IO request context |
1014 | @param[in] mode IO mode |
1015 | @param[in] name Name of the file or path as NUL terminated |
1016 | string |
1017 | @param[in] file Open file handle |
1018 | @param[out] buf buffer where to read |
1019 | @param[in] offset file offset where to read |
1020 | @param[in] n number of bytes to read |
1021 | @param[in] read_only if true read only mode checks are enforced |
1022 | @param[in,out] m1 Message for the AIO handler, (can be used to |
1023 | identify a completed AIO operation); ignored |
1024 | if mode is OS_AIO_SYNC |
1025 | @param[in,out] m2 message for the AIO handler (can be used to |
1026 | identify a completed AIO operation); ignored |
1027 | if mode is OS_AIO_SYNC |
1028 | @param[in] src_file file name where func invoked |
1029 | @param[in] src_line line where the func invoked |
1030 | @return DB_SUCCESS if request was queued successfully, FALSE if fail */ |
1031 | UNIV_INLINE |
1032 | dberr_t |
1033 | pfs_os_aio_func( |
1034 | IORequest& type, |
1035 | ulint mode, |
1036 | const char* name, |
1037 | pfs_os_file_t file, |
1038 | void* buf, |
1039 | os_offset_t offset, |
1040 | ulint n, |
1041 | bool read_only, |
1042 | fil_node_t* m1, |
1043 | void* m2, |
1044 | const char* src_file, |
1045 | uint src_line); |
1046 | |
1047 | /** NOTE! Please use the corresponding macro os_file_write(), not directly |
1048 | this function! |
1049 | This is the performance schema instrumented wrapper function for |
1050 | os_file_write() which requests a synchronous write operation. |
1051 | @param[in] type IO request context |
1052 | @param[in] name Name of the file or path as NUL terminated |
1053 | string |
1054 | @param[in] file Open file handle |
1055 | @param[out] buf buffer where to read |
1056 | @param[in] offset file offset where to read |
1057 | @param[in] n number of bytes to read |
1058 | @param[in] src_file file name where func invoked |
1059 | @param[in] src_line line where the func invoked |
1060 | @return DB_SUCCESS if request was successful */ |
1061 | UNIV_INLINE |
1062 | dberr_t |
1063 | pfs_os_file_write_func( |
1064 | const IORequest& type, |
1065 | const char* name, |
1066 | pfs_os_file_t file, |
1067 | const void* buf, |
1068 | os_offset_t offset, |
1069 | ulint n, |
1070 | const char* src_file, |
1071 | uint src_line); |
1072 | |
1073 | /** NOTE! Please use the corresponding macro os_file_flush(), not directly |
1074 | this function! |
1075 | This is the performance schema instrumented wrapper function for |
1076 | os_file_flush() which flushes the write buffers of a given file to the disk. |
1077 | Flushes the write buffers of a given file to the disk. |
1078 | @param[in] file Open file handle |
1079 | @param[in] src_file file name where func invoked |
1080 | @param[in] src_line line where the func invoked |
1081 | @return TRUE if success */ |
1082 | UNIV_INLINE |
1083 | bool |
1084 | pfs_os_file_flush_func( |
1085 | pfs_os_file_t file, |
1086 | const char* src_file, |
1087 | uint src_line); |
1088 | |
1089 | /** NOTE! Please use the corresponding macro os_file_rename(), not directly |
1090 | this function! |
1091 | This is the performance schema instrumented wrapper function for |
1092 | os_file_rename() |
1093 | @param[in] key Performance Schema Key |
1094 | @param[in] oldpath old file path as a null-terminated string |
1095 | @param[in] newpath new file path |
1096 | @param[in] src_file file name where func invoked |
1097 | @param[in] src_line line where the func invoked |
1098 | @return true if success */ |
1099 | UNIV_INLINE |
1100 | bool |
1101 | pfs_os_file_rename_func( |
1102 | mysql_pfs_key_t key, |
1103 | const char* oldpath, |
1104 | const char* newpath, |
1105 | const char* src_file, |
1106 | uint src_line); |
1107 | |
1108 | /** |
1109 | NOTE! Please use the corresponding macro os_file_delete(), not directly |
1110 | this function! |
1111 | This is the performance schema instrumented wrapper function for |
1112 | os_file_delete() |
1113 | @param[in] key Performance Schema Key |
1114 | @param[in] name old file path as a null-terminated string |
1115 | @param[in] src_file file name where func invoked |
1116 | @param[in] src_line line where the func invoked |
1117 | @return true if success */ |
1118 | UNIV_INLINE |
1119 | bool |
1120 | pfs_os_file_delete_func( |
1121 | mysql_pfs_key_t key, |
1122 | const char* name, |
1123 | const char* src_file, |
1124 | uint src_line); |
1125 | |
1126 | /** |
1127 | NOTE! Please use the corresponding macro os_file_delete_if_exists(), not |
1128 | directly this function! |
1129 | This is the performance schema instrumented wrapper function for |
1130 | os_file_delete_if_exists() |
1131 | @param[in] key Performance Schema Key |
1132 | @param[in] name old file path as a null-terminated string |
1133 | @param[in] exist indicate if file pre-exist |
1134 | @param[in] src_file file name where func invoked |
1135 | @param[in] src_line line where the func invoked |
1136 | @return true if success */ |
1137 | UNIV_INLINE |
1138 | bool |
1139 | pfs_os_file_delete_if_exists_func( |
1140 | mysql_pfs_key_t key, |
1141 | const char* name, |
1142 | bool* exist, |
1143 | const char* src_file, |
1144 | uint src_line); |
1145 | |
1146 | #else /* UNIV_PFS_IO */ |
1147 | |
1148 | /* If UNIV_PFS_IO is not defined, these I/O APIs point |
1149 | to original un-instrumented file I/O APIs */ |
1150 | # define os_file_create(key, name, create, purpose, type, read_only, \ |
1151 | success) \ |
1152 | os_file_create_func(name, create, purpose, type, read_only, \ |
1153 | success) |
1154 | |
1155 | # define os_file_create_simple(key, name, create_mode, access, \ |
1156 | read_only, success) \ |
1157 | os_file_create_simple_func(name, create_mode, access, \ |
1158 | read_only, success) |
1159 | |
1160 | # define os_file_create_simple_no_error_handling( \ |
1161 | key, name, create_mode, access, read_only, success) \ |
1162 | os_file_create_simple_no_error_handling_func( \ |
1163 | name, create_mode, access, read_only, success) |
1164 | |
1165 | # define os_file_close(file) os_file_close_func(file) |
1166 | |
1167 | # define os_aio(type, mode, name, file, buf, offset, \ |
1168 | n, read_only, message1, message2) \ |
1169 | os_aio_func(type, mode, name, file, buf, offset, \ |
1170 | n, read_only, message1, message2) |
1171 | |
1172 | # define os_file_read(type, file, buf, offset, n) \ |
1173 | os_file_read_func(type, file, buf, offset, n) |
1174 | |
1175 | # define os_file_read_no_error_handling(type, file, buf, offset, n, o) \ |
1176 | os_file_read_no_error_handling_func(type, file, buf, offset, n, o) |
1177 | # define os_file_read_no_error_handling_int_fd(type, file, buf, offset, n) \ |
1178 | os_file_read_no_error_handling_func(type, OS_FILE_FROM_FD(file), buf, offset, n, NULL) |
1179 | |
1180 | # define os_file_write(type, name, file, buf, offset, n) \ |
1181 | os_file_write_func(type, name, file, buf, offset, n) |
1182 | # define os_file_write_int_fd(type, name, file, buf, offset, n) \ |
1183 | os_file_write_func(type, name, OS_FILE_FROM_FD(file), buf, offset, n) |
1184 | |
1185 | # define os_file_flush(file) os_file_flush_func(file) |
1186 | |
1187 | # define os_file_rename(key, oldpath, newpath) \ |
1188 | os_file_rename_func(oldpath, newpath) |
1189 | |
1190 | # define os_file_delete(key, name) os_file_delete_func(name) |
1191 | |
1192 | # define os_file_delete_if_exists(key, name, exist) \ |
1193 | os_file_delete_if_exists_func(name, exist) |
1194 | |
1195 | #endif /* UNIV_PFS_IO */ |
1196 | |
1197 | /** Gets a file size. |
1198 | @param[in] file handle to a file |
1199 | @return file size if OK, else set m_total_size to ~0 and m_alloc_size |
1200 | to errno */ |
1201 | os_file_size_t |
1202 | os_file_get_size( |
1203 | const char* filename) |
1204 | MY_ATTRIBUTE((warn_unused_result)); |
1205 | |
1206 | /** Gets a file size. |
1207 | @param[in] file handle to a file |
1208 | @return file size, or (os_offset_t) -1 on failure */ |
1209 | os_offset_t |
1210 | os_file_get_size( |
1211 | os_file_t file) |
1212 | MY_ATTRIBUTE((warn_unused_result)); |
1213 | |
1214 | /** Extend a file. |
1215 | |
1216 | On Windows, extending a file allocates blocks for the file, |
1217 | unless the file is sparse. |
1218 | |
1219 | On Unix, we will extend the file with ftruncate(), if |
1220 | file needs to be sparse. Otherwise posix_fallocate() is used |
1221 | when available, and if not, binary zeroes are added to the end |
1222 | of file. |
1223 | |
1224 | @param[in] name file name |
1225 | @param[in] file file handle |
1226 | @param[in] size desired file size |
1227 | @param[in] sparse whether to create a sparse file (no preallocating) |
1228 | @return whether the operation succeeded */ |
1229 | bool |
1230 | os_file_set_size( |
1231 | const char* name, |
1232 | os_file_t file, |
1233 | os_offset_t size, |
1234 | bool is_sparse = false) |
1235 | MY_ATTRIBUTE((warn_unused_result)); |
1236 | |
1237 | /** Truncates a file at its current position. |
1238 | @param[in/out] file file to be truncated |
1239 | @return true if success */ |
1240 | bool |
1241 | os_file_set_eof( |
1242 | FILE* file); /*!< in: file to be truncated */ |
1243 | |
1244 | /** Truncates a file to a specified size in bytes. Do nothing if the size |
1245 | preserved is smaller or equal than current size of file. |
1246 | @param[in] pathname file path |
1247 | @param[in] file file to be truncated |
1248 | @param[in] size size preserved in bytes |
1249 | @return true if success */ |
1250 | bool |
1251 | os_file_truncate( |
1252 | const char* pathname, |
1253 | os_file_t file, |
1254 | os_offset_t size); |
1255 | |
1256 | /** NOTE! Use the corresponding macro os_file_flush(), not directly this |
1257 | function! |
1258 | Flushes the write buffers of a given file to the disk. |
1259 | @param[in] file handle to a file |
1260 | @return true if success */ |
1261 | bool |
1262 | os_file_flush_func( |
1263 | os_file_t file); |
1264 | |
1265 | /** Retrieves the last error number if an error occurs in a file io function. |
1266 | The number should be retrieved before any other OS calls (because they may |
1267 | overwrite the error number). If the number is not known to this program, |
1268 | the OS error number + 100 is returned. |
1269 | @param[in] report true if we want an error message printed |
1270 | for all errors |
1271 | @return error number, or OS error number + 100 */ |
1272 | ulint |
1273 | os_file_get_last_error( |
1274 | bool report); |
1275 | |
1276 | /** NOTE! Use the corresponding macro os_file_read(), not directly this |
1277 | function! |
1278 | Requests a synchronous read operation. |
1279 | @param[in] type IO request context |
1280 | @param[in] file Open file handle |
1281 | @param[out] buf buffer where to read |
1282 | @param[in] offset file offset where to read |
1283 | @param[in] n number of bytes to read |
1284 | @return DB_SUCCESS if request was successful */ |
1285 | dberr_t |
1286 | os_file_read_func( |
1287 | const IORequest& type, |
1288 | os_file_t file, |
1289 | void* buf, |
1290 | os_offset_t offset, |
1291 | ulint n) |
1292 | MY_ATTRIBUTE((warn_unused_result)); |
1293 | |
1294 | /** Rewind file to its start, read at most size - 1 bytes from it to str, and |
1295 | NUL-terminate str. All errors are silently ignored. This function is |
1296 | mostly meant to be used with temporary files. |
1297 | @param[in,out] file file to read from |
1298 | @param[in,out] str buffer where to read |
1299 | @param[in] size size of buffer */ |
1300 | void |
1301 | os_file_read_string( |
1302 | FILE* file, |
1303 | char* str, |
1304 | ulint size); |
1305 | |
1306 | /** NOTE! Use the corresponding macro os_file_read_no_error_handling(), |
1307 | not directly this function! |
1308 | Requests a synchronous positioned read operation. This function does not do |
1309 | any error handling. In case of error it returns FALSE. |
1310 | @param[in] type IO request context |
1311 | @param[in] file Open file handle |
1312 | @param[out] buf buffer where to read |
1313 | @param[in] offset file offset where to read |
1314 | @param[in] n number of bytes to read |
1315 | @param[out] o number of bytes actually read |
1316 | @return DB_SUCCESS or error code */ |
1317 | dberr_t |
1318 | os_file_read_no_error_handling_func( |
1319 | const IORequest& type, |
1320 | os_file_t file, |
1321 | void* buf, |
1322 | os_offset_t offset, |
1323 | ulint n, |
1324 | ulint* o) |
1325 | MY_ATTRIBUTE((warn_unused_result)); |
1326 | |
1327 | /** NOTE! Use the corresponding macro os_file_write(), not directly this |
1328 | function! |
1329 | Requests a synchronous write operation. |
1330 | @param[in] type IO request context |
1331 | @param[in] file Open file handle |
1332 | @param[out] buf buffer where to read |
1333 | @param[in] offset file offset where to read |
1334 | @param[in] n number of bytes to read |
1335 | @return DB_SUCCESS if request was successful */ |
1336 | dberr_t |
1337 | os_file_write_func( |
1338 | const IORequest& type, |
1339 | const char* name, |
1340 | os_file_t file, |
1341 | const void* buf, |
1342 | os_offset_t offset, |
1343 | ulint n) |
1344 | MY_ATTRIBUTE((warn_unused_result)); |
1345 | |
1346 | /** Check the existence and type of the given file. |
1347 | @param[in] path pathname of the file |
1348 | @param[out] exists true if file exists |
1349 | @param[out] type type of the file (if it exists) |
1350 | @return true if call succeeded */ |
1351 | bool |
1352 | os_file_status( |
1353 | const char* path, |
1354 | bool* exists, |
1355 | os_file_type_t* type); |
1356 | |
1357 | /** This function returns a new path name after replacing the basename |
1358 | in an old path with a new basename. The old_path is a full path |
1359 | name including the extension. The tablename is in the normal |
1360 | form "databasename/tablename". The new base name is found after |
1361 | the forward slash. Both input strings are null terminated. |
1362 | |
1363 | This function allocates memory to be returned. It is the callers |
1364 | responsibility to free the return value after it is no longer needed. |
1365 | |
1366 | @param[in] old_path pathname |
1367 | @param[in] new_name new file name |
1368 | @return own: new full pathname */ |
1369 | char* |
1370 | os_file_make_new_pathname( |
1371 | const char* old_path, |
1372 | const char* new_name); |
1373 | |
1374 | /** This function reduces a null-terminated full remote path name into |
1375 | the path that is sent by MySQL for DATA DIRECTORY clause. It replaces |
1376 | the 'databasename/tablename.ibd' found at the end of the path with just |
1377 | 'tablename'. |
1378 | |
1379 | Since the result is always smaller than the path sent in, no new memory |
1380 | is allocated. The caller should allocate memory for the path sent in. |
1381 | This function manipulates that path in place. |
1382 | |
1383 | If the path format is not as expected, just return. The result is used |
1384 | to inform a SHOW CREATE TABLE command. |
1385 | @param[in,out] data_dir_path Full path/data_dir_path */ |
1386 | void |
1387 | os_file_make_data_dir_path( |
1388 | char* data_dir_path); |
1389 | |
1390 | /** Create all missing subdirectories along the given path. |
1391 | @return DB_SUCCESS if OK, otherwise error code. */ |
1392 | dberr_t |
1393 | os_file_create_subdirs_if_needed( |
1394 | const char* path); |
1395 | |
1396 | #ifdef UNIV_ENABLE_UNIT_TEST_GET_PARENT_DIR |
1397 | /* Test the function os_file_get_parent_dir. */ |
1398 | void |
1399 | unit_test_os_file_get_parent_dir(); |
1400 | #endif /* UNIV_ENABLE_UNIT_TEST_GET_PARENT_DIR */ |
1401 | |
1402 | /** Initializes the asynchronous io system. Creates one array each for ibuf |
1403 | and log i/o. Also creates one array each for read and write where each |
1404 | array is divided logically into n_read_segs and n_write_segs |
1405 | respectively. The caller must create an i/o handler thread for each |
1406 | segment in these arrays. This function also creates the sync array. |
1407 | No i/o handler thread needs to be created for that |
1408 | @param[in] n_read_segs number of reader threads |
1409 | @param[in] n_write_segs number of writer threads |
1410 | @param[in] n_slots_sync number of slots in the sync aio array */ |
1411 | |
1412 | bool |
1413 | os_aio_init( |
1414 | ulint n_read_segs, |
1415 | ulint n_write_segs, |
1416 | ulint n_slots_sync); |
1417 | |
1418 | /** |
1419 | Frees the asynchronous io system. */ |
1420 | void |
1421 | os_aio_free(); |
1422 | |
1423 | /** |
1424 | NOTE! Use the corresponding macro os_aio(), not directly this function! |
1425 | Requests an asynchronous i/o operation. |
1426 | @param[in,out] type IO request context |
1427 | @param[in] mode IO mode |
1428 | @param[in] name Name of the file or path as NUL terminated |
1429 | string |
1430 | @param[in] file Open file handle |
1431 | @param[out] buf buffer where to read |
1432 | @param[in] offset file offset where to read |
1433 | @param[in] n number of bytes to read |
1434 | @param[in] read_only if true read only mode checks are enforced |
1435 | @param[in,out] m1 Message for the AIO handler, (can be used to |
1436 | identify a completed AIO operation); ignored |
1437 | if mode is OS_AIO_SYNC |
1438 | @param[in,out] m2 message for the AIO handler (can be used to |
1439 | identify a completed AIO operation); ignored |
1440 | if mode is OS_AIO_SYNC |
1441 | @return DB_SUCCESS or error code */ |
1442 | dberr_t |
1443 | os_aio_func( |
1444 | IORequest& type, |
1445 | ulint mode, |
1446 | const char* name, |
1447 | pfs_os_file_t file, |
1448 | void* buf, |
1449 | os_offset_t offset, |
1450 | ulint n, |
1451 | bool read_only, |
1452 | fil_node_t* m1, |
1453 | void* m2); |
1454 | |
1455 | /** Wakes up all async i/o threads so that they know to exit themselves in |
1456 | shutdown. */ |
1457 | void |
1458 | os_aio_wake_all_threads_at_shutdown(); |
1459 | |
1460 | /** Waits until there are no pending writes in os_aio_write_array. There can |
1461 | be other, synchronous, pending writes. */ |
1462 | void |
1463 | os_aio_wait_until_no_pending_writes(); |
1464 | |
1465 | /** Wakes up simulated aio i/o-handler threads if they have something to do. */ |
1466 | void |
1467 | os_aio_simulated_wake_handler_threads(); |
1468 | |
1469 | #ifdef _WIN32 |
1470 | /** This function can be called if one wants to post a batch of reads and |
1471 | prefers an i/o-handler thread to handle them all at once later. You must |
1472 | call os_aio_simulated_wake_handler_threads later to ensure the threads |
1473 | are not left sleeping! */ |
1474 | void |
1475 | os_aio_simulated_put_read_threads_to_sleep(); |
1476 | #else /* _WIN32 */ |
1477 | # define os_aio_simulated_put_read_threads_to_sleep() |
1478 | #endif /* _WIN32 */ |
1479 | |
1480 | /** This is the generic AIO handler interface function. |
1481 | Waits for an aio operation to complete. This function is used to wait the |
1482 | for completed requests. The AIO array of pending requests is divided |
1483 | into segments. The thread specifies which segment or slot it wants to wait |
1484 | for. NOTE: this function will also take care of freeing the aio slot, |
1485 | therefore no other thread is allowed to do the freeing! |
1486 | @param[in] segment the number of the segment in the aio arrays to |
1487 | wait for; segment 0 is the ibuf I/O thread, |
1488 | segment 1 the log I/O thread, then follow the |
1489 | non-ibuf read threads, and as the last are the |
1490 | non-ibuf write threads; if this is |
1491 | ULINT_UNDEFINED, then it means that sync AIO |
1492 | is used, and this parameter is ignored |
1493 | @param[out] m1 the messages passed with the AIO request; |
1494 | note that also in the case where the AIO |
1495 | operation failed, these output parameters |
1496 | are valid and can be used to restart the |
1497 | operation, for example |
1498 | @param[out] m2 callback message |
1499 | @param[out] type OS_FILE_WRITE or ..._READ |
1500 | @return DB_SUCCESS or error code */ |
1501 | dberr_t |
1502 | os_aio_handler( |
1503 | ulint segment, |
1504 | fil_node_t** m1, |
1505 | void** m2, |
1506 | IORequest* type); |
1507 | |
1508 | /** Prints info of the aio arrays. |
1509 | @param[in/out] file file where to print */ |
1510 | void |
1511 | os_aio_print(FILE* file); |
1512 | |
1513 | /** Refreshes the statistics used to print per-second averages. */ |
1514 | void |
1515 | os_aio_refresh_stats(); |
1516 | |
1517 | /** Checks that all slots in the system have been freed, that is, there are |
1518 | no pending io operations. */ |
1519 | bool |
1520 | os_aio_all_slots_free(); |
1521 | |
1522 | #ifdef UNIV_DEBUG |
1523 | |
1524 | /** Prints all pending IO |
1525 | @param[in] file file where to print */ |
1526 | void |
1527 | os_aio_print_pending_io(FILE* file); |
1528 | |
1529 | #endif /* UNIV_DEBUG */ |
1530 | |
1531 | /** This function returns information about the specified file |
1532 | @param[in] path pathname of the file |
1533 | @param[in] stat_info information of a file in a directory |
1534 | @param[in] check_rw_perm for testing whether the file can be opened |
1535 | in RW mode |
1536 | @param[in] read_only if true read only mode checks are enforced |
1537 | @return DB_SUCCESS if all OK */ |
1538 | dberr_t |
1539 | os_file_get_status( |
1540 | const char* path, |
1541 | os_file_stat_t* stat_info, |
1542 | bool check_rw_perm, |
1543 | bool read_only); |
1544 | |
1545 | /** Creates a temporary file in the location specified by the parameter |
1546 | path. If the path is NULL then it will be created on --tmpdir location. |
1547 | This function is defined in ha_innodb.cc. |
1548 | @param[in] path location for creating temporary file |
1549 | @return temporary file descriptor, or < 0 on error */ |
1550 | os_file_t |
1551 | innobase_mysql_tmpfile( |
1552 | const char* path); |
1553 | |
1554 | /** Set the file create umask |
1555 | @param[in] umask The umask to use for file creation. */ |
1556 | void |
1557 | os_file_set_umask(ulint umask); |
1558 | |
1559 | #ifdef _WIN32 |
1560 | |
1561 | /** |
1562 | Make file sparse, on Windows. |
1563 | |
1564 | @param[in] file file handle |
1565 | @param[in] is_sparse if true, make file sparse, |
1566 | otherwise "unsparse" the file |
1567 | @return true on success, false on error */ |
1568 | bool os_file_set_sparse_win32(os_file_t file, bool is_sparse = true); |
1569 | |
1570 | /** |
1571 | Changes file size on Windows |
1572 | |
1573 | If file is extended, following happens the bytes between |
1574 | old and new EOF are zeros. |
1575 | |
1576 | If file is sparse, "virtual" block is added at the end of |
1577 | allocated area. |
1578 | |
1579 | If file is normal, file system allocates storage. |
1580 | |
1581 | @param[in] pathname file path |
1582 | @param[in] file file handle |
1583 | @param[in] size size to preserve in bytes |
1584 | @return true if success */ |
1585 | bool |
1586 | os_file_change_size_win32( |
1587 | const char* pathname, |
1588 | os_file_t file, |
1589 | os_offset_t size); |
1590 | |
1591 | #endif /*_WIN32 */ |
1592 | |
1593 | /** Check if the file system supports sparse files. |
1594 | |
1595 | Warning: On POSIX systems we try and punch a hole from offset 0 to |
1596 | the system configured page size. This should only be called on an empty |
1597 | file. |
1598 | |
1599 | @param[in] fh File handle for the file - if opened |
1600 | @return true if the file system supports sparse files */ |
1601 | bool |
1602 | os_is_sparse_file_supported( |
1603 | os_file_t fh) |
1604 | MY_ATTRIBUTE((warn_unused_result)); |
1605 | |
1606 | /** Free storage space associated with a section of the file. |
1607 | @param[in] fh Open file handle |
1608 | @param[in] off Starting offset (SEEK_SET) |
1609 | @param[in] len Size of the hole |
1610 | @return DB_SUCCESS or error code */ |
1611 | dberr_t |
1612 | os_file_punch_hole( |
1613 | os_file_t fh, |
1614 | os_offset_t off, |
1615 | os_offset_t len) |
1616 | MY_ATTRIBUTE((warn_unused_result)); |
1617 | |
1618 | /** Normalizes a directory path for the current OS: |
1619 | On Windows, we convert '/' to '\', else we convert '\' to '/'. |
1620 | @param[in,out] str A null-terminated directory and file path */ |
1621 | void os_normalize_path(char* str); |
1622 | |
1623 | /* Determine if a path is an absolute path or not. |
1624 | @param[in] OS directory or file path to evaluate |
1625 | @retval true if an absolute path |
1626 | @retval false if a relative path */ |
1627 | UNIV_INLINE |
1628 | bool |
1629 | is_absolute_path( |
1630 | const char* path) |
1631 | { |
1632 | if (path[0] == OS_PATH_SEPARATOR) { |
1633 | return(true); |
1634 | } |
1635 | |
1636 | #ifdef _WIN32 |
1637 | if (path[1] == ':' && path[2] == OS_PATH_SEPARATOR) { |
1638 | return(true); |
1639 | } |
1640 | #endif /* _WIN32 */ |
1641 | |
1642 | return(false); |
1643 | } |
1644 | |
1645 | /***********************************************************************//** |
1646 | Try to get number of bytes per sector from file system. |
1647 | @return file block size */ |
1648 | UNIV_INTERN |
1649 | ulint |
1650 | os_file_get_block_size( |
1651 | /*===================*/ |
1652 | os_file_t file, /*!< in: handle to a file */ |
1653 | const char* name); /*!< in: file name */ |
1654 | |
1655 | #include "os0file.ic" |
1656 | |
1657 | #endif /* os0file_h */ |
1658 | |