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