~ubuntu-branches/ubuntu/precise/mysql-5.5/precise-201203300109

« back to all changes in this revision

Viewing changes to storage/innobase/os/os0file.c

  • Committer: Package Import Robot
  • Author(s): Clint Byrum
  • Date: 2011-11-08 11:31:13 UTC
  • Revision ID: package-import@ubuntu.com-20111108113113-3ulw01fvi4vn8m25
Tags: upstream-5.5.17
ImportĀ upstreamĀ versionĀ 5.5.17

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/***********************************************************************
 
2
 
 
3
Copyright (c) 1995, 2010, Innobase Oy. All Rights Reserved.
 
4
Copyright (c) 2009, Percona Inc.
 
5
 
 
6
Portions of this file contain modifications contributed and copyrighted
 
7
by Percona Inc.. Those modifications are
 
8
gratefully acknowledged and are described briefly in the InnoDB
 
9
documentation. The contributions by Percona Inc. are incorporated with
 
10
their permission, and subject to the conditions contained in the file
 
11
COPYING.Percona.
 
12
 
 
13
This program is free software; you can redistribute it and/or modify it
 
14
under the terms of the GNU General Public License as published by the
 
15
Free Software Foundation; version 2 of the License.
 
16
 
 
17
This program is distributed in the hope that it will be useful, but
 
18
WITHOUT ANY WARRANTY; without even the implied warranty of
 
19
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
 
20
Public License for more details.
 
21
 
 
22
You should have received a copy of the GNU General Public License along
 
23
with this program; if not, write to the Free Software Foundation, Inc.,
 
24
59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 
25
 
 
26
***********************************************************************/
 
27
 
 
28
/**************************************************//**
 
29
@file os/os0file.c
 
30
The interface to the operating system file i/o primitives
 
31
 
 
32
Created 10/21/1995 Heikki Tuuri
 
33
*******************************************************/
 
34
 
 
35
#include "os0file.h"
 
36
 
 
37
#ifdef UNIV_NONINL
 
38
#include "os0file.ic"
 
39
#endif
 
40
 
 
41
#include "ut0mem.h"
 
42
#include "srv0srv.h"
 
43
#include "srv0start.h"
 
44
#include "fil0fil.h"
 
45
#include "buf0buf.h"
 
46
#ifndef UNIV_HOTBACKUP
 
47
# include "os0sync.h"
 
48
# include "os0thread.h"
 
49
#else /* !UNIV_HOTBACKUP */
 
50
# ifdef __WIN__
 
51
/* Add includes for the _stat() call to compile on Windows */
 
52
#  include <sys/types.h>
 
53
#  include <sys/stat.h>
 
54
#  include <errno.h>
 
55
# endif /* __WIN__ */
 
56
#endif /* !UNIV_HOTBACKUP */
 
57
 
 
58
#if defined(LINUX_NATIVE_AIO)
 
59
#include <libaio.h>
 
60
#endif
 
61
 
 
62
/* This specifies the file permissions InnoDB uses when it creates files in
 
63
Unix; the value of os_innodb_umask is initialized in ha_innodb.cc to
 
64
my_umask */
 
65
 
 
66
#ifndef __WIN__
 
67
/** Umask for creating files */
 
68
UNIV_INTERN ulint       os_innodb_umask
 
69
                        = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP;
 
70
#else
 
71
/** Umask for creating files */
 
72
UNIV_INTERN ulint       os_innodb_umask         = 0;
 
73
#endif
 
74
 
 
75
#ifdef UNIV_DO_FLUSH
 
76
/* If the following is set to TRUE, we do not call os_file_flush in every
 
77
os_file_write. We can set this TRUE when the doublewrite buffer is used. */
 
78
UNIV_INTERN ibool       os_do_not_call_flush_at_each_write      = FALSE;
 
79
#else
 
80
/* We do not call os_file_flush in every os_file_write. */
 
81
#endif /* UNIV_DO_FLUSH */
 
82
 
 
83
#ifndef UNIV_HOTBACKUP
 
84
/* We use these mutexes to protect lseek + file i/o operation, if the
 
85
OS does not provide an atomic pread or pwrite, or similar */
 
86
#define OS_FILE_N_SEEK_MUTEXES  16
 
87
UNIV_INTERN os_mutex_t  os_file_seek_mutexes[OS_FILE_N_SEEK_MUTEXES];
 
88
 
 
89
/* In simulated aio, merge at most this many consecutive i/os */
 
90
#define OS_AIO_MERGE_N_CONSECUTIVE      64
 
91
 
 
92
/**********************************************************************
 
93
 
 
94
InnoDB AIO Implementation:
 
95
=========================
 
96
 
 
97
We support native AIO for windows and linux. For rest of the platforms
 
98
we simulate AIO by special io-threads servicing the IO-requests.
 
99
 
 
100
Simulated AIO:
 
101
==============
 
102
 
 
103
In platforms where we 'simulate' AIO following is a rough explanation
 
104
of the high level design.
 
105
There are four io-threads (for ibuf, log, read, write).
 
106
All synchronous IO requests are serviced by the calling thread using
 
107
os_file_write/os_file_read. The Asynchronous requests are queued up
 
108
in an array (there are four such arrays) by the calling thread. 
 
109
Later these requests are picked up by the io-thread and are serviced
 
110
synchronously.
 
111
 
 
112
Windows native AIO:
 
113
==================
 
114
 
 
115
If srv_use_native_aio is not set then windows follow the same
 
116
code as simulated AIO. If the flag is set then native AIO interface
 
117
is used. On windows, one of the limitation is that if a file is opened
 
118
for AIO no synchronous IO can be done on it. Therefore we have an
 
119
extra fifth array to queue up synchronous IO requests.
 
120
There are innodb_file_io_threads helper threads. These threads work
 
121
on the four arrays mentioned above in Simulated AIO. No thread is
 
122
required for the sync array.
 
123
If a synchronous IO request is made, it is first queued in the sync
 
124
array. Then the calling thread itself waits on the request, thus
 
125
making the call synchronous.
 
126
If an AIO request is made the calling thread not only queues it in the
 
127
array but also submits the requests. The helper thread then collects
 
128
the completed IO request and calls completion routine on it.
 
129
 
 
130
Linux native AIO:
 
131
=================
 
132
 
 
133
If we have libaio installed on the system and innodb_use_native_aio
 
134
is set to TRUE we follow the code path of native AIO, otherwise we
 
135
do simulated AIO.
 
136
There are innodb_file_io_threads helper threads. These threads work
 
137
on the four arrays mentioned above in Simulated AIO.
 
138
If a synchronous IO request is made, it is handled by calling
 
139
os_file_write/os_file_read.
 
140
If an AIO request is made the calling thread not only queues it in the
 
141
array but also submits the requests. The helper thread then collects
 
142
the completed IO request and calls completion routine on it.
 
143
 
 
144
**********************************************************************/
 
145
 
 
146
/** Flag: enable debug printout for asynchronous i/o */
 
147
UNIV_INTERN ibool       os_aio_print_debug      = FALSE;
 
148
 
 
149
#ifdef UNIV_PFS_IO
 
150
/* Keys to register InnoDB I/O with performance schema */
 
151
UNIV_INTERN mysql_pfs_key_t  innodb_file_data_key;
 
152
UNIV_INTERN mysql_pfs_key_t  innodb_file_log_key;
 
153
UNIV_INTERN mysql_pfs_key_t  innodb_file_temp_key;
 
154
#endif /* UNIV_PFS_IO */
 
155
 
 
156
/** The asynchronous i/o array slot structure */
 
157
typedef struct os_aio_slot_struct       os_aio_slot_t;
 
158
 
 
159
/** The asynchronous i/o array slot structure */
 
160
struct os_aio_slot_struct{
 
161
        ibool           is_read;        /*!< TRUE if a read operation */
 
162
        ulint           pos;            /*!< index of the slot in the aio
 
163
                                        array */
 
164
        ibool           reserved;       /*!< TRUE if this slot is reserved */
 
165
        time_t          reservation_time;/*!< time when reserved */
 
166
        ulint           len;            /*!< length of the block to read or
 
167
                                        write */
 
168
        byte*           buf;            /*!< buffer used in i/o */
 
169
        ulint           type;           /*!< OS_FILE_READ or OS_FILE_WRITE */
 
170
        ulint           offset;         /*!< 32 low bits of file offset in
 
171
                                        bytes */
 
172
        ulint           offset_high;    /*!< 32 high bits of file offset */
 
173
        os_file_t       file;           /*!< file where to read or write */
 
174
        const char*     name;           /*!< file name or path */
 
175
        ibool           io_already_done;/*!< used only in simulated aio:
 
176
                                        TRUE if the physical i/o already
 
177
                                        made and only the slot message
 
178
                                        needs to be passed to the caller
 
179
                                        of os_aio_simulated_handle */
 
180
        fil_node_t*     message1;       /*!< message which is given by the */
 
181
        void*           message2;       /*!< the requester of an aio operation
 
182
                                        and which can be used to identify
 
183
                                        which pending aio operation was
 
184
                                        completed */
 
185
#ifdef WIN_ASYNC_IO
 
186
        HANDLE          handle;         /*!< handle object we need in the
 
187
                                        OVERLAPPED struct */
 
188
        OVERLAPPED      control;        /*!< Windows control block for the
 
189
                                        aio request */
 
190
#elif defined(LINUX_NATIVE_AIO)
 
191
        struct iocb     control;        /* Linux control block for aio */
 
192
        int             n_bytes;        /* bytes written/read. */
 
193
        int             ret;            /* AIO return code */
 
194
#endif
 
195
};
 
196
 
 
197
/** The asynchronous i/o array structure */
 
198
typedef struct os_aio_array_struct      os_aio_array_t;
 
199
 
 
200
/** The asynchronous i/o array structure */
 
201
struct os_aio_array_struct{
 
202
        os_mutex_t      mutex;  /*!< the mutex protecting the aio array */
 
203
        os_event_t      not_full;
 
204
                                /*!< The event which is set to the
 
205
                                signaled state when there is space in
 
206
                                the aio outside the ibuf segment */
 
207
        os_event_t      is_empty;
 
208
                                /*!< The event which is set to the
 
209
                                signaled state when there are no
 
210
                                pending i/os in this array */
 
211
        ulint           n_slots;/*!< Total number of slots in the aio
 
212
                                array.  This must be divisible by
 
213
                                n_threads. */
 
214
        ulint           n_segments;
 
215
                                /*!< Number of segments in the aio
 
216
                                array of pending aio requests. A
 
217
                                thread can wait separately for any one
 
218
                                of the segments. */
 
219
        ulint           cur_seg;/*!< We reserve IO requests in round
 
220
                                robin fashion to different segments.
 
221
                                This points to the segment that is to
 
222
                                be used to service next IO request. */
 
223
        ulint           n_reserved;
 
224
                                /*!< Number of reserved slots in the
 
225
                                aio array outside the ibuf segment */
 
226
        os_aio_slot_t*  slots;  /*!< Pointer to the slots in the array */
 
227
#ifdef __WIN__
 
228
        HANDLE*         handles;
 
229
                                /*!< Pointer to an array of OS native
 
230
                                event handles where we copied the
 
231
                                handles from slots, in the same
 
232
                                order. This can be used in
 
233
                                WaitForMultipleObjects; used only in
 
234
                                Windows */
 
235
#endif
 
236
 
 
237
#if defined(LINUX_NATIVE_AIO)
 
238
        io_context_t*           aio_ctx;
 
239
                                /* completion queue for IO. There is 
 
240
                                one such queue per segment. Each thread
 
241
                                will work on one ctx exclusively. */
 
242
        struct io_event*        aio_events;
 
243
                                /* The array to collect completed IOs.
 
244
                                There is one such event for each
 
245
                                possible pending IO. The size of the
 
246
                                array is equal to n_slots. */
 
247
#endif
 
248
};
 
249
 
 
250
#if defined(LINUX_NATIVE_AIO)
 
251
/** timeout for each io_getevents() call = 500ms. */
 
252
#define OS_AIO_REAP_TIMEOUT     (500000000UL)
 
253
 
 
254
/** time to sleep, in microseconds if io_setup() returns EAGAIN. */
 
255
#define OS_AIO_IO_SETUP_RETRY_SLEEP     (500000UL)
 
256
 
 
257
/** number of attempts before giving up on io_setup(). */
 
258
#define OS_AIO_IO_SETUP_RETRY_ATTEMPTS  5
 
259
#endif
 
260
 
 
261
/** Array of events used in simulated aio */
 
262
static os_event_t*      os_aio_segment_wait_events      = NULL;
 
263
 
 
264
/** The aio arrays for non-ibuf i/o and ibuf i/o, as well as sync aio. These
 
265
are NULL when the module has not yet been initialized. @{ */
 
266
static os_aio_array_t*  os_aio_read_array       = NULL; /*!< Reads */
 
267
static os_aio_array_t*  os_aio_write_array      = NULL; /*!< Writes */
 
268
static os_aio_array_t*  os_aio_ibuf_array       = NULL; /*!< Insert buffer */
 
269
static os_aio_array_t*  os_aio_log_array        = NULL; /*!< Redo log */
 
270
static os_aio_array_t*  os_aio_sync_array       = NULL; /*!< Synchronous I/O */
 
271
/* @} */
 
272
 
 
273
/** Number of asynchronous I/O segments.  Set by os_aio_init(). */
 
274
static ulint    os_aio_n_segments       = ULINT_UNDEFINED;
 
275
 
 
276
/** If the following is TRUE, read i/o handler threads try to
 
277
wait until a batch of new read requests have been posted */
 
278
static ibool    os_aio_recommend_sleep_for_read_threads = FALSE;
 
279
#endif /* !UNIV_HOTBACKUP */
 
280
 
 
281
UNIV_INTERN ulint       os_n_file_reads         = 0;
 
282
UNIV_INTERN ulint       os_bytes_read_since_printout = 0;
 
283
UNIV_INTERN ulint       os_n_file_writes        = 0;
 
284
UNIV_INTERN ulint       os_n_fsyncs             = 0;
 
285
UNIV_INTERN ulint       os_n_file_reads_old     = 0;
 
286
UNIV_INTERN ulint       os_n_file_writes_old    = 0;
 
287
UNIV_INTERN ulint       os_n_fsyncs_old         = 0;
 
288
UNIV_INTERN time_t      os_last_printout;
 
289
 
 
290
UNIV_INTERN ibool       os_has_said_disk_full   = FALSE;
 
291
 
 
292
#ifndef UNIV_HOTBACKUP
 
293
/** The mutex protecting the following counts of pending I/O operations */
 
294
static os_mutex_t       os_file_count_mutex;
 
295
#endif /* !UNIV_HOTBACKUP */
 
296
/** Number of pending os_file_pread() operations */
 
297
UNIV_INTERN ulint       os_file_n_pending_preads  = 0;
 
298
/** Number of pending os_file_pwrite() operations */
 
299
UNIV_INTERN ulint       os_file_n_pending_pwrites = 0;
 
300
/** Number of pending write operations */
 
301
UNIV_INTERN ulint       os_n_pending_writes = 0;
 
302
/** Number of pending read operations */
 
303
UNIV_INTERN ulint       os_n_pending_reads = 0;
 
304
 
 
305
#ifdef UNIV_DEBUG
 
306
/**********************************************************************//**
 
307
Validates the consistency the aio system some of the time.
 
308
@return TRUE if ok or the check was skipped */
 
309
UNIV_INTERN
 
310
ibool
 
311
os_aio_validate_skip(void)
 
312
/*======================*/
 
313
{
 
314
/** Try os_aio_validate() every this many times */
 
315
# define OS_AIO_VALIDATE_SKIP   13
 
316
 
 
317
        /** The os_aio_validate() call skip counter.
 
318
        Use a signed type because of the race condition below. */
 
319
        static int os_aio_validate_count = OS_AIO_VALIDATE_SKIP;
 
320
 
 
321
        /* There is a race condition below, but it does not matter,
 
322
        because this call is only for heuristic purposes. We want to
 
323
        reduce the call frequency of the costly os_aio_validate()
 
324
        check in debug builds. */
 
325
        if (--os_aio_validate_count > 0) {
 
326
                return(TRUE);
 
327
        }
 
328
 
 
329
        os_aio_validate_count = OS_AIO_VALIDATE_SKIP;
 
330
        return(os_aio_validate());
 
331
}
 
332
#endif /* UNIV_DEBUG */
 
333
 
 
334
#ifdef __WIN__
 
335
/***********************************************************************//**
 
336
Gets the operating system version. Currently works only on Windows.
 
337
@return OS_WIN95, OS_WIN31, OS_WINNT, OS_WIN2000, OS_WINXP, OS_WINVISTA,
 
338
OS_WIN7. */
 
339
UNIV_INTERN
 
340
ulint
 
341
os_get_os_version(void)
 
342
/*===================*/
 
343
{
 
344
        OSVERSIONINFO     os_info;
 
345
 
 
346
        os_info.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
 
347
 
 
348
        ut_a(GetVersionEx(&os_info));
 
349
 
 
350
        if (os_info.dwPlatformId == VER_PLATFORM_WIN32s) {
 
351
                return(OS_WIN31);
 
352
        } else if (os_info.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS) {
 
353
                return(OS_WIN95);
 
354
        } else if (os_info.dwPlatformId == VER_PLATFORM_WIN32_NT) {
 
355
                switch (os_info.dwMajorVersion) {
 
356
                case 3:
 
357
                case 4:
 
358
                        return OS_WINNT;
 
359
                case 5:
 
360
                        return (os_info.dwMinorVersion == 0) ? OS_WIN2000
 
361
                                                             : OS_WINXP;
 
362
                case 6:
 
363
                        return (os_info.dwMinorVersion == 0) ? OS_WINVISTA
 
364
                                                             : OS_WIN7;
 
365
                default:
 
366
                        return OS_WIN7;
 
367
                }
 
368
        } else {
 
369
                ut_error;
 
370
                return(0);
 
371
        }
 
372
}
 
373
#endif /* __WIN__ */
 
374
 
 
375
/***********************************************************************//**
 
376
Retrieves the last error number if an error occurs in a file io function.
 
377
The number should be retrieved before any other OS calls (because they may
 
378
overwrite the error number). If the number is not known to this program,
 
379
the OS error number + 100 is returned.
 
380
@return error number, or OS error number + 100 */
 
381
UNIV_INTERN
 
382
ulint
 
383
os_file_get_last_error(
 
384
/*===================*/
 
385
        ibool   report_all_errors)      /*!< in: TRUE if we want an error message
 
386
                                        printed of all errors */
 
387
{
 
388
        ulint   err;
 
389
 
 
390
#ifdef __WIN__
 
391
 
 
392
        err = (ulint) GetLastError();
 
393
 
 
394
        if (report_all_errors
 
395
            || (err != ERROR_DISK_FULL && err != ERROR_FILE_EXISTS)) {
 
396
 
 
397
                ut_print_timestamp(stderr);
 
398
                fprintf(stderr,
 
399
                        "  InnoDB: Operating system error number %lu"
 
400
                        " in a file operation.\n", (ulong) err);
 
401
 
 
402
                if (err == ERROR_PATH_NOT_FOUND) {
 
403
                        fprintf(stderr,
 
404
                                "InnoDB: The error means the system"
 
405
                                " cannot find the path specified.\n");
 
406
 
 
407
                        if (srv_is_being_started) {
 
408
                                fprintf(stderr,
 
409
                                        "InnoDB: If you are installing InnoDB,"
 
410
                                        " remember that you must create\n"
 
411
                                        "InnoDB: directories yourself, InnoDB"
 
412
                                        " does not create them.\n");
 
413
                        }
 
414
                } else if (err == ERROR_ACCESS_DENIED) {
 
415
                        fprintf(stderr,
 
416
                                "InnoDB: The error means mysqld does not have"
 
417
                                " the access rights to\n"
 
418
                                "InnoDB: the directory. It may also be"
 
419
                                " you have created a subdirectory\n"
 
420
                                "InnoDB: of the same name as a data file.\n");
 
421
                } else if (err == ERROR_SHARING_VIOLATION
 
422
                           || err == ERROR_LOCK_VIOLATION) {
 
423
                        fprintf(stderr,
 
424
                                "InnoDB: The error means that another program"
 
425
                                " is using InnoDB's files.\n"
 
426
                                "InnoDB: This might be a backup or antivirus"
 
427
                                " software or another instance\n"
 
428
                                "InnoDB: of MySQL."
 
429
                                " Please close it to get rid of this error.\n");
 
430
                } else if (err == ERROR_WORKING_SET_QUOTA
 
431
                           || err == ERROR_NO_SYSTEM_RESOURCES) {
 
432
                        fprintf(stderr,
 
433
                                "InnoDB: The error means that there are no"
 
434
                                " sufficient system resources or quota to"
 
435
                                " complete the operation.\n");
 
436
                } else if (err == ERROR_OPERATION_ABORTED) {
 
437
                        fprintf(stderr,
 
438
                                "InnoDB: The error means that the I/O"
 
439
                                " operation has been aborted\n"
 
440
                                "InnoDB: because of either a thread exit"
 
441
                                " or an application request.\n"
 
442
                                "InnoDB: Retry attempt is made.\n");
 
443
                } else {
 
444
                        fprintf(stderr,
 
445
                                "InnoDB: Some operating system error numbers"
 
446
                                " are described at\n"
 
447
                                "InnoDB: "
 
448
                                REFMAN
 
449
                                "operating-system-error-codes.html\n");
 
450
                }
 
451
        }
 
452
 
 
453
        fflush(stderr);
 
454
 
 
455
        if (err == ERROR_FILE_NOT_FOUND) {
 
456
                return(OS_FILE_NOT_FOUND);
 
457
        } else if (err == ERROR_DISK_FULL) {
 
458
                return(OS_FILE_DISK_FULL);
 
459
        } else if (err == ERROR_FILE_EXISTS) {
 
460
                return(OS_FILE_ALREADY_EXISTS);
 
461
        } else if (err == ERROR_SHARING_VIOLATION
 
462
                   || err == ERROR_LOCK_VIOLATION) {
 
463
                return(OS_FILE_SHARING_VIOLATION);
 
464
        } else if (err == ERROR_WORKING_SET_QUOTA
 
465
                   || err == ERROR_NO_SYSTEM_RESOURCES) {
 
466
                return(OS_FILE_INSUFFICIENT_RESOURCE);
 
467
        } else if (err == ERROR_OPERATION_ABORTED) {
 
468
                return(OS_FILE_OPERATION_ABORTED);
 
469
        } else {
 
470
                return(100 + err);
 
471
        }
 
472
#else
 
473
        err = (ulint) errno;
 
474
 
 
475
        if (report_all_errors
 
476
            || (err != ENOSPC && err != EEXIST)) {
 
477
 
 
478
                ut_print_timestamp(stderr);
 
479
                fprintf(stderr,
 
480
                        "  InnoDB: Operating system error number %lu"
 
481
                        " in a file operation.\n", (ulong) err);
 
482
 
 
483
                if (err == ENOENT) {
 
484
                        fprintf(stderr,
 
485
                                "InnoDB: The error means the system"
 
486
                                " cannot find the path specified.\n");
 
487
 
 
488
                        if (srv_is_being_started) {
 
489
                                fprintf(stderr,
 
490
                                        "InnoDB: If you are installing InnoDB,"
 
491
                                        " remember that you must create\n"
 
492
                                        "InnoDB: directories yourself, InnoDB"
 
493
                                        " does not create them.\n");
 
494
                        }
 
495
                } else if (err == EACCES) {
 
496
                        fprintf(stderr,
 
497
                                "InnoDB: The error means mysqld does not have"
 
498
                                " the access rights to\n"
 
499
                                "InnoDB: the directory.\n");
 
500
                } else {
 
501
                        if (strerror((int)err) != NULL) {
 
502
                                fprintf(stderr,
 
503
                                        "InnoDB: Error number %lu"
 
504
                                        " means '%s'.\n",
 
505
                                        err, strerror((int)err));
 
506
                        }
 
507
 
 
508
                        fprintf(stderr,
 
509
                                "InnoDB: Some operating system"
 
510
                                " error numbers are described at\n"
 
511
                                "InnoDB: "
 
512
                                REFMAN
 
513
                                "operating-system-error-codes.html\n");
 
514
                }
 
515
        }
 
516
 
 
517
        fflush(stderr);
 
518
 
 
519
        switch (err) {
 
520
        case ENOSPC:
 
521
                return(OS_FILE_DISK_FULL);
 
522
        case ENOENT:
 
523
                return(OS_FILE_NOT_FOUND);
 
524
        case EEXIST:
 
525
                return(OS_FILE_ALREADY_EXISTS);
 
526
        case EXDEV:
 
527
        case ENOTDIR:
 
528
        case EISDIR:
 
529
                return(OS_FILE_PATH_ERROR);
 
530
        case EAGAIN:
 
531
                if (srv_use_native_aio) {
 
532
                        return(OS_FILE_AIO_RESOURCES_RESERVED);
 
533
                }
 
534
                break;
 
535
        case EINTR:
 
536
                if (srv_use_native_aio) {
 
537
                        return(OS_FILE_AIO_INTERRUPTED);
 
538
                }
 
539
                break;
 
540
        }
 
541
        return(100 + err);
 
542
#endif
 
543
}
 
544
 
 
545
/****************************************************************//**
 
546
Does error handling when a file operation fails.
 
547
Conditionally exits (calling exit(3)) based on should_exit value and the
 
548
error type
 
549
@return TRUE if we should retry the operation */
 
550
static
 
551
ibool
 
552
os_file_handle_error_cond_exit(
 
553
/*===========================*/
 
554
        const char*     name,           /*!< in: name of a file or NULL */
 
555
        const char*     operation,      /*!< in: operation */
 
556
        ibool           should_exit)    /*!< in: call exit(3) if unknown error
 
557
                                        and this parameter is TRUE */
 
558
{
 
559
        ulint   err;
 
560
 
 
561
        err = os_file_get_last_error(FALSE);
 
562
 
 
563
        if (err == OS_FILE_DISK_FULL) {
 
564
                /* We only print a warning about disk full once */
 
565
 
 
566
                if (os_has_said_disk_full) {
 
567
 
 
568
                        return(FALSE);
 
569
                }
 
570
 
 
571
                if (name) {
 
572
                        ut_print_timestamp(stderr);
 
573
                        fprintf(stderr,
 
574
                                "  InnoDB: Encountered a problem with"
 
575
                                " file %s\n", name);
 
576
                }
 
577
 
 
578
                ut_print_timestamp(stderr);
 
579
                fprintf(stderr,
 
580
                        "  InnoDB: Disk is full. Try to clean the disk"
 
581
                        " to free space.\n");
 
582
 
 
583
                os_has_said_disk_full = TRUE;
 
584
 
 
585
                fflush(stderr);
 
586
 
 
587
                return(FALSE);
 
588
        } else if (err == OS_FILE_AIO_RESOURCES_RESERVED) {
 
589
 
 
590
                return(TRUE);
 
591
        } else if (err == OS_FILE_AIO_INTERRUPTED) {
 
592
 
 
593
                return(TRUE);
 
594
        } else if (err == OS_FILE_ALREADY_EXISTS
 
595
                   || err == OS_FILE_PATH_ERROR) {
 
596
 
 
597
                return(FALSE);
 
598
        } else if (err == OS_FILE_SHARING_VIOLATION) {
 
599
 
 
600
                os_thread_sleep(10000000);  /* 10 sec */
 
601
                return(TRUE);
 
602
        } else if (err == OS_FILE_INSUFFICIENT_RESOURCE) {
 
603
 
 
604
                os_thread_sleep(100000);        /* 100 ms */
 
605
                return(TRUE);
 
606
        } else if (err == OS_FILE_OPERATION_ABORTED) {
 
607
 
 
608
                os_thread_sleep(100000);        /* 100 ms */
 
609
                return(TRUE);
 
610
        } else {
 
611
                if (name) {
 
612
                        fprintf(stderr, "InnoDB: File name %s\n", name);
 
613
                }
 
614
 
 
615
                fprintf(stderr, "InnoDB: File operation call: '%s'.\n",
 
616
                        operation);
 
617
 
 
618
                if (should_exit) {
 
619
                        fprintf(stderr, "InnoDB: Cannot continue operation.\n");
 
620
 
 
621
                        fflush(stderr);
 
622
 
 
623
                        exit(1);
 
624
                }
 
625
        }
 
626
 
 
627
        return(FALSE);
 
628
}
 
629
 
 
630
/****************************************************************//**
 
631
Does error handling when a file operation fails.
 
632
@return TRUE if we should retry the operation */
 
633
static
 
634
ibool
 
635
os_file_handle_error(
 
636
/*=================*/
 
637
        const char*     name,   /*!< in: name of a file or NULL */
 
638
        const char*     operation)/*!< in: operation */
 
639
{
 
640
        /* exit in case of unknown error */
 
641
        return(os_file_handle_error_cond_exit(name, operation, TRUE));
 
642
}
 
643
 
 
644
/****************************************************************//**
 
645
Does error handling when a file operation fails.
 
646
@return TRUE if we should retry the operation */
 
647
static
 
648
ibool
 
649
os_file_handle_error_no_exit(
 
650
/*=========================*/
 
651
        const char*     name,   /*!< in: name of a file or NULL */
 
652
        const char*     operation)/*!< in: operation */
 
653
{
 
654
        /* don't exit in case of unknown error */
 
655
        return(os_file_handle_error_cond_exit(name, operation, FALSE));
 
656
}
 
657
 
 
658
#undef USE_FILE_LOCK
 
659
#define USE_FILE_LOCK
 
660
#if defined(UNIV_HOTBACKUP) || defined(__WIN__)
 
661
/* InnoDB Hot Backup does not lock the data files.
 
662
 * On Windows, mandatory locking is used.
 
663
 */
 
664
# undef USE_FILE_LOCK
 
665
#endif
 
666
#ifdef USE_FILE_LOCK
 
667
/****************************************************************//**
 
668
Obtain an exclusive lock on a file.
 
669
@return 0 on success */
 
670
static
 
671
int
 
672
os_file_lock(
 
673
/*=========*/
 
674
        int             fd,     /*!< in: file descriptor */
 
675
        const char*     name)   /*!< in: file name */
 
676
{
 
677
        struct flock lk;
 
678
        lk.l_type = F_WRLCK;
 
679
        lk.l_whence = SEEK_SET;
 
680
        lk.l_start = lk.l_len = 0;
 
681
        if (fcntl(fd, F_SETLK, &lk) == -1) {
 
682
                fprintf(stderr,
 
683
                        "InnoDB: Unable to lock %s, error: %d\n", name, errno);
 
684
 
 
685
                if (errno == EAGAIN || errno == EACCES) {
 
686
                        fprintf(stderr,
 
687
                                "InnoDB: Check that you do not already have"
 
688
                                " another mysqld process\n"
 
689
                                "InnoDB: using the same InnoDB data"
 
690
                                " or log files.\n");
 
691
                }
 
692
 
 
693
                return(-1);
 
694
        }
 
695
 
 
696
        return(0);
 
697
}
 
698
#endif /* USE_FILE_LOCK */
 
699
 
 
700
#ifndef UNIV_HOTBACKUP
 
701
/****************************************************************//**
 
702
Creates the seek mutexes used in positioned reads and writes. */
 
703
UNIV_INTERN
 
704
void
 
705
os_io_init_simple(void)
 
706
/*===================*/
 
707
{
 
708
        ulint   i;
 
709
 
 
710
        os_file_count_mutex = os_mutex_create();
 
711
 
 
712
        for (i = 0; i < OS_FILE_N_SEEK_MUTEXES; i++) {
 
713
                os_file_seek_mutexes[i] = os_mutex_create();
 
714
        }
 
715
}
 
716
 
 
717
/***********************************************************************//**
 
718
Creates a temporary file.  This function is like tmpfile(3), but
 
719
the temporary file is created in the MySQL temporary directory.
 
720
@return temporary file handle, or NULL on error */
 
721
UNIV_INTERN
 
722
FILE*
 
723
os_file_create_tmpfile(void)
 
724
/*========================*/
 
725
{
 
726
        FILE*   file    = NULL;
 
727
        int     fd      = innobase_mysql_tmpfile();
 
728
 
 
729
        if (fd >= 0) {
 
730
                file = fdopen(fd, "w+b");
 
731
        }
 
732
 
 
733
        if (!file) {
 
734
                ut_print_timestamp(stderr);
 
735
                fprintf(stderr,
 
736
                        "  InnoDB: Error: unable to create temporary file;"
 
737
                        " errno: %d\n", errno);
 
738
                if (fd >= 0) {
 
739
                        close(fd);
 
740
                }
 
741
        }
 
742
 
 
743
        return(file);
 
744
}
 
745
#endif /* !UNIV_HOTBACKUP */
 
746
 
 
747
/***********************************************************************//**
 
748
The os_file_opendir() function opens a directory stream corresponding to the
 
749
directory named by the dirname argument. The directory stream is positioned
 
750
at the first entry. In both Unix and Windows we automatically skip the '.'
 
751
and '..' items at the start of the directory listing.
 
752
@return directory stream, NULL if error */
 
753
UNIV_INTERN
 
754
os_file_dir_t
 
755
os_file_opendir(
 
756
/*============*/
 
757
        const char*     dirname,        /*!< in: directory name; it must not
 
758
                                        contain a trailing '\' or '/' */
 
759
        ibool           error_is_fatal) /*!< in: TRUE if we should treat an
 
760
                                        error as a fatal error; if we try to
 
761
                                        open symlinks then we do not wish a
 
762
                                        fatal error if it happens not to be
 
763
                                        a directory */
 
764
{
 
765
        os_file_dir_t           dir;
 
766
#ifdef __WIN__
 
767
        LPWIN32_FIND_DATA       lpFindFileData;
 
768
        char                    path[OS_FILE_MAX_PATH + 3];
 
769
 
 
770
        ut_a(strlen(dirname) < OS_FILE_MAX_PATH);
 
771
 
 
772
        strcpy(path, dirname);
 
773
        strcpy(path + strlen(path), "\\*");
 
774
 
 
775
        /* Note that in Windows opening the 'directory stream' also retrieves
 
776
        the first entry in the directory. Since it is '.', that is no problem,
 
777
        as we will skip over the '.' and '..' entries anyway. */
 
778
 
 
779
        lpFindFileData = ut_malloc(sizeof(WIN32_FIND_DATA));
 
780
 
 
781
        dir = FindFirstFile((LPCTSTR) path, lpFindFileData);
 
782
 
 
783
        ut_free(lpFindFileData);
 
784
 
 
785
        if (dir == INVALID_HANDLE_VALUE) {
 
786
 
 
787
                if (error_is_fatal) {
 
788
                        os_file_handle_error(dirname, "opendir");
 
789
                }
 
790
 
 
791
                return(NULL);
 
792
        }
 
793
 
 
794
        return(dir);
 
795
#else
 
796
        dir = opendir(dirname);
 
797
 
 
798
        if (dir == NULL && error_is_fatal) {
 
799
                os_file_handle_error(dirname, "opendir");
 
800
        }
 
801
 
 
802
        return(dir);
 
803
#endif
 
804
}
 
805
 
 
806
/***********************************************************************//**
 
807
Closes a directory stream.
 
808
@return 0 if success, -1 if failure */
 
809
UNIV_INTERN
 
810
int
 
811
os_file_closedir(
 
812
/*=============*/
 
813
        os_file_dir_t   dir)    /*!< in: directory stream */
 
814
{
 
815
#ifdef __WIN__
 
816
        BOOL            ret;
 
817
 
 
818
        ret = FindClose(dir);
 
819
 
 
820
        if (!ret) {
 
821
                os_file_handle_error_no_exit(NULL, "closedir");
 
822
 
 
823
                return(-1);
 
824
        }
 
825
 
 
826
        return(0);
 
827
#else
 
828
        int     ret;
 
829
 
 
830
        ret = closedir(dir);
 
831
 
 
832
        if (ret) {
 
833
                os_file_handle_error_no_exit(NULL, "closedir");
 
834
        }
 
835
 
 
836
        return(ret);
 
837
#endif
 
838
}
 
839
 
 
840
/***********************************************************************//**
 
841
This function returns information of the next file in the directory. We jump
 
842
over the '.' and '..' entries in the directory.
 
843
@return 0 if ok, -1 if error, 1 if at the end of the directory */
 
844
UNIV_INTERN
 
845
int
 
846
os_file_readdir_next_file(
 
847
/*======================*/
 
848
        const char*     dirname,/*!< in: directory name or path */
 
849
        os_file_dir_t   dir,    /*!< in: directory stream */
 
850
        os_file_stat_t* info)   /*!< in/out: buffer where the info is returned */
 
851
{
 
852
#ifdef __WIN__
 
853
        LPWIN32_FIND_DATA       lpFindFileData;
 
854
        BOOL                    ret;
 
855
 
 
856
        lpFindFileData = ut_malloc(sizeof(WIN32_FIND_DATA));
 
857
next_file:
 
858
        ret = FindNextFile(dir, lpFindFileData);
 
859
 
 
860
        if (ret) {
 
861
                ut_a(strlen((char *) lpFindFileData->cFileName)
 
862
                     < OS_FILE_MAX_PATH);
 
863
 
 
864
                if (strcmp((char *) lpFindFileData->cFileName, ".") == 0
 
865
                    || strcmp((char *) lpFindFileData->cFileName, "..") == 0) {
 
866
 
 
867
                        goto next_file;
 
868
                }
 
869
 
 
870
                strcpy(info->name, (char *) lpFindFileData->cFileName);
 
871
 
 
872
                info->size = (ib_int64_t)(lpFindFileData->nFileSizeLow)
 
873
                        + (((ib_int64_t)(lpFindFileData->nFileSizeHigh))
 
874
                           << 32);
 
875
 
 
876
                if (lpFindFileData->dwFileAttributes
 
877
                    & FILE_ATTRIBUTE_REPARSE_POINT) {
 
878
                        /* TODO: test Windows symlinks */
 
879
                        /* TODO: MySQL has apparently its own symlink
 
880
                        implementation in Windows, dbname.sym can
 
881
                        redirect a database directory:
 
882
                        REFMAN "windows-symbolic-links.html" */
 
883
                        info->type = OS_FILE_TYPE_LINK;
 
884
                } else if (lpFindFileData->dwFileAttributes
 
885
                           & FILE_ATTRIBUTE_DIRECTORY) {
 
886
                        info->type = OS_FILE_TYPE_DIR;
 
887
                } else {
 
888
                        /* It is probably safest to assume that all other
 
889
                        file types are normal. Better to check them rather
 
890
                        than blindly skip them. */
 
891
 
 
892
                        info->type = OS_FILE_TYPE_FILE;
 
893
                }
 
894
        }
 
895
 
 
896
        ut_free(lpFindFileData);
 
897
 
 
898
        if (ret) {
 
899
                return(0);
 
900
        } else if (GetLastError() == ERROR_NO_MORE_FILES) {
 
901
 
 
902
                return(1);
 
903
        } else {
 
904
                os_file_handle_error_no_exit(dirname,
 
905
                                             "readdir_next_file");
 
906
                return(-1);
 
907
        }
 
908
#else
 
909
        struct dirent*  ent;
 
910
        char*           full_path;
 
911
        int             ret;
 
912
        struct stat     statinfo;
 
913
#ifdef HAVE_READDIR_R
 
914
        char            dirent_buf[sizeof(struct dirent)
 
915
                                   + _POSIX_PATH_MAX + 100];
 
916
        /* In /mysys/my_lib.c, _POSIX_PATH_MAX + 1 is used as
 
917
        the max file name len; but in most standards, the
 
918
        length is NAME_MAX; we add 100 to be even safer */
 
919
#endif
 
920
 
 
921
next_file:
 
922
 
 
923
#ifdef HAVE_READDIR_R
 
924
        ret = readdir_r(dir, (struct dirent*)dirent_buf, &ent);
 
925
 
 
926
        if (ret != 0
 
927
#ifdef UNIV_AIX
 
928
            /* On AIX, only if we got non-NULL 'ent' (result) value and
 
929
            a non-zero 'ret' (return) value, it indicates a failed
 
930
            readdir_r() call. An NULL 'ent' with an non-zero 'ret'
 
931
            would indicate the "end of the directory" is reached. */
 
932
            && ent != NULL
 
933
#endif
 
934
           ) {
 
935
                fprintf(stderr,
 
936
                        "InnoDB: cannot read directory %s, error %lu\n",
 
937
                        dirname, (ulong)ret);
 
938
 
 
939
                return(-1);
 
940
        }
 
941
 
 
942
        if (ent == NULL) {
 
943
                /* End of directory */
 
944
 
 
945
                return(1);
 
946
        }
 
947
 
 
948
        ut_a(strlen(ent->d_name) < _POSIX_PATH_MAX + 100 - 1);
 
949
#else
 
950
        ent = readdir(dir);
 
951
 
 
952
        if (ent == NULL) {
 
953
 
 
954
                return(1);
 
955
        }
 
956
#endif
 
957
        ut_a(strlen(ent->d_name) < OS_FILE_MAX_PATH);
 
958
 
 
959
        if (strcmp(ent->d_name, ".") == 0 || strcmp(ent->d_name, "..") == 0) {
 
960
 
 
961
                goto next_file;
 
962
        }
 
963
 
 
964
        strcpy(info->name, ent->d_name);
 
965
 
 
966
        full_path = ut_malloc(strlen(dirname) + strlen(ent->d_name) + 10);
 
967
 
 
968
        sprintf(full_path, "%s/%s", dirname, ent->d_name);
 
969
 
 
970
        ret = stat(full_path, &statinfo);
 
971
 
 
972
        if (ret) {
 
973
 
 
974
                if (errno == ENOENT) {
 
975
                        /* readdir() returned a file that does not exist,
 
976
                        it must have been deleted in the meantime. Do what
 
977
                        would have happened if the file was deleted before
 
978
                        readdir() - ignore and go to the next entry.
 
979
                        If this is the last entry then info->name will still
 
980
                        contain the name of the deleted file when this
 
981
                        function returns, but this is not an issue since the
 
982
                        caller shouldn't be looking at info when end of
 
983
                        directory is returned. */
 
984
 
 
985
                        ut_free(full_path);
 
986
 
 
987
                        goto next_file;
 
988
                }
 
989
 
 
990
                os_file_handle_error_no_exit(full_path, "stat");
 
991
 
 
992
                ut_free(full_path);
 
993
 
 
994
                return(-1);
 
995
        }
 
996
 
 
997
        info->size = (ib_int64_t)statinfo.st_size;
 
998
 
 
999
        if (S_ISDIR(statinfo.st_mode)) {
 
1000
                info->type = OS_FILE_TYPE_DIR;
 
1001
        } else if (S_ISLNK(statinfo.st_mode)) {
 
1002
                info->type = OS_FILE_TYPE_LINK;
 
1003
        } else if (S_ISREG(statinfo.st_mode)) {
 
1004
                info->type = OS_FILE_TYPE_FILE;
 
1005
        } else {
 
1006
                info->type = OS_FILE_TYPE_UNKNOWN;
 
1007
        }
 
1008
 
 
1009
        ut_free(full_path);
 
1010
 
 
1011
        return(0);
 
1012
#endif
 
1013
}
 
1014
 
 
1015
/*****************************************************************//**
 
1016
This function attempts to create a directory named pathname. The new directory
 
1017
gets default permissions. On Unix the permissions are (0770 & ~umask). If the
 
1018
directory exists already, nothing is done and the call succeeds, unless the
 
1019
fail_if_exists arguments is true.
 
1020
@return TRUE if call succeeds, FALSE on error */
 
1021
UNIV_INTERN
 
1022
ibool
 
1023
os_file_create_directory(
 
1024
/*=====================*/
 
1025
        const char*     pathname,       /*!< in: directory name as
 
1026
                                        null-terminated string */
 
1027
        ibool           fail_if_exists) /*!< in: if TRUE, pre-existing directory
 
1028
                                        is treated as an error. */
 
1029
{
 
1030
#ifdef __WIN__
 
1031
        BOOL    rcode;
 
1032
 
 
1033
        rcode = CreateDirectory((LPCTSTR) pathname, NULL);
 
1034
        if (!(rcode != 0
 
1035
              || (GetLastError() == ERROR_ALREADY_EXISTS
 
1036
                  && !fail_if_exists))) {
 
1037
                /* failure */
 
1038
                os_file_handle_error(pathname, "CreateDirectory");
 
1039
 
 
1040
                return(FALSE);
 
1041
        }
 
1042
 
 
1043
        return (TRUE);
 
1044
#else
 
1045
        int     rcode;
 
1046
 
 
1047
        rcode = mkdir(pathname, 0770);
 
1048
 
 
1049
        if (!(rcode == 0 || (errno == EEXIST && !fail_if_exists))) {
 
1050
                /* failure */
 
1051
                os_file_handle_error(pathname, "mkdir");
 
1052
 
 
1053
                return(FALSE);
 
1054
        }
 
1055
 
 
1056
        return (TRUE);
 
1057
#endif
 
1058
}
 
1059
 
 
1060
/****************************************************************//**
 
1061
NOTE! Use the corresponding macro os_file_create_simple(), not directly
 
1062
this function!
 
1063
A simple function to open or create a file.
 
1064
@return own: handle to the file, not defined if error, error number
 
1065
can be retrieved with os_file_get_last_error */
 
1066
UNIV_INTERN
 
1067
os_file_t
 
1068
os_file_create_simple_func(
 
1069
/*=======================*/
 
1070
        const char*     name,   /*!< in: name of the file or path as a
 
1071
                                null-terminated string */
 
1072
        ulint           create_mode,/*!< in: OS_FILE_OPEN if an existing file is
 
1073
                                opened (if does not exist, error), or
 
1074
                                OS_FILE_CREATE if a new file is created
 
1075
                                (if exists, error), or
 
1076
                                OS_FILE_CREATE_PATH if new file
 
1077
                                (if exists, error) and subdirectories along
 
1078
                                its path are created (if needed)*/
 
1079
        ulint           access_type,/*!< in: OS_FILE_READ_ONLY or
 
1080
                                OS_FILE_READ_WRITE */
 
1081
        ibool*          success)/*!< out: TRUE if succeed, FALSE if error */
 
1082
{
 
1083
#ifdef __WIN__
 
1084
        os_file_t       file;
 
1085
        DWORD           create_flag;
 
1086
        DWORD           access;
 
1087
        DWORD           attributes      = 0;
 
1088
        ibool           retry;
 
1089
 
 
1090
try_again:
 
1091
        ut_a(name);
 
1092
 
 
1093
        if (create_mode == OS_FILE_OPEN) {
 
1094
                create_flag = OPEN_EXISTING;
 
1095
        } else if (create_mode == OS_FILE_CREATE) {
 
1096
                create_flag = CREATE_NEW;
 
1097
        } else if (create_mode == OS_FILE_CREATE_PATH) {
 
1098
                /* create subdirs along the path if needed  */
 
1099
                *success = os_file_create_subdirs_if_needed(name);
 
1100
                if (!*success) {
 
1101
                        ut_error;
 
1102
                }
 
1103
                create_flag = CREATE_NEW;
 
1104
                create_mode = OS_FILE_CREATE;
 
1105
        } else {
 
1106
                create_flag = 0;
 
1107
                ut_error;
 
1108
        }
 
1109
 
 
1110
        if (access_type == OS_FILE_READ_ONLY) {
 
1111
                access = GENERIC_READ;
 
1112
        } else if (access_type == OS_FILE_READ_WRITE) {
 
1113
                access = GENERIC_READ | GENERIC_WRITE;
 
1114
        } else {
 
1115
                access = 0;
 
1116
                ut_error;
 
1117
        }
 
1118
 
 
1119
        file = CreateFile((LPCTSTR) name,
 
1120
                          access,
 
1121
                          FILE_SHARE_READ | FILE_SHARE_WRITE,
 
1122
                          /* file can be read and written also
 
1123
                          by other processes */
 
1124
                          NULL, /* default security attributes */
 
1125
                          create_flag,
 
1126
                          attributes,
 
1127
                          NULL);        /*!< no template file */
 
1128
 
 
1129
        if (file == INVALID_HANDLE_VALUE) {
 
1130
                *success = FALSE;
 
1131
 
 
1132
                retry = os_file_handle_error(name,
 
1133
                                             create_mode == OS_FILE_OPEN ?
 
1134
                                             "open" : "create");
 
1135
                if (retry) {
 
1136
                        goto try_again;
 
1137
                }
 
1138
        } else {
 
1139
                *success = TRUE;
 
1140
        }
 
1141
 
 
1142
        return(file);
 
1143
#else /* __WIN__ */
 
1144
        os_file_t       file;
 
1145
        int             create_flag;
 
1146
        ibool           retry;
 
1147
 
 
1148
try_again:
 
1149
        ut_a(name);
 
1150
 
 
1151
        if (create_mode == OS_FILE_OPEN) {
 
1152
                if (access_type == OS_FILE_READ_ONLY) {
 
1153
                        create_flag = O_RDONLY;
 
1154
                } else {
 
1155
                        create_flag = O_RDWR;
 
1156
                }
 
1157
        } else if (create_mode == OS_FILE_CREATE) {
 
1158
                create_flag = O_RDWR | O_CREAT | O_EXCL;
 
1159
        } else if (create_mode == OS_FILE_CREATE_PATH) {
 
1160
                /* create subdirs along the path if needed  */
 
1161
                *success = os_file_create_subdirs_if_needed(name);
 
1162
                if (!*success) {
 
1163
                        return (-1);
 
1164
                }
 
1165
                create_flag = O_RDWR | O_CREAT | O_EXCL;
 
1166
                create_mode = OS_FILE_CREATE;
 
1167
        } else {
 
1168
                create_flag = 0;
 
1169
                ut_error;
 
1170
        }
 
1171
 
 
1172
        if (create_mode == OS_FILE_CREATE) {
 
1173
                file = open(name, create_flag, S_IRUSR | S_IWUSR
 
1174
                            | S_IRGRP | S_IWGRP);
 
1175
        } else {
 
1176
                file = open(name, create_flag);
 
1177
        }
 
1178
 
 
1179
        if (file == -1) {
 
1180
                *success = FALSE;
 
1181
 
 
1182
                retry = os_file_handle_error(name,
 
1183
                                             create_mode == OS_FILE_OPEN ?
 
1184
                                             "open" : "create");
 
1185
                if (retry) {
 
1186
                        goto try_again;
 
1187
                }
 
1188
#ifdef USE_FILE_LOCK
 
1189
        } else if (access_type == OS_FILE_READ_WRITE
 
1190
                   && os_file_lock(file, name)) {
 
1191
                *success = FALSE;
 
1192
                close(file);
 
1193
                file = -1;
 
1194
#endif
 
1195
        } else {
 
1196
                *success = TRUE;
 
1197
        }
 
1198
 
 
1199
        return(file);
 
1200
#endif /* __WIN__ */
 
1201
}
 
1202
 
 
1203
/****************************************************************//**
 
1204
NOTE! Use the corresponding macro
 
1205
os_file_create_simple_no_error_handling(), not directly this function!
 
1206
A simple function to open or create a file.
 
1207
@return own: handle to the file, not defined if error, error number
 
1208
can be retrieved with os_file_get_last_error */
 
1209
UNIV_INTERN
 
1210
os_file_t
 
1211
os_file_create_simple_no_error_handling_func(
 
1212
/*=========================================*/
 
1213
        const char*     name,   /*!< in: name of the file or path as a
 
1214
                                null-terminated string */
 
1215
        ulint           create_mode,/*!< in: OS_FILE_OPEN if an existing file
 
1216
                                is opened (if does not exist, error), or
 
1217
                                OS_FILE_CREATE if a new file is created
 
1218
                                (if exists, error) */
 
1219
        ulint           access_type,/*!< in: OS_FILE_READ_ONLY,
 
1220
                                OS_FILE_READ_WRITE, or
 
1221
                                OS_FILE_READ_ALLOW_DELETE; the last option is
 
1222
                                used by a backup program reading the file */
 
1223
        ibool*          success)/*!< out: TRUE if succeed, FALSE if error */
 
1224
{
 
1225
#ifdef __WIN__
 
1226
        os_file_t       file;
 
1227
        DWORD           create_flag;
 
1228
        DWORD           access;
 
1229
        DWORD           attributes      = 0;
 
1230
        DWORD           share_mode      = FILE_SHARE_READ | FILE_SHARE_WRITE;
 
1231
 
 
1232
        ut_a(name);
 
1233
 
 
1234
        if (create_mode == OS_FILE_OPEN) {
 
1235
                create_flag = OPEN_EXISTING;
 
1236
        } else if (create_mode == OS_FILE_CREATE) {
 
1237
                create_flag = CREATE_NEW;
 
1238
        } else {
 
1239
                create_flag = 0;
 
1240
                ut_error;
 
1241
        }
 
1242
 
 
1243
        if (access_type == OS_FILE_READ_ONLY) {
 
1244
                access = GENERIC_READ;
 
1245
        } else if (access_type == OS_FILE_READ_WRITE) {
 
1246
                access = GENERIC_READ | GENERIC_WRITE;
 
1247
        } else if (access_type == OS_FILE_READ_ALLOW_DELETE) {
 
1248
                access = GENERIC_READ;
 
1249
                share_mode = FILE_SHARE_DELETE | FILE_SHARE_READ
 
1250
                        | FILE_SHARE_WRITE;     /*!< A backup program has to give
 
1251
                                                mysqld the maximum freedom to
 
1252
                                                do what it likes with the
 
1253
                                                file */
 
1254
        } else {
 
1255
                access = 0;
 
1256
                ut_error;
 
1257
        }
 
1258
 
 
1259
        file = CreateFile((LPCTSTR) name,
 
1260
                          access,
 
1261
                          share_mode,
 
1262
                          NULL, /* default security attributes */
 
1263
                          create_flag,
 
1264
                          attributes,
 
1265
                          NULL);        /*!< no template file */
 
1266
 
 
1267
        if (file == INVALID_HANDLE_VALUE) {
 
1268
                *success = FALSE;
 
1269
        } else {
 
1270
                *success = TRUE;
 
1271
        }
 
1272
 
 
1273
        return(file);
 
1274
#else /* __WIN__ */
 
1275
        os_file_t       file;
 
1276
        int             create_flag;
 
1277
 
 
1278
        ut_a(name);
 
1279
 
 
1280
        if (create_mode == OS_FILE_OPEN) {
 
1281
                if (access_type == OS_FILE_READ_ONLY) {
 
1282
                        create_flag = O_RDONLY;
 
1283
                } else {
 
1284
                        create_flag = O_RDWR;
 
1285
                }
 
1286
        } else if (create_mode == OS_FILE_CREATE) {
 
1287
                create_flag = O_RDWR | O_CREAT | O_EXCL;
 
1288
        } else {
 
1289
                create_flag = 0;
 
1290
                ut_error;
 
1291
        }
 
1292
 
 
1293
        if (create_mode == OS_FILE_CREATE) {
 
1294
                file = open(name, create_flag, S_IRUSR | S_IWUSR
 
1295
                            | S_IRGRP | S_IWGRP);
 
1296
        } else {
 
1297
                file = open(name, create_flag);
 
1298
        }
 
1299
 
 
1300
        if (file == -1) {
 
1301
                *success = FALSE;
 
1302
#ifdef USE_FILE_LOCK
 
1303
        } else if (access_type == OS_FILE_READ_WRITE
 
1304
                   && os_file_lock(file, name)) {
 
1305
                *success = FALSE;
 
1306
                close(file);
 
1307
                file = -1;
 
1308
#endif
 
1309
        } else {
 
1310
                *success = TRUE;
 
1311
        }
 
1312
 
 
1313
        return(file);
 
1314
#endif /* __WIN__ */
 
1315
}
 
1316
 
 
1317
/****************************************************************//**
 
1318
Tries to disable OS caching on an opened file descriptor. */
 
1319
UNIV_INTERN
 
1320
void
 
1321
os_file_set_nocache(
 
1322
/*================*/
 
1323
        int             fd              /*!< in: file descriptor to alter */
 
1324
        __attribute__((unused)),
 
1325
        const char*     file_name       /*!< in: used in the diagnostic message */
 
1326
        __attribute__((unused)),
 
1327
        const char*     operation_name __attribute__((unused)))
 
1328
                                        /*!< in: "open" or "create"; used in the
 
1329
                                        diagnostic message */
 
1330
{
 
1331
        /* some versions of Solaris may not have DIRECTIO_ON */
 
1332
#if defined(UNIV_SOLARIS) && defined(DIRECTIO_ON)
 
1333
        if (directio(fd, DIRECTIO_ON) == -1) {
 
1334
                int     errno_save;
 
1335
                errno_save = (int)errno;
 
1336
                ut_print_timestamp(stderr);
 
1337
                fprintf(stderr,
 
1338
                        "  InnoDB: Failed to set DIRECTIO_ON "
 
1339
                        "on file %s: %s: %s, continuing anyway\n",
 
1340
                        file_name, operation_name, strerror(errno_save));
 
1341
        }
 
1342
#elif defined(O_DIRECT)
 
1343
        if (fcntl(fd, F_SETFL, O_DIRECT) == -1) {
 
1344
                int     errno_save;
 
1345
                errno_save = (int)errno;
 
1346
                ut_print_timestamp(stderr);
 
1347
                fprintf(stderr,
 
1348
                        "  InnoDB: Failed to set O_DIRECT "
 
1349
                        "on file %s: %s: %s, continuing anyway\n",
 
1350
                        file_name, operation_name, strerror(errno_save));
 
1351
                if (errno_save == EINVAL) {
 
1352
                        ut_print_timestamp(stderr);
 
1353
                        fprintf(stderr,
 
1354
                                "  InnoDB: O_DIRECT is known to result in "
 
1355
                                "'Invalid argument' on Linux on tmpfs, "
 
1356
                                "see MySQL Bug#26662\n");
 
1357
                }
 
1358
        }
 
1359
#endif
 
1360
}
 
1361
 
 
1362
/****************************************************************//**
 
1363
NOTE! Use the corresponding macro os_file_create(), not directly
 
1364
this function!
 
1365
Opens an existing file or creates a new.
 
1366
@return own: handle to the file, not defined if error, error number
 
1367
can be retrieved with os_file_get_last_error */
 
1368
UNIV_INTERN
 
1369
os_file_t
 
1370
os_file_create_func(
 
1371
/*================*/
 
1372
        const char*     name,   /*!< in: name of the file or path as a
 
1373
                                null-terminated string */
 
1374
        ulint           create_mode,/*!< in: OS_FILE_OPEN if an existing file
 
1375
                                is opened (if does not exist, error), or
 
1376
                                OS_FILE_CREATE if a new file is created
 
1377
                                (if exists, error),
 
1378
                                OS_FILE_OVERWRITE if a new file is created
 
1379
                                or an old overwritten;
 
1380
                                OS_FILE_OPEN_RAW, if a raw device or disk
 
1381
                                partition should be opened */
 
1382
        ulint           purpose,/*!< in: OS_FILE_AIO, if asynchronous,
 
1383
                                non-buffered i/o is desired,
 
1384
                                OS_FILE_NORMAL, if any normal file;
 
1385
                                NOTE that it also depends on type, os_aio_..
 
1386
                                and srv_.. variables whether we really use
 
1387
                                async i/o or unbuffered i/o: look in the
 
1388
                                function source code for the exact rules */
 
1389
        ulint           type,   /*!< in: OS_DATA_FILE or OS_LOG_FILE */
 
1390
        ibool*          success)/*!< out: TRUE if succeed, FALSE if error */
 
1391
{
 
1392
#ifdef __WIN__
 
1393
        os_file_t       file;
 
1394
        DWORD           share_mode      = FILE_SHARE_READ;
 
1395
        DWORD           create_flag;
 
1396
        DWORD           attributes;
 
1397
        ibool           retry;
 
1398
try_again:
 
1399
        ut_a(name);
 
1400
 
 
1401
        if (create_mode == OS_FILE_OPEN_RAW) {
 
1402
                create_flag = OPEN_EXISTING;
 
1403
                share_mode = FILE_SHARE_WRITE;
 
1404
        } else if (create_mode == OS_FILE_OPEN
 
1405
                   || create_mode == OS_FILE_OPEN_RETRY) {
 
1406
                create_flag = OPEN_EXISTING;
 
1407
        } else if (create_mode == OS_FILE_CREATE) {
 
1408
                create_flag = CREATE_NEW;
 
1409
        } else if (create_mode == OS_FILE_OVERWRITE) {
 
1410
                create_flag = CREATE_ALWAYS;
 
1411
        } else {
 
1412
                create_flag = 0;
 
1413
                ut_error;
 
1414
        }
 
1415
 
 
1416
        if (purpose == OS_FILE_AIO) {
 
1417
                /* If specified, use asynchronous (overlapped) io and no
 
1418
                buffering of writes in the OS */
 
1419
                attributes = 0;
 
1420
#ifdef WIN_ASYNC_IO
 
1421
                if (srv_use_native_aio) {
 
1422
                        attributes = attributes | FILE_FLAG_OVERLAPPED;
 
1423
                }
 
1424
#endif
 
1425
#ifdef UNIV_NON_BUFFERED_IO
 
1426
# ifndef UNIV_HOTBACKUP
 
1427
                if (type == OS_LOG_FILE && srv_flush_log_at_trx_commit == 2) {
 
1428
                        /* Do not use unbuffered i/o to log files because
 
1429
                        value 2 denotes that we do not flush the log at every
 
1430
                        commit, but only once per second */
 
1431
                } else if (srv_win_file_flush_method
 
1432
                           == SRV_WIN_IO_UNBUFFERED) {
 
1433
                        attributes = attributes | FILE_FLAG_NO_BUFFERING;
 
1434
                }
 
1435
# else /* !UNIV_HOTBACKUP */
 
1436
                attributes = attributes | FILE_FLAG_NO_BUFFERING;
 
1437
# endif /* !UNIV_HOTBACKUP */
 
1438
#endif /* UNIV_NON_BUFFERED_IO */
 
1439
        } else if (purpose == OS_FILE_NORMAL) {
 
1440
                attributes = 0;
 
1441
#ifdef UNIV_NON_BUFFERED_IO
 
1442
# ifndef UNIV_HOTBACKUP
 
1443
                if (type == OS_LOG_FILE && srv_flush_log_at_trx_commit == 2) {
 
1444
                        /* Do not use unbuffered i/o to log files because
 
1445
                        value 2 denotes that we do not flush the log at every
 
1446
                        commit, but only once per second */
 
1447
                } else if (srv_win_file_flush_method
 
1448
                           == SRV_WIN_IO_UNBUFFERED) {
 
1449
                        attributes = attributes | FILE_FLAG_NO_BUFFERING;
 
1450
                }
 
1451
# else /* !UNIV_HOTBACKUP */
 
1452
                attributes = attributes | FILE_FLAG_NO_BUFFERING;
 
1453
# endif /* !UNIV_HOTBACKUP */
 
1454
#endif /* UNIV_NON_BUFFERED_IO */
 
1455
        } else {
 
1456
                attributes = 0;
 
1457
                ut_error;
 
1458
        }
 
1459
 
 
1460
        file = CreateFile((LPCTSTR) name,
 
1461
                          GENERIC_READ | GENERIC_WRITE, /* read and write
 
1462
                                                        access */
 
1463
                          share_mode,   /* File can be read also by other
 
1464
                                        processes; we must give the read
 
1465
                                        permission because of ibbackup. We do
 
1466
                                        not give the write permission to
 
1467
                                        others because if one would succeed to
 
1468
                                        start 2 instances of mysqld on the
 
1469
                                        SAME files, that could cause severe
 
1470
                                        database corruption! When opening
 
1471
                                        raw disk partitions, Microsoft manuals
 
1472
                                        say that we must give also the write
 
1473
                                        permission. */
 
1474
                          NULL, /* default security attributes */
 
1475
                          create_flag,
 
1476
                          attributes,
 
1477
                          NULL);        /*!< no template file */
 
1478
 
 
1479
        if (file == INVALID_HANDLE_VALUE) {
 
1480
                *success = FALSE;
 
1481
 
 
1482
                /* When srv_file_per_table is on, file creation failure may not
 
1483
                be critical to the whole instance. Do not crash the server in
 
1484
                case of unknown errors.
 
1485
                Please note "srv_file_per_table" is a global variable with
 
1486
                no explicit synchronization protection. It could be
 
1487
                changed during this execution path. It might not have the
 
1488
                same value as the one when building the table definition */
 
1489
                if (srv_file_per_table) {
 
1490
                        retry = os_file_handle_error_no_exit(name,
 
1491
                                                create_mode == OS_FILE_CREATE ?
 
1492
                                                "create" : "open");
 
1493
                } else {
 
1494
                        retry = os_file_handle_error(name,
 
1495
                                                create_mode == OS_FILE_CREATE ?
 
1496
                                                "create" : "open");
 
1497
                }
 
1498
 
 
1499
                if (retry) {
 
1500
                        goto try_again;
 
1501
                }
 
1502
        } else {
 
1503
                *success = TRUE;
 
1504
        }
 
1505
 
 
1506
        return(file);
 
1507
#else /* __WIN__ */
 
1508
        os_file_t       file;
 
1509
        int             create_flag;
 
1510
        ibool           retry;
 
1511
        const char*     mode_str        = NULL;
 
1512
 
 
1513
try_again:
 
1514
        ut_a(name);
 
1515
 
 
1516
        if (create_mode == OS_FILE_OPEN || create_mode == OS_FILE_OPEN_RAW
 
1517
            || create_mode == OS_FILE_OPEN_RETRY) {
 
1518
                mode_str = "OPEN";
 
1519
                create_flag = O_RDWR;
 
1520
        } else if (create_mode == OS_FILE_CREATE) {
 
1521
                mode_str = "CREATE";
 
1522
                create_flag = O_RDWR | O_CREAT | O_EXCL;
 
1523
        } else if (create_mode == OS_FILE_OVERWRITE) {
 
1524
                mode_str = "OVERWRITE";
 
1525
                create_flag = O_RDWR | O_CREAT | O_TRUNC;
 
1526
        } else {
 
1527
                create_flag = 0;
 
1528
                ut_error;
 
1529
        }
 
1530
 
 
1531
        ut_a(type == OS_LOG_FILE || type == OS_DATA_FILE);
 
1532
        ut_a(purpose == OS_FILE_AIO || purpose == OS_FILE_NORMAL);
 
1533
 
 
1534
#ifdef O_SYNC
 
1535
        /* We let O_SYNC only affect log files; note that we map O_DSYNC to
 
1536
        O_SYNC because the datasync options seemed to corrupt files in 2001
 
1537
        in both Linux and Solaris */
 
1538
        if (type == OS_LOG_FILE
 
1539
            && srv_unix_file_flush_method == SRV_UNIX_O_DSYNC) {
 
1540
 
 
1541
# if 0
 
1542
                fprintf(stderr, "Using O_SYNC for file %s\n", name);
 
1543
# endif
 
1544
 
 
1545
                create_flag = create_flag | O_SYNC;
 
1546
        }
 
1547
#endif /* O_SYNC */
 
1548
 
 
1549
        file = open(name, create_flag, os_innodb_umask);
 
1550
 
 
1551
        if (file == -1) {
 
1552
                *success = FALSE;
 
1553
 
 
1554
                /* When srv_file_per_table is on, file creation failure may not
 
1555
                be critical to the whole instance. Do not crash the server in
 
1556
                case of unknown errors.
 
1557
                Please note "srv_file_per_table" is a global variable with
 
1558
                no explicit synchronization protection. It could be
 
1559
                changed during this execution path. It might not have the
 
1560
                same value as the one when building the table definition */
 
1561
                if (srv_file_per_table) {
 
1562
                        retry = os_file_handle_error_no_exit(name,
 
1563
                                                create_mode == OS_FILE_CREATE ?
 
1564
                                                "create" : "open");
 
1565
                } else {
 
1566
                        retry = os_file_handle_error(name,
 
1567
                                                create_mode == OS_FILE_CREATE ?
 
1568
                                                "create" : "open");
 
1569
                }
 
1570
 
 
1571
                if (retry) {
 
1572
                        goto try_again;
 
1573
                } else {
 
1574
                        return(file /* -1 */);
 
1575
                }
 
1576
        }
 
1577
        /* else */
 
1578
 
 
1579
        *success = TRUE;
 
1580
 
 
1581
        /* We disable OS caching (O_DIRECT) only on data files */
 
1582
        if (type != OS_LOG_FILE
 
1583
            && srv_unix_file_flush_method == SRV_UNIX_O_DIRECT) {
 
1584
                
 
1585
                os_file_set_nocache(file, name, mode_str);
 
1586
        }
 
1587
 
 
1588
#ifdef USE_FILE_LOCK
 
1589
        if (create_mode != OS_FILE_OPEN_RAW && os_file_lock(file, name)) {
 
1590
 
 
1591
                if (create_mode == OS_FILE_OPEN_RETRY) {
 
1592
                        int i;
 
1593
                        ut_print_timestamp(stderr);
 
1594
                        fputs("  InnoDB: Retrying to lock"
 
1595
                              " the first data file\n",
 
1596
                              stderr);
 
1597
                        for (i = 0; i < 100; i++) {
 
1598
                                os_thread_sleep(1000000);
 
1599
                                if (!os_file_lock(file, name)) {
 
1600
                                        *success = TRUE;
 
1601
                                        return(file);
 
1602
                                }
 
1603
                        }
 
1604
                        ut_print_timestamp(stderr);
 
1605
                        fputs("  InnoDB: Unable to open the first data file\n",
 
1606
                              stderr);
 
1607
                }
 
1608
 
 
1609
                *success = FALSE;
 
1610
                close(file);
 
1611
                file = -1;
 
1612
        }
 
1613
#endif /* USE_FILE_LOCK */
 
1614
 
 
1615
        return(file);
 
1616
#endif /* __WIN__ */
 
1617
}
 
1618
 
 
1619
/***********************************************************************//**
 
1620
Deletes a file if it exists. The file has to be closed before calling this.
 
1621
@return TRUE if success */
 
1622
UNIV_INTERN
 
1623
ibool
 
1624
os_file_delete_if_exists(
 
1625
/*=====================*/
 
1626
        const char*     name)   /*!< in: file path as a null-terminated string */
 
1627
{
 
1628
#ifdef __WIN__
 
1629
        BOOL    ret;
 
1630
        ulint   count   = 0;
 
1631
loop:
 
1632
        /* In Windows, deleting an .ibd file may fail if ibbackup is copying
 
1633
        it */
 
1634
 
 
1635
        ret = DeleteFile((LPCTSTR)name);
 
1636
 
 
1637
        if (ret) {
 
1638
                return(TRUE);
 
1639
        }
 
1640
 
 
1641
        if (GetLastError() == ERROR_FILE_NOT_FOUND) {
 
1642
                /* the file does not exist, this not an error */
 
1643
 
 
1644
                return(TRUE);
 
1645
        }
 
1646
 
 
1647
        count++;
 
1648
 
 
1649
        if (count > 100 && 0 == (count % 10)) {
 
1650
                fprintf(stderr,
 
1651
                        "InnoDB: Warning: cannot delete file %s\n"
 
1652
                        "InnoDB: Are you running ibbackup"
 
1653
                        " to back up the file?\n", name);
 
1654
 
 
1655
                os_file_get_last_error(TRUE); /* print error information */
 
1656
        }
 
1657
 
 
1658
        os_thread_sleep(1000000);       /* sleep for a second */
 
1659
 
 
1660
        if (count > 2000) {
 
1661
 
 
1662
                return(FALSE);
 
1663
        }
 
1664
 
 
1665
        goto loop;
 
1666
#else
 
1667
        int     ret;
 
1668
 
 
1669
        ret = unlink(name);
 
1670
 
 
1671
        if (ret != 0 && errno != ENOENT) {
 
1672
                os_file_handle_error_no_exit(name, "delete");
 
1673
 
 
1674
                return(FALSE);
 
1675
        }
 
1676
 
 
1677
        return(TRUE);
 
1678
#endif
 
1679
}
 
1680
 
 
1681
/***********************************************************************//**
 
1682
Deletes a file. The file has to be closed before calling this.
 
1683
@return TRUE if success */
 
1684
UNIV_INTERN
 
1685
ibool
 
1686
os_file_delete(
 
1687
/*===========*/
 
1688
        const char*     name)   /*!< in: file path as a null-terminated string */
 
1689
{
 
1690
#ifdef __WIN__
 
1691
        BOOL    ret;
 
1692
        ulint   count   = 0;
 
1693
loop:
 
1694
        /* In Windows, deleting an .ibd file may fail if ibbackup is copying
 
1695
        it */
 
1696
 
 
1697
        ret = DeleteFile((LPCTSTR)name);
 
1698
 
 
1699
        if (ret) {
 
1700
                return(TRUE);
 
1701
        }
 
1702
 
 
1703
        if (GetLastError() == ERROR_FILE_NOT_FOUND) {
 
1704
                /* If the file does not exist, we classify this as a 'mild'
 
1705
                error and return */
 
1706
 
 
1707
                return(FALSE);
 
1708
        }
 
1709
 
 
1710
        count++;
 
1711
 
 
1712
        if (count > 100 && 0 == (count % 10)) {
 
1713
                fprintf(stderr,
 
1714
                        "InnoDB: Warning: cannot delete file %s\n"
 
1715
                        "InnoDB: Are you running ibbackup"
 
1716
                        " to back up the file?\n", name);
 
1717
 
 
1718
                os_file_get_last_error(TRUE); /* print error information */
 
1719
        }
 
1720
 
 
1721
        os_thread_sleep(1000000);       /* sleep for a second */
 
1722
 
 
1723
        if (count > 2000) {
 
1724
 
 
1725
                return(FALSE);
 
1726
        }
 
1727
 
 
1728
        goto loop;
 
1729
#else
 
1730
        int     ret;
 
1731
 
 
1732
        ret = unlink(name);
 
1733
 
 
1734
        if (ret != 0) {
 
1735
                os_file_handle_error_no_exit(name, "delete");
 
1736
 
 
1737
                return(FALSE);
 
1738
        }
 
1739
 
 
1740
        return(TRUE);
 
1741
#endif
 
1742
}
 
1743
 
 
1744
/***********************************************************************//**
 
1745
NOTE! Use the corresponding macro os_file_rename(), not directly this function!
 
1746
Renames a file (can also move it to another directory). It is safest that the
 
1747
file is closed before calling this function.
 
1748
@return TRUE if success */
 
1749
UNIV_INTERN
 
1750
ibool
 
1751
os_file_rename_func(
 
1752
/*================*/
 
1753
        const char*     oldpath,/*!< in: old file path as a null-terminated
 
1754
                                string */
 
1755
        const char*     newpath)/*!< in: new file path */
 
1756
{
 
1757
#ifdef __WIN__
 
1758
        BOOL    ret;
 
1759
 
 
1760
        ret = MoveFile((LPCTSTR)oldpath, (LPCTSTR)newpath);
 
1761
 
 
1762
        if (ret) {
 
1763
                return(TRUE);
 
1764
        }
 
1765
 
 
1766
        os_file_handle_error_no_exit(oldpath, "rename");
 
1767
 
 
1768
        return(FALSE);
 
1769
#else
 
1770
        int     ret;
 
1771
 
 
1772
        ret = rename(oldpath, newpath);
 
1773
 
 
1774
        if (ret != 0) {
 
1775
                os_file_handle_error_no_exit(oldpath, "rename");
 
1776
 
 
1777
                return(FALSE);
 
1778
        }
 
1779
 
 
1780
        return(TRUE);
 
1781
#endif
 
1782
}
 
1783
 
 
1784
/***********************************************************************//**
 
1785
NOTE! Use the corresponding macro os_file_close(), not directly this function!
 
1786
Closes a file handle. In case of error, error number can be retrieved with
 
1787
os_file_get_last_error.
 
1788
@return TRUE if success */
 
1789
UNIV_INTERN
 
1790
ibool
 
1791
os_file_close_func(
 
1792
/*===============*/
 
1793
        os_file_t       file)   /*!< in, own: handle to a file */
 
1794
{
 
1795
#ifdef __WIN__
 
1796
        BOOL    ret;
 
1797
 
 
1798
        ut_a(file);
 
1799
 
 
1800
        ret = CloseHandle(file);
 
1801
 
 
1802
        if (ret) {
 
1803
                return(TRUE);
 
1804
        }
 
1805
 
 
1806
        os_file_handle_error(NULL, "close");
 
1807
 
 
1808
        return(FALSE);
 
1809
#else
 
1810
        int     ret;
 
1811
 
 
1812
        ret = close(file);
 
1813
 
 
1814
        if (ret == -1) {
 
1815
                os_file_handle_error(NULL, "close");
 
1816
 
 
1817
                return(FALSE);
 
1818
        }
 
1819
 
 
1820
        return(TRUE);
 
1821
#endif
 
1822
}
 
1823
 
 
1824
#ifdef UNIV_HOTBACKUP
 
1825
/***********************************************************************//**
 
1826
Closes a file handle.
 
1827
@return TRUE if success */
 
1828
UNIV_INTERN
 
1829
ibool
 
1830
os_file_close_no_error_handling(
 
1831
/*============================*/
 
1832
        os_file_t       file)   /*!< in, own: handle to a file */
 
1833
{
 
1834
#ifdef __WIN__
 
1835
        BOOL    ret;
 
1836
 
 
1837
        ut_a(file);
 
1838
 
 
1839
        ret = CloseHandle(file);
 
1840
 
 
1841
        if (ret) {
 
1842
                return(TRUE);
 
1843
        }
 
1844
 
 
1845
        return(FALSE);
 
1846
#else
 
1847
        int     ret;
 
1848
 
 
1849
        ret = close(file);
 
1850
 
 
1851
        if (ret == -1) {
 
1852
 
 
1853
                return(FALSE);
 
1854
        }
 
1855
 
 
1856
        return(TRUE);
 
1857
#endif
 
1858
}
 
1859
#endif /* UNIV_HOTBACKUP */
 
1860
 
 
1861
/***********************************************************************//**
 
1862
Gets a file size.
 
1863
@return TRUE if success */
 
1864
UNIV_INTERN
 
1865
ibool
 
1866
os_file_get_size(
 
1867
/*=============*/
 
1868
        os_file_t       file,   /*!< in: handle to a file */
 
1869
        ulint*          size,   /*!< out: least significant 32 bits of file
 
1870
                                size */
 
1871
        ulint*          size_high)/*!< out: most significant 32 bits of size */
 
1872
{
 
1873
#ifdef __WIN__
 
1874
        DWORD   high;
 
1875
        DWORD   low;
 
1876
 
 
1877
        low = GetFileSize(file, &high);
 
1878
 
 
1879
        if ((low == 0xFFFFFFFF) && (GetLastError() != NO_ERROR)) {
 
1880
                return(FALSE);
 
1881
        }
 
1882
 
 
1883
        *size = low;
 
1884
        *size_high = high;
 
1885
 
 
1886
        return(TRUE);
 
1887
#else
 
1888
        off_t   offs;
 
1889
 
 
1890
        offs = lseek(file, 0, SEEK_END);
 
1891
 
 
1892
        if (offs == ((off_t)-1)) {
 
1893
 
 
1894
                return(FALSE);
 
1895
        }
 
1896
 
 
1897
        if (sizeof(off_t) > 4) {
 
1898
                *size = (ulint)(offs & 0xFFFFFFFFUL);
 
1899
                *size_high = (ulint)(offs >> 32);
 
1900
        } else {
 
1901
                *size = (ulint) offs;
 
1902
                *size_high = 0;
 
1903
        }
 
1904
 
 
1905
        return(TRUE);
 
1906
#endif
 
1907
}
 
1908
 
 
1909
/***********************************************************************//**
 
1910
Gets file size as a 64-bit integer ib_int64_t.
 
1911
@return size in bytes, -1 if error */
 
1912
UNIV_INTERN
 
1913
ib_int64_t
 
1914
os_file_get_size_as_iblonglong(
 
1915
/*===========================*/
 
1916
        os_file_t       file)   /*!< in: handle to a file */
 
1917
{
 
1918
        ulint   size;
 
1919
        ulint   size_high;
 
1920
        ibool   success;
 
1921
 
 
1922
        success = os_file_get_size(file, &size, &size_high);
 
1923
 
 
1924
        if (!success) {
 
1925
 
 
1926
                return(-1);
 
1927
        }
 
1928
 
 
1929
        return((((ib_int64_t)size_high) << 32) + (ib_int64_t)size);
 
1930
}
 
1931
 
 
1932
/***********************************************************************//**
 
1933
Write the specified number of zeros to a newly created file.
 
1934
@return TRUE if success */
 
1935
UNIV_INTERN
 
1936
ibool
 
1937
os_file_set_size(
 
1938
/*=============*/
 
1939
        const char*     name,   /*!< in: name of the file or path as a
 
1940
                                null-terminated string */
 
1941
        os_file_t       file,   /*!< in: handle to a file */
 
1942
        ulint           size,   /*!< in: least significant 32 bits of file
 
1943
                                size */
 
1944
        ulint           size_high)/*!< in: most significant 32 bits of size */
 
1945
{
 
1946
        ib_int64_t      current_size;
 
1947
        ib_int64_t      desired_size;
 
1948
        ibool           ret;
 
1949
        byte*           buf;
 
1950
        byte*           buf2;
 
1951
        ulint           buf_size;
 
1952
 
 
1953
        ut_a(size == (size & 0xFFFFFFFF));
 
1954
 
 
1955
        current_size = 0;
 
1956
        desired_size = (ib_int64_t)size + (((ib_int64_t)size_high) << 32);
 
1957
 
 
1958
        /* Write up to 1 megabyte at a time. */
 
1959
        buf_size = ut_min(64, (ulint) (desired_size / UNIV_PAGE_SIZE))
 
1960
                * UNIV_PAGE_SIZE;
 
1961
        buf2 = ut_malloc(buf_size + UNIV_PAGE_SIZE);
 
1962
 
 
1963
        /* Align the buffer for possible raw i/o */
 
1964
        buf = ut_align(buf2, UNIV_PAGE_SIZE);
 
1965
 
 
1966
        /* Write buffer full of zeros */
 
1967
        memset(buf, 0, buf_size);
 
1968
 
 
1969
        if (desired_size >= (ib_int64_t)(100 * 1024 * 1024)) {
 
1970
 
 
1971
                fprintf(stderr, "InnoDB: Progress in MB:");
 
1972
        }
 
1973
 
 
1974
        while (current_size < desired_size) {
 
1975
                ulint   n_bytes;
 
1976
 
 
1977
                if (desired_size - current_size < (ib_int64_t) buf_size) {
 
1978
                        n_bytes = (ulint) (desired_size - current_size);
 
1979
                } else {
 
1980
                        n_bytes = buf_size;
 
1981
                }
 
1982
 
 
1983
                ret = os_file_write(name, file, buf,
 
1984
                                    (ulint)(current_size & 0xFFFFFFFF),
 
1985
                                    (ulint)(current_size >> 32),
 
1986
                                    n_bytes);
 
1987
                if (!ret) {
 
1988
                        ut_free(buf2);
 
1989
                        goto error_handling;
 
1990
                }
 
1991
 
 
1992
                /* Print about progress for each 100 MB written */
 
1993
                if ((ib_int64_t) (current_size + n_bytes) / (ib_int64_t)(100 * 1024 * 1024)
 
1994
                    != current_size / (ib_int64_t)(100 * 1024 * 1024)) {
 
1995
 
 
1996
                        fprintf(stderr, " %lu00",
 
1997
                                (ulong) ((current_size + n_bytes)
 
1998
                                         / (ib_int64_t)(100 * 1024 * 1024)));
 
1999
                }
 
2000
 
 
2001
                current_size += n_bytes;
 
2002
        }
 
2003
 
 
2004
        if (desired_size >= (ib_int64_t)(100 * 1024 * 1024)) {
 
2005
 
 
2006
                fprintf(stderr, "\n");
 
2007
        }
 
2008
 
 
2009
        ut_free(buf2);
 
2010
 
 
2011
        ret = os_file_flush(file);
 
2012
 
 
2013
        if (ret) {
 
2014
                return(TRUE);
 
2015
        }
 
2016
 
 
2017
error_handling:
 
2018
        return(FALSE);
 
2019
}
 
2020
 
 
2021
/***********************************************************************//**
 
2022
Truncates a file at its current position.
 
2023
@return TRUE if success */
 
2024
UNIV_INTERN
 
2025
ibool
 
2026
os_file_set_eof(
 
2027
/*============*/
 
2028
        FILE*           file)   /*!< in: file to be truncated */
 
2029
{
 
2030
#ifdef __WIN__
 
2031
        HANDLE h = (HANDLE) _get_osfhandle(fileno(file));
 
2032
        return(SetEndOfFile(h));
 
2033
#else /* __WIN__ */
 
2034
        return(!ftruncate(fileno(file), ftell(file)));
 
2035
#endif /* __WIN__ */
 
2036
}
 
2037
 
 
2038
#ifndef __WIN__
 
2039
/***********************************************************************//**
 
2040
Wrapper to fsync(2) that retries the call on some errors.
 
2041
Returns the value 0 if successful; otherwise the value -1 is returned and
 
2042
the global variable errno is set to indicate the error.
 
2043
@return 0 if success, -1 otherwise */
 
2044
 
 
2045
static
 
2046
int
 
2047
os_file_fsync(
 
2048
/*==========*/
 
2049
        os_file_t       file)   /*!< in: handle to a file */
 
2050
{
 
2051
        int     ret;
 
2052
        int     failures;
 
2053
        ibool   retry;
 
2054
 
 
2055
        failures = 0;
 
2056
 
 
2057
        do {
 
2058
                ret = fsync(file);
 
2059
 
 
2060
                os_n_fsyncs++;
 
2061
 
 
2062
                if (ret == -1 && errno == ENOLCK) {
 
2063
 
 
2064
                        if (failures % 100 == 0) {
 
2065
 
 
2066
                                ut_print_timestamp(stderr);
 
2067
                                fprintf(stderr,
 
2068
                                        "  InnoDB: fsync(): "
 
2069
                                        "No locks available; retrying\n");
 
2070
                        }
 
2071
 
 
2072
                        os_thread_sleep(200000 /* 0.2 sec */);
 
2073
 
 
2074
                        failures++;
 
2075
 
 
2076
                        retry = TRUE;
 
2077
                } else {
 
2078
 
 
2079
                        retry = FALSE;
 
2080
                }
 
2081
        } while (retry);
 
2082
 
 
2083
        return(ret);
 
2084
}
 
2085
#endif /* !__WIN__ */
 
2086
 
 
2087
/***********************************************************************//**
 
2088
NOTE! Use the corresponding macro os_file_flush(), not directly this function!
 
2089
Flushes the write buffers of a given file to the disk.
 
2090
@return TRUE if success */
 
2091
UNIV_INTERN
 
2092
ibool
 
2093
os_file_flush_func(
 
2094
/*===============*/
 
2095
        os_file_t       file)   /*!< in, own: handle to a file */
 
2096
{
 
2097
#ifdef __WIN__
 
2098
        BOOL    ret;
 
2099
 
 
2100
        ut_a(file);
 
2101
 
 
2102
        os_n_fsyncs++;
 
2103
 
 
2104
        ret = FlushFileBuffers(file);
 
2105
 
 
2106
        if (ret) {
 
2107
                return(TRUE);
 
2108
        }
 
2109
 
 
2110
        /* Since Windows returns ERROR_INVALID_FUNCTION if the 'file' is
 
2111
        actually a raw device, we choose to ignore that error if we are using
 
2112
        raw disks */
 
2113
 
 
2114
        if (srv_start_raw_disk_in_use && GetLastError()
 
2115
            == ERROR_INVALID_FUNCTION) {
 
2116
                return(TRUE);
 
2117
        }
 
2118
 
 
2119
        os_file_handle_error(NULL, "flush");
 
2120
 
 
2121
        /* It is a fatal error if a file flush does not succeed, because then
 
2122
        the database can get corrupt on disk */
 
2123
        ut_error;
 
2124
 
 
2125
        return(FALSE);
 
2126
#else
 
2127
        int     ret;
 
2128
 
 
2129
#if defined(HAVE_DARWIN_THREADS)
 
2130
# ifndef F_FULLFSYNC
 
2131
        /* The following definition is from the Mac OS X 10.3 <sys/fcntl.h> */
 
2132
#  define F_FULLFSYNC 51 /* fsync + ask the drive to flush to the media */
 
2133
# elif F_FULLFSYNC != 51
 
2134
#  error "F_FULLFSYNC != 51: ABI incompatibility with Mac OS X 10.3"
 
2135
# endif
 
2136
        /* Apple has disabled fsync() for internal disk drives in OS X. That
 
2137
        caused corruption for a user when he tested a power outage. Let us in
 
2138
        OS X use a nonstandard flush method recommended by an Apple
 
2139
        engineer. */
 
2140
 
 
2141
        if (!srv_have_fullfsync) {
 
2142
                /* If we are not on an operating system that supports this,
 
2143
                then fall back to a plain fsync. */
 
2144
 
 
2145
                ret = os_file_fsync(file);
 
2146
        } else {
 
2147
                ret = fcntl(file, F_FULLFSYNC, NULL);
 
2148
 
 
2149
                if (ret) {
 
2150
                        /* If we are not on a file system that supports this,
 
2151
                        then fall back to a plain fsync. */
 
2152
                        ret = os_file_fsync(file);
 
2153
                }
 
2154
        }
 
2155
#else
 
2156
        ret = os_file_fsync(file);
 
2157
#endif
 
2158
 
 
2159
        if (ret == 0) {
 
2160
                return(TRUE);
 
2161
        }
 
2162
 
 
2163
        /* Since Linux returns EINVAL if the 'file' is actually a raw device,
 
2164
        we choose to ignore that error if we are using raw disks */
 
2165
 
 
2166
        if (srv_start_raw_disk_in_use && errno == EINVAL) {
 
2167
 
 
2168
                return(TRUE);
 
2169
        }
 
2170
 
 
2171
        ut_print_timestamp(stderr);
 
2172
 
 
2173
        fprintf(stderr,
 
2174
                "  InnoDB: Error: the OS said file flush did not succeed\n");
 
2175
 
 
2176
        os_file_handle_error(NULL, "flush");
 
2177
 
 
2178
        /* It is a fatal error if a file flush does not succeed, because then
 
2179
        the database can get corrupt on disk */
 
2180
        ut_error;
 
2181
 
 
2182
        return(FALSE);
 
2183
#endif
 
2184
}
 
2185
 
 
2186
#ifndef __WIN__
 
2187
/*******************************************************************//**
 
2188
Does a synchronous read operation in Posix.
 
2189
@return number of bytes read, -1 if error */
 
2190
static
 
2191
ssize_t
 
2192
os_file_pread(
 
2193
/*==========*/
 
2194
        os_file_t       file,   /*!< in: handle to a file */
 
2195
        void*           buf,    /*!< in: buffer where to read */
 
2196
        ulint           n,      /*!< in: number of bytes to read */
 
2197
        ulint           offset, /*!< in: least significant 32 bits of file
 
2198
                                offset from where to read */
 
2199
        ulint           offset_high) /*!< in: most significant 32 bits of
 
2200
                                offset */
 
2201
{
 
2202
        off_t   offs;
 
2203
#if defined(HAVE_PREAD) && !defined(HAVE_BROKEN_PREAD)
 
2204
        ssize_t n_bytes;
 
2205
#endif /* HAVE_PREAD && !HAVE_BROKEN_PREAD */
 
2206
 
 
2207
        ut_a((offset & 0xFFFFFFFFUL) == offset);
 
2208
 
 
2209
        /* If off_t is > 4 bytes in size, then we assume we can pass a
 
2210
        64-bit address */
 
2211
 
 
2212
        if (sizeof(off_t) > 4) {
 
2213
                offs = (off_t)offset + (((off_t)offset_high) << 32);
 
2214
 
 
2215
        } else {
 
2216
                offs = (off_t)offset;
 
2217
 
 
2218
                if (offset_high > 0) {
 
2219
                        fprintf(stderr,
 
2220
                                "InnoDB: Error: file read at offset > 4 GB\n");
 
2221
                }
 
2222
        }
 
2223
 
 
2224
        os_n_file_reads++;
 
2225
 
 
2226
#if defined(HAVE_PREAD) && !defined(HAVE_BROKEN_PREAD)
 
2227
        os_mutex_enter(os_file_count_mutex);
 
2228
        os_file_n_pending_preads++;
 
2229
        os_n_pending_reads++;
 
2230
        os_mutex_exit(os_file_count_mutex);
 
2231
 
 
2232
        n_bytes = pread(file, buf, (ssize_t)n, offs);
 
2233
 
 
2234
        os_mutex_enter(os_file_count_mutex);
 
2235
        os_file_n_pending_preads--;
 
2236
        os_n_pending_reads--;
 
2237
        os_mutex_exit(os_file_count_mutex);
 
2238
 
 
2239
        return(n_bytes);
 
2240
#else
 
2241
        {
 
2242
                off_t   ret_offset;
 
2243
                ssize_t ret;
 
2244
#ifndef UNIV_HOTBACKUP
 
2245
                ulint   i;
 
2246
#endif /* !UNIV_HOTBACKUP */
 
2247
 
 
2248
                os_mutex_enter(os_file_count_mutex);
 
2249
                os_n_pending_reads++;
 
2250
                os_mutex_exit(os_file_count_mutex);
 
2251
 
 
2252
#ifndef UNIV_HOTBACKUP
 
2253
                /* Protect the seek / read operation with a mutex */
 
2254
                i = ((ulint) file) % OS_FILE_N_SEEK_MUTEXES;
 
2255
 
 
2256
                os_mutex_enter(os_file_seek_mutexes[i]);
 
2257
#endif /* !UNIV_HOTBACKUP */
 
2258
 
 
2259
                ret_offset = lseek(file, offs, SEEK_SET);
 
2260
 
 
2261
                if (ret_offset < 0) {
 
2262
                        ret = -1;
 
2263
                } else {
 
2264
                        ret = read(file, buf, (ssize_t)n);
 
2265
                }
 
2266
 
 
2267
#ifndef UNIV_HOTBACKUP
 
2268
                os_mutex_exit(os_file_seek_mutexes[i]);
 
2269
#endif /* !UNIV_HOTBACKUP */
 
2270
 
 
2271
                os_mutex_enter(os_file_count_mutex);
 
2272
                os_n_pending_reads--;
 
2273
                os_mutex_exit(os_file_count_mutex);
 
2274
 
 
2275
                return(ret);
 
2276
        }
 
2277
#endif
 
2278
}
 
2279
 
 
2280
/*******************************************************************//**
 
2281
Does a synchronous write operation in Posix.
 
2282
@return number of bytes written, -1 if error */
 
2283
static
 
2284
ssize_t
 
2285
os_file_pwrite(
 
2286
/*===========*/
 
2287
        os_file_t       file,   /*!< in: handle to a file */
 
2288
        const void*     buf,    /*!< in: buffer from where to write */
 
2289
        ulint           n,      /*!< in: number of bytes to write */
 
2290
        ulint           offset, /*!< in: least significant 32 bits of file
 
2291
                                offset where to write */
 
2292
        ulint           offset_high) /*!< in: most significant 32 bits of
 
2293
                                offset */
 
2294
{
 
2295
        ssize_t ret;
 
2296
        off_t   offs;
 
2297
 
 
2298
        ut_a((offset & 0xFFFFFFFFUL) == offset);
 
2299
 
 
2300
        /* If off_t is > 4 bytes in size, then we assume we can pass a
 
2301
        64-bit address */
 
2302
 
 
2303
        if (sizeof(off_t) > 4) {
 
2304
                offs = (off_t)offset + (((off_t)offset_high) << 32);
 
2305
        } else {
 
2306
                offs = (off_t)offset;
 
2307
 
 
2308
                if (offset_high > 0) {
 
2309
                        fprintf(stderr,
 
2310
                                "InnoDB: Error: file write"
 
2311
                                " at offset > 4 GB\n");
 
2312
                }
 
2313
        }
 
2314
 
 
2315
        os_n_file_writes++;
 
2316
 
 
2317
#if defined(HAVE_PWRITE) && !defined(HAVE_BROKEN_PREAD)
 
2318
        os_mutex_enter(os_file_count_mutex);
 
2319
        os_file_n_pending_pwrites++;
 
2320
        os_n_pending_writes++;
 
2321
        os_mutex_exit(os_file_count_mutex);
 
2322
 
 
2323
        ret = pwrite(file, buf, (ssize_t)n, offs);
 
2324
 
 
2325
        os_mutex_enter(os_file_count_mutex);
 
2326
        os_file_n_pending_pwrites--;
 
2327
        os_n_pending_writes--;
 
2328
        os_mutex_exit(os_file_count_mutex);
 
2329
 
 
2330
# ifdef UNIV_DO_FLUSH
 
2331
        if (srv_unix_file_flush_method != SRV_UNIX_LITTLESYNC
 
2332
            && srv_unix_file_flush_method != SRV_UNIX_NOSYNC
 
2333
            && !os_do_not_call_flush_at_each_write) {
 
2334
 
 
2335
                /* Always do fsync to reduce the probability that when
 
2336
                the OS crashes, a database page is only partially
 
2337
                physically written to disk. */
 
2338
 
 
2339
                ut_a(TRUE == os_file_flush(file));
 
2340
        }
 
2341
# endif /* UNIV_DO_FLUSH */
 
2342
 
 
2343
        return(ret);
 
2344
#else
 
2345
        {
 
2346
                off_t   ret_offset;
 
2347
# ifndef UNIV_HOTBACKUP
 
2348
                ulint   i;
 
2349
# endif /* !UNIV_HOTBACKUP */
 
2350
 
 
2351
                os_mutex_enter(os_file_count_mutex);
 
2352
                os_n_pending_writes++;
 
2353
                os_mutex_exit(os_file_count_mutex);
 
2354
 
 
2355
# ifndef UNIV_HOTBACKUP
 
2356
                /* Protect the seek / write operation with a mutex */
 
2357
                i = ((ulint) file) % OS_FILE_N_SEEK_MUTEXES;
 
2358
 
 
2359
                os_mutex_enter(os_file_seek_mutexes[i]);
 
2360
# endif /* UNIV_HOTBACKUP */
 
2361
 
 
2362
                ret_offset = lseek(file, offs, SEEK_SET);
 
2363
 
 
2364
                if (ret_offset < 0) {
 
2365
                        ret = -1;
 
2366
 
 
2367
                        goto func_exit;
 
2368
                }
 
2369
 
 
2370
                ret = write(file, buf, (ssize_t)n);
 
2371
 
 
2372
# ifdef UNIV_DO_FLUSH
 
2373
                if (srv_unix_file_flush_method != SRV_UNIX_LITTLESYNC
 
2374
                    && srv_unix_file_flush_method != SRV_UNIX_NOSYNC
 
2375
                    && !os_do_not_call_flush_at_each_write) {
 
2376
 
 
2377
                        /* Always do fsync to reduce the probability that when
 
2378
                        the OS crashes, a database page is only partially
 
2379
                        physically written to disk. */
 
2380
 
 
2381
                        ut_a(TRUE == os_file_flush(file));
 
2382
                }
 
2383
# endif /* UNIV_DO_FLUSH */
 
2384
 
 
2385
func_exit:
 
2386
# ifndef UNIV_HOTBACKUP
 
2387
                os_mutex_exit(os_file_seek_mutexes[i]);
 
2388
# endif /* !UNIV_HOTBACKUP */
 
2389
 
 
2390
                os_mutex_enter(os_file_count_mutex);
 
2391
                os_n_pending_writes--;
 
2392
                os_mutex_exit(os_file_count_mutex);
 
2393
 
 
2394
                return(ret);
 
2395
        }
 
2396
#endif
 
2397
}
 
2398
#endif
 
2399
 
 
2400
/*******************************************************************//**
 
2401
NOTE! Use the corresponding macro os_file_read(), not directly this
 
2402
function!
 
2403
Requests a synchronous positioned read operation.
 
2404
@return TRUE if request was successful, FALSE if fail */
 
2405
UNIV_INTERN
 
2406
ibool
 
2407
os_file_read_func(
 
2408
/*==============*/
 
2409
        os_file_t       file,   /*!< in: handle to a file */
 
2410
        void*           buf,    /*!< in: buffer where to read */
 
2411
        ulint           offset, /*!< in: least significant 32 bits of file
 
2412
                                offset where to read */
 
2413
        ulint           offset_high, /*!< in: most significant 32 bits of
 
2414
                                offset */
 
2415
        ulint           n)      /*!< in: number of bytes to read */
 
2416
{
 
2417
#ifdef __WIN__
 
2418
        BOOL            ret;
 
2419
        DWORD           len;
 
2420
        DWORD           ret2;
 
2421
        DWORD           low;
 
2422
        DWORD           high;
 
2423
        ibool           retry;
 
2424
#ifndef UNIV_HOTBACKUP
 
2425
        ulint           i;
 
2426
#endif /* !UNIV_HOTBACKUP */
 
2427
 
 
2428
        /* On 64-bit Windows, ulint is 64 bits. But offset and n should be
 
2429
        no more than 32 bits. */
 
2430
        ut_a((offset & 0xFFFFFFFFUL) == offset);
 
2431
        ut_a((n & 0xFFFFFFFFUL) == n);
 
2432
 
 
2433
        os_n_file_reads++;
 
2434
        os_bytes_read_since_printout += n;
 
2435
 
 
2436
try_again:
 
2437
        ut_ad(file);
 
2438
        ut_ad(buf);
 
2439
        ut_ad(n > 0);
 
2440
 
 
2441
        low = (DWORD) offset;
 
2442
        high = (DWORD) offset_high;
 
2443
 
 
2444
        os_mutex_enter(os_file_count_mutex);
 
2445
        os_n_pending_reads++;
 
2446
        os_mutex_exit(os_file_count_mutex);
 
2447
 
 
2448
#ifndef UNIV_HOTBACKUP
 
2449
        /* Protect the seek / read operation with a mutex */
 
2450
        i = ((ulint) file) % OS_FILE_N_SEEK_MUTEXES;
 
2451
 
 
2452
        os_mutex_enter(os_file_seek_mutexes[i]);
 
2453
#endif /* !UNIV_HOTBACKUP */
 
2454
 
 
2455
        ret2 = SetFilePointer(file, low, &high, FILE_BEGIN);
 
2456
 
 
2457
        if (ret2 == 0xFFFFFFFF && GetLastError() != NO_ERROR) {
 
2458
 
 
2459
#ifndef UNIV_HOTBACKUP
 
2460
                os_mutex_exit(os_file_seek_mutexes[i]);
 
2461
#endif /* !UNIV_HOTBACKUP */
 
2462
 
 
2463
                os_mutex_enter(os_file_count_mutex);
 
2464
                os_n_pending_reads--;
 
2465
                os_mutex_exit(os_file_count_mutex);
 
2466
 
 
2467
                goto error_handling;
 
2468
        }
 
2469
 
 
2470
        ret = ReadFile(file, buf, (DWORD) n, &len, NULL);
 
2471
 
 
2472
#ifndef UNIV_HOTBACKUP
 
2473
        os_mutex_exit(os_file_seek_mutexes[i]);
 
2474
#endif /* !UNIV_HOTBACKUP */
 
2475
 
 
2476
        os_mutex_enter(os_file_count_mutex);
 
2477
        os_n_pending_reads--;
 
2478
        os_mutex_exit(os_file_count_mutex);
 
2479
 
 
2480
        if (ret && len == n) {
 
2481
                return(TRUE);
 
2482
        }
 
2483
#else /* __WIN__ */
 
2484
        ibool   retry;
 
2485
        ssize_t ret;
 
2486
 
 
2487
        os_bytes_read_since_printout += n;
 
2488
 
 
2489
try_again:
 
2490
        ret = os_file_pread(file, buf, n, offset, offset_high);
 
2491
 
 
2492
        if ((ulint)ret == n) {
 
2493
 
 
2494
                return(TRUE);
 
2495
        }
 
2496
 
 
2497
        fprintf(stderr,
 
2498
                "InnoDB: Error: tried to read %lu bytes at offset %lu %lu.\n"
 
2499
                "InnoDB: Was only able to read %ld.\n",
 
2500
                (ulong)n, (ulong)offset_high,
 
2501
                (ulong)offset, (long)ret);
 
2502
#endif /* __WIN__ */
 
2503
#ifdef __WIN__
 
2504
error_handling:
 
2505
#endif
 
2506
        retry = os_file_handle_error(NULL, "read");
 
2507
 
 
2508
        if (retry) {
 
2509
                goto try_again;
 
2510
        }
 
2511
 
 
2512
        fprintf(stderr,
 
2513
                "InnoDB: Fatal error: cannot read from file."
 
2514
                " OS error number %lu.\n",
 
2515
#ifdef __WIN__
 
2516
                (ulong) GetLastError()
 
2517
#else
 
2518
                (ulong) errno
 
2519
#endif
 
2520
                );
 
2521
        fflush(stderr);
 
2522
 
 
2523
        ut_error;
 
2524
 
 
2525
        return(FALSE);
 
2526
}
 
2527
 
 
2528
/*******************************************************************//**
 
2529
NOTE! Use the corresponding macro os_file_read_no_error_handling(),
 
2530
not directly this function!
 
2531
Requests a synchronous positioned read operation. This function does not do
 
2532
any error handling. In case of error it returns FALSE.
 
2533
@return TRUE if request was successful, FALSE if fail */
 
2534
UNIV_INTERN
 
2535
ibool
 
2536
os_file_read_no_error_handling_func(
 
2537
/*================================*/
 
2538
        os_file_t       file,   /*!< in: handle to a file */
 
2539
        void*           buf,    /*!< in: buffer where to read */
 
2540
        ulint           offset, /*!< in: least significant 32 bits of file
 
2541
                                offset where to read */
 
2542
        ulint           offset_high, /*!< in: most significant 32 bits of
 
2543
                                offset */
 
2544
        ulint           n)      /*!< in: number of bytes to read */
 
2545
{
 
2546
#ifdef __WIN__
 
2547
        BOOL            ret;
 
2548
        DWORD           len;
 
2549
        DWORD           ret2;
 
2550
        DWORD           low;
 
2551
        DWORD           high;
 
2552
        ibool           retry;
 
2553
#ifndef UNIV_HOTBACKUP
 
2554
        ulint           i;
 
2555
#endif /* !UNIV_HOTBACKUP */
 
2556
 
 
2557
        /* On 64-bit Windows, ulint is 64 bits. But offset and n should be
 
2558
        no more than 32 bits. */
 
2559
        ut_a((offset & 0xFFFFFFFFUL) == offset);
 
2560
        ut_a((n & 0xFFFFFFFFUL) == n);
 
2561
 
 
2562
        os_n_file_reads++;
 
2563
        os_bytes_read_since_printout += n;
 
2564
 
 
2565
try_again:
 
2566
        ut_ad(file);
 
2567
        ut_ad(buf);
 
2568
        ut_ad(n > 0);
 
2569
 
 
2570
        low = (DWORD) offset;
 
2571
        high = (DWORD) offset_high;
 
2572
 
 
2573
        os_mutex_enter(os_file_count_mutex);
 
2574
        os_n_pending_reads++;
 
2575
        os_mutex_exit(os_file_count_mutex);
 
2576
 
 
2577
#ifndef UNIV_HOTBACKUP
 
2578
        /* Protect the seek / read operation with a mutex */
 
2579
        i = ((ulint) file) % OS_FILE_N_SEEK_MUTEXES;
 
2580
 
 
2581
        os_mutex_enter(os_file_seek_mutexes[i]);
 
2582
#endif /* !UNIV_HOTBACKUP */
 
2583
 
 
2584
        ret2 = SetFilePointer(file, low, &high, FILE_BEGIN);
 
2585
 
 
2586
        if (ret2 == 0xFFFFFFFF && GetLastError() != NO_ERROR) {
 
2587
 
 
2588
#ifndef UNIV_HOTBACKUP
 
2589
                os_mutex_exit(os_file_seek_mutexes[i]);
 
2590
#endif /* !UNIV_HOTBACKUP */
 
2591
 
 
2592
                os_mutex_enter(os_file_count_mutex);
 
2593
                os_n_pending_reads--;
 
2594
                os_mutex_exit(os_file_count_mutex);
 
2595
 
 
2596
                goto error_handling;
 
2597
        }
 
2598
 
 
2599
        ret = ReadFile(file, buf, (DWORD) n, &len, NULL);
 
2600
 
 
2601
#ifndef UNIV_HOTBACKUP
 
2602
        os_mutex_exit(os_file_seek_mutexes[i]);
 
2603
#endif /* !UNIV_HOTBACKUP */
 
2604
 
 
2605
        os_mutex_enter(os_file_count_mutex);
 
2606
        os_n_pending_reads--;
 
2607
        os_mutex_exit(os_file_count_mutex);
 
2608
 
 
2609
        if (ret && len == n) {
 
2610
                return(TRUE);
 
2611
        }
 
2612
#else /* __WIN__ */
 
2613
        ibool   retry;
 
2614
        ssize_t ret;
 
2615
 
 
2616
        os_bytes_read_since_printout += n;
 
2617
 
 
2618
try_again:
 
2619
        ret = os_file_pread(file, buf, n, offset, offset_high);
 
2620
 
 
2621
        if ((ulint)ret == n) {
 
2622
 
 
2623
                return(TRUE);
 
2624
        }
 
2625
#endif /* __WIN__ */
 
2626
#ifdef __WIN__
 
2627
error_handling:
 
2628
#endif
 
2629
        retry = os_file_handle_error_no_exit(NULL, "read");
 
2630
 
 
2631
        if (retry) {
 
2632
                goto try_again;
 
2633
        }
 
2634
 
 
2635
        return(FALSE);
 
2636
}
 
2637
 
 
2638
/*******************************************************************//**
 
2639
Rewind file to its start, read at most size - 1 bytes from it to str, and
 
2640
NUL-terminate str. All errors are silently ignored. This function is
 
2641
mostly meant to be used with temporary files. */
 
2642
UNIV_INTERN
 
2643
void
 
2644
os_file_read_string(
 
2645
/*================*/
 
2646
        FILE*   file,   /*!< in: file to read from */
 
2647
        char*   str,    /*!< in: buffer where to read */
 
2648
        ulint   size)   /*!< in: size of buffer */
 
2649
{
 
2650
        size_t  flen;
 
2651
 
 
2652
        if (size == 0) {
 
2653
                return;
 
2654
        }
 
2655
 
 
2656
        rewind(file);
 
2657
        flen = fread(str, 1, size - 1, file);
 
2658
        str[flen] = '\0';
 
2659
}
 
2660
 
 
2661
/*******************************************************************//**
 
2662
NOTE! Use the corresponding macro os_file_write(), not directly
 
2663
this function!
 
2664
Requests a synchronous write operation.
 
2665
@return TRUE if request was successful, FALSE if fail */
 
2666
UNIV_INTERN
 
2667
ibool
 
2668
os_file_write_func(
 
2669
/*===============*/
 
2670
        const char*     name,   /*!< in: name of the file or path as a
 
2671
                                null-terminated string */
 
2672
        os_file_t       file,   /*!< in: handle to a file */
 
2673
        const void*     buf,    /*!< in: buffer from which to write */
 
2674
        ulint           offset, /*!< in: least significant 32 bits of file
 
2675
                                offset where to write */
 
2676
        ulint           offset_high, /*!< in: most significant 32 bits of
 
2677
                                offset */
 
2678
        ulint           n)      /*!< in: number of bytes to write */
 
2679
{
 
2680
#ifdef __WIN__
 
2681
        BOOL            ret;
 
2682
        DWORD           len;
 
2683
        DWORD           ret2;
 
2684
        DWORD           low;
 
2685
        DWORD           high;
 
2686
        ulint           n_retries       = 0;
 
2687
        ulint           err;
 
2688
#ifndef UNIV_HOTBACKUP
 
2689
        ulint           i;
 
2690
#endif /* !UNIV_HOTBACKUP */
 
2691
 
 
2692
        /* On 64-bit Windows, ulint is 64 bits. But offset and n should be
 
2693
        no more than 32 bits. */
 
2694
        ut_a((offset & 0xFFFFFFFFUL) == offset);
 
2695
        ut_a((n & 0xFFFFFFFFUL) == n);
 
2696
 
 
2697
        os_n_file_writes++;
 
2698
 
 
2699
        ut_ad(file);
 
2700
        ut_ad(buf);
 
2701
        ut_ad(n > 0);
 
2702
retry:
 
2703
        low = (DWORD) offset;
 
2704
        high = (DWORD) offset_high;
 
2705
 
 
2706
        os_mutex_enter(os_file_count_mutex);
 
2707
        os_n_pending_writes++;
 
2708
        os_mutex_exit(os_file_count_mutex);
 
2709
 
 
2710
#ifndef UNIV_HOTBACKUP
 
2711
        /* Protect the seek / write operation with a mutex */
 
2712
        i = ((ulint) file) % OS_FILE_N_SEEK_MUTEXES;
 
2713
 
 
2714
        os_mutex_enter(os_file_seek_mutexes[i]);
 
2715
#endif /* !UNIV_HOTBACKUP */
 
2716
 
 
2717
        ret2 = SetFilePointer(file, low, &high, FILE_BEGIN);
 
2718
 
 
2719
        if (ret2 == 0xFFFFFFFF && GetLastError() != NO_ERROR) {
 
2720
 
 
2721
#ifndef UNIV_HOTBACKUP
 
2722
                os_mutex_exit(os_file_seek_mutexes[i]);
 
2723
#endif /* !UNIV_HOTBACKUP */
 
2724
 
 
2725
                os_mutex_enter(os_file_count_mutex);
 
2726
                os_n_pending_writes--;
 
2727
                os_mutex_exit(os_file_count_mutex);
 
2728
 
 
2729
                ut_print_timestamp(stderr);
 
2730
 
 
2731
                fprintf(stderr,
 
2732
                        "  InnoDB: Error: File pointer positioning to"
 
2733
                        " file %s failed at\n"
 
2734
                        "InnoDB: offset %lu %lu. Operating system"
 
2735
                        " error number %lu.\n"
 
2736
                        "InnoDB: Some operating system error numbers"
 
2737
                        " are described at\n"
 
2738
                        "InnoDB: "
 
2739
                        REFMAN "operating-system-error-codes.html\n",
 
2740
                        name, (ulong) offset_high, (ulong) offset,
 
2741
                        (ulong) GetLastError());
 
2742
 
 
2743
                return(FALSE);
 
2744
        }
 
2745
 
 
2746
        ret = WriteFile(file, buf, (DWORD) n, &len, NULL);
 
2747
 
 
2748
        /* Always do fsync to reduce the probability that when the OS crashes,
 
2749
        a database page is only partially physically written to disk. */
 
2750
 
 
2751
# ifdef UNIV_DO_FLUSH
 
2752
        if (!os_do_not_call_flush_at_each_write) {
 
2753
                ut_a(TRUE == os_file_flush(file));
 
2754
        }
 
2755
# endif /* UNIV_DO_FLUSH */
 
2756
 
 
2757
#ifndef UNIV_HOTBACKUP
 
2758
        os_mutex_exit(os_file_seek_mutexes[i]);
 
2759
#endif /* !UNIV_HOTBACKUP */
 
2760
 
 
2761
        os_mutex_enter(os_file_count_mutex);
 
2762
        os_n_pending_writes--;
 
2763
        os_mutex_exit(os_file_count_mutex);
 
2764
 
 
2765
        if (ret && len == n) {
 
2766
 
 
2767
                return(TRUE);
 
2768
        }
 
2769
 
 
2770
        /* If some background file system backup tool is running, then, at
 
2771
        least in Windows 2000, we may get here a specific error. Let us
 
2772
        retry the operation 100 times, with 1 second waits. */
 
2773
 
 
2774
        if (GetLastError() == ERROR_LOCK_VIOLATION && n_retries < 100) {
 
2775
 
 
2776
                os_thread_sleep(1000000);
 
2777
 
 
2778
                n_retries++;
 
2779
 
 
2780
                goto retry;
 
2781
        }
 
2782
 
 
2783
        if (!os_has_said_disk_full) {
 
2784
 
 
2785
                err = (ulint)GetLastError();
 
2786
 
 
2787
                ut_print_timestamp(stderr);
 
2788
 
 
2789
                fprintf(stderr,
 
2790
                        "  InnoDB: Error: Write to file %s failed"
 
2791
                        " at offset %lu %lu.\n"
 
2792
                        "InnoDB: %lu bytes should have been written,"
 
2793
                        " only %lu were written.\n"
 
2794
                        "InnoDB: Operating system error number %lu.\n"
 
2795
                        "InnoDB: Check that your OS and file system"
 
2796
                        " support files of this size.\n"
 
2797
                        "InnoDB: Check also that the disk is not full"
 
2798
                        " or a disk quota exceeded.\n",
 
2799
                        name, (ulong) offset_high, (ulong) offset,
 
2800
                        (ulong) n, (ulong) len, (ulong) err);
 
2801
 
 
2802
                if (strerror((int)err) != NULL) {
 
2803
                        fprintf(stderr,
 
2804
                                "InnoDB: Error number %lu means '%s'.\n",
 
2805
                                (ulong) err, strerror((int)err));
 
2806
                }
 
2807
 
 
2808
                fprintf(stderr,
 
2809
                        "InnoDB: Some operating system error numbers"
 
2810
                        " are described at\n"
 
2811
                        "InnoDB: "
 
2812
                        REFMAN "operating-system-error-codes.html\n");
 
2813
 
 
2814
                os_has_said_disk_full = TRUE;
 
2815
        }
 
2816
 
 
2817
        return(FALSE);
 
2818
#else
 
2819
        ssize_t ret;
 
2820
 
 
2821
        ret = os_file_pwrite(file, buf, n, offset, offset_high);
 
2822
 
 
2823
        if ((ulint)ret == n) {
 
2824
 
 
2825
                return(TRUE);
 
2826
        }
 
2827
 
 
2828
        if (!os_has_said_disk_full) {
 
2829
 
 
2830
                ut_print_timestamp(stderr);
 
2831
 
 
2832
                fprintf(stderr,
 
2833
                        "  InnoDB: Error: Write to file %s failed"
 
2834
                        " at offset %lu %lu.\n"
 
2835
                        "InnoDB: %lu bytes should have been written,"
 
2836
                        " only %ld were written.\n"
 
2837
                        "InnoDB: Operating system error number %lu.\n"
 
2838
                        "InnoDB: Check that your OS and file system"
 
2839
                        " support files of this size.\n"
 
2840
                        "InnoDB: Check also that the disk is not full"
 
2841
                        " or a disk quota exceeded.\n",
 
2842
                        name, offset_high, offset, n, (long int)ret,
 
2843
                        (ulint)errno);
 
2844
                if (strerror(errno) != NULL) {
 
2845
                        fprintf(stderr,
 
2846
                                "InnoDB: Error number %lu means '%s'.\n",
 
2847
                                (ulint)errno, strerror(errno));
 
2848
                }
 
2849
 
 
2850
                fprintf(stderr,
 
2851
                        "InnoDB: Some operating system error numbers"
 
2852
                        " are described at\n"
 
2853
                        "InnoDB: "
 
2854
                        REFMAN "operating-system-error-codes.html\n");
 
2855
 
 
2856
                os_has_said_disk_full = TRUE;
 
2857
        }
 
2858
 
 
2859
        return(FALSE);
 
2860
#endif
 
2861
}
 
2862
 
 
2863
/*******************************************************************//**
 
2864
Check the existence and type of the given file.
 
2865
@return TRUE if call succeeded */
 
2866
UNIV_INTERN
 
2867
ibool
 
2868
os_file_status(
 
2869
/*===========*/
 
2870
        const char*     path,   /*!< in:        pathname of the file */
 
2871
        ibool*          exists, /*!< out: TRUE if file exists */
 
2872
        os_file_type_t* type)   /*!< out: type of the file (if it exists) */
 
2873
{
 
2874
#ifdef __WIN__
 
2875
        int             ret;
 
2876
        struct _stat    statinfo;
 
2877
 
 
2878
        ret = _stat(path, &statinfo);
 
2879
        if (ret && (errno == ENOENT || errno == ENOTDIR)) {
 
2880
                /* file does not exist */
 
2881
                *exists = FALSE;
 
2882
                return(TRUE);
 
2883
        } else if (ret) {
 
2884
                /* file exists, but stat call failed */
 
2885
 
 
2886
                os_file_handle_error_no_exit(path, "stat");
 
2887
 
 
2888
                return(FALSE);
 
2889
        }
 
2890
 
 
2891
        if (_S_IFDIR & statinfo.st_mode) {
 
2892
                *type = OS_FILE_TYPE_DIR;
 
2893
        } else if (_S_IFREG & statinfo.st_mode) {
 
2894
                *type = OS_FILE_TYPE_FILE;
 
2895
        } else {
 
2896
                *type = OS_FILE_TYPE_UNKNOWN;
 
2897
        }
 
2898
 
 
2899
        *exists = TRUE;
 
2900
 
 
2901
        return(TRUE);
 
2902
#else
 
2903
        int             ret;
 
2904
        struct stat     statinfo;
 
2905
 
 
2906
        ret = stat(path, &statinfo);
 
2907
        if (ret && (errno == ENOENT || errno == ENOTDIR)) {
 
2908
                /* file does not exist */
 
2909
                *exists = FALSE;
 
2910
                return(TRUE);
 
2911
        } else if (ret) {
 
2912
                /* file exists, but stat call failed */
 
2913
 
 
2914
                os_file_handle_error_no_exit(path, "stat");
 
2915
 
 
2916
                return(FALSE);
 
2917
        }
 
2918
 
 
2919
        if (S_ISDIR(statinfo.st_mode)) {
 
2920
                *type = OS_FILE_TYPE_DIR;
 
2921
        } else if (S_ISLNK(statinfo.st_mode)) {
 
2922
                *type = OS_FILE_TYPE_LINK;
 
2923
        } else if (S_ISREG(statinfo.st_mode)) {
 
2924
                *type = OS_FILE_TYPE_FILE;
 
2925
        } else {
 
2926
                *type = OS_FILE_TYPE_UNKNOWN;
 
2927
        }
 
2928
 
 
2929
        *exists = TRUE;
 
2930
 
 
2931
        return(TRUE);
 
2932
#endif
 
2933
}
 
2934
 
 
2935
/*******************************************************************//**
 
2936
This function returns information about the specified file
 
2937
@return TRUE if stat information found */
 
2938
UNIV_INTERN
 
2939
ibool
 
2940
os_file_get_status(
 
2941
/*===============*/
 
2942
        const char*     path,           /*!< in:        pathname of the file */
 
2943
        os_file_stat_t* stat_info)      /*!< information of a file in a
 
2944
                                        directory */
 
2945
{
 
2946
#ifdef __WIN__
 
2947
        int             ret;
 
2948
        struct _stat    statinfo;
 
2949
 
 
2950
        ret = _stat(path, &statinfo);
 
2951
        if (ret && (errno == ENOENT || errno == ENOTDIR)) {
 
2952
                /* file does not exist */
 
2953
 
 
2954
                return(FALSE);
 
2955
        } else if (ret) {
 
2956
                /* file exists, but stat call failed */
 
2957
 
 
2958
                os_file_handle_error_no_exit(path, "stat");
 
2959
 
 
2960
                return(FALSE);
 
2961
        }
 
2962
        if (_S_IFDIR & statinfo.st_mode) {
 
2963
                stat_info->type = OS_FILE_TYPE_DIR;
 
2964
        } else if (_S_IFREG & statinfo.st_mode) {
 
2965
                stat_info->type = OS_FILE_TYPE_FILE;
 
2966
        } else {
 
2967
                stat_info->type = OS_FILE_TYPE_UNKNOWN;
 
2968
        }
 
2969
 
 
2970
        stat_info->ctime = statinfo.st_ctime;
 
2971
        stat_info->atime = statinfo.st_atime;
 
2972
        stat_info->mtime = statinfo.st_mtime;
 
2973
        stat_info->size  = statinfo.st_size;
 
2974
 
 
2975
        return(TRUE);
 
2976
#else
 
2977
        int             ret;
 
2978
        struct stat     statinfo;
 
2979
 
 
2980
        ret = stat(path, &statinfo);
 
2981
 
 
2982
        if (ret && (errno == ENOENT || errno == ENOTDIR)) {
 
2983
                /* file does not exist */
 
2984
 
 
2985
                return(FALSE);
 
2986
        } else if (ret) {
 
2987
                /* file exists, but stat call failed */
 
2988
 
 
2989
                os_file_handle_error_no_exit(path, "stat");
 
2990
 
 
2991
                return(FALSE);
 
2992
        }
 
2993
 
 
2994
        if (S_ISDIR(statinfo.st_mode)) {
 
2995
                stat_info->type = OS_FILE_TYPE_DIR;
 
2996
        } else if (S_ISLNK(statinfo.st_mode)) {
 
2997
                stat_info->type = OS_FILE_TYPE_LINK;
 
2998
        } else if (S_ISREG(statinfo.st_mode)) {
 
2999
                stat_info->type = OS_FILE_TYPE_FILE;
 
3000
        } else {
 
3001
                stat_info->type = OS_FILE_TYPE_UNKNOWN;
 
3002
        }
 
3003
 
 
3004
        stat_info->ctime = statinfo.st_ctime;
 
3005
        stat_info->atime = statinfo.st_atime;
 
3006
        stat_info->mtime = statinfo.st_mtime;
 
3007
        stat_info->size  = statinfo.st_size;
 
3008
 
 
3009
        return(TRUE);
 
3010
#endif
 
3011
}
 
3012
 
 
3013
/* path name separator character */
 
3014
#ifdef __WIN__
 
3015
#  define OS_FILE_PATH_SEPARATOR        '\\'
 
3016
#else
 
3017
#  define OS_FILE_PATH_SEPARATOR        '/'
 
3018
#endif
 
3019
 
 
3020
/****************************************************************//**
 
3021
The function os_file_dirname returns a directory component of a
 
3022
null-terminated pathname string.  In the usual case, dirname returns
 
3023
the string up to, but not including, the final '/', and basename
 
3024
is the component following the final '/'.  Trailing '/' characļæ½
 
3025
ters are not counted as part of the pathname.
 
3026
 
 
3027
If path does not contain a slash, dirname returns the string ".".
 
3028
 
 
3029
Concatenating the string returned by dirname, a "/", and the basename
 
3030
yields a complete pathname.
 
3031
 
 
3032
The return value is  a copy of the directory component of the pathname.
 
3033
The copy is allocated from heap. It is the caller responsibility
 
3034
to free it after it is no longer needed.
 
3035
 
 
3036
The following list of examples (taken from SUSv2) shows the strings
 
3037
returned by dirname and basename for different paths:
 
3038
 
 
3039
       path           dirname        basename
 
3040
       "/usr/lib"     "/usr"         "lib"
 
3041
       "/usr/"        "/"            "usr"
 
3042
       "usr"          "."            "usr"
 
3043
       "/"            "/"            "/"
 
3044
       "."            "."            "."
 
3045
       ".."           "."            ".."
 
3046
 
 
3047
@return own: directory component of the pathname */
 
3048
UNIV_INTERN
 
3049
char*
 
3050
os_file_dirname(
 
3051
/*============*/
 
3052
        const char*     path)   /*!< in: pathname */
 
3053
{
 
3054
        /* Find the offset of the last slash */
 
3055
        const char* last_slash = strrchr(path, OS_FILE_PATH_SEPARATOR);
 
3056
        if (!last_slash) {
 
3057
                /* No slash in the path, return "." */
 
3058
 
 
3059
                return(mem_strdup("."));
 
3060
        }
 
3061
 
 
3062
        /* Ok, there is a slash */
 
3063
 
 
3064
        if (last_slash == path) {
 
3065
                /* last slash is the first char of the path */
 
3066
 
 
3067
                return(mem_strdup("/"));
 
3068
        }
 
3069
 
 
3070
        /* Non-trivial directory component */
 
3071
 
 
3072
        return(mem_strdupl(path, last_slash - path));
 
3073
}
 
3074
 
 
3075
/****************************************************************//**
 
3076
Creates all missing subdirectories along the given path.
 
3077
@return TRUE if call succeeded FALSE otherwise */
 
3078
UNIV_INTERN
 
3079
ibool
 
3080
os_file_create_subdirs_if_needed(
 
3081
/*=============================*/
 
3082
        const char*     path)   /*!< in: path name */
 
3083
{
 
3084
        char*           subdir;
 
3085
        ibool           success, subdir_exists;
 
3086
        os_file_type_t  type;
 
3087
 
 
3088
        subdir = os_file_dirname(path);
 
3089
        if (strlen(subdir) == 1
 
3090
            && (*subdir == OS_FILE_PATH_SEPARATOR || *subdir == '.')) {
 
3091
                /* subdir is root or cwd, nothing to do */
 
3092
                mem_free(subdir);
 
3093
 
 
3094
                return(TRUE);
 
3095
        }
 
3096
 
 
3097
        /* Test if subdir exists */
 
3098
        success = os_file_status(subdir, &subdir_exists, &type);
 
3099
        if (success && !subdir_exists) {
 
3100
                /* subdir does not exist, create it */
 
3101
                success = os_file_create_subdirs_if_needed(subdir);
 
3102
                if (!success) {
 
3103
                        mem_free(subdir);
 
3104
 
 
3105
                        return(FALSE);
 
3106
                }
 
3107
                success = os_file_create_directory(subdir, FALSE);
 
3108
        }
 
3109
 
 
3110
        mem_free(subdir);
 
3111
 
 
3112
        return(success);
 
3113
}
 
3114
 
 
3115
#ifndef UNIV_HOTBACKUP
 
3116
/****************************************************************//**
 
3117
Returns a pointer to the nth slot in the aio array.
 
3118
@return pointer to slot */
 
3119
static
 
3120
os_aio_slot_t*
 
3121
os_aio_array_get_nth_slot(
 
3122
/*======================*/
 
3123
        os_aio_array_t*         array,  /*!< in: aio array */
 
3124
        ulint                   index)  /*!< in: index of the slot */
 
3125
{
 
3126
        ut_a(index < array->n_slots);
 
3127
 
 
3128
        return((array->slots) + index);
 
3129
}
 
3130
 
 
3131
#if defined(LINUX_NATIVE_AIO)
 
3132
/******************************************************************//**
 
3133
Creates an io_context for native linux AIO.
 
3134
@return TRUE on success. */
 
3135
static
 
3136
ibool
 
3137
os_aio_linux_create_io_ctx(
 
3138
/*=======================*/
 
3139
        ulint           max_events,     /*!< in: number of events. */
 
3140
        io_context_t*   io_ctx)         /*!< out: io_ctx to initialize. */
 
3141
{
 
3142
        int     ret;
 
3143
        ulint   retries = 0;
 
3144
 
 
3145
retry:
 
3146
        memset(io_ctx, 0x0, sizeof(*io_ctx));
 
3147
 
 
3148
        /* Initialize the io_ctx. Tell it how many pending
 
3149
        IO requests this context will handle. */
 
3150
 
 
3151
        ret = io_setup(max_events, io_ctx);
 
3152
        if (ret == 0) {
 
3153
#if defined(UNIV_AIO_DEBUG)
 
3154
                fprintf(stderr,
 
3155
                        "InnoDB: Linux native AIO:"
 
3156
                        " initialized io_ctx for segment\n");
 
3157
#endif
 
3158
                /* Success. Return now. */
 
3159
                return(TRUE);
 
3160
        }
 
3161
 
 
3162
        /* If we hit EAGAIN we'll make a few attempts before failing. */
 
3163
 
 
3164
        switch (ret) {
 
3165
        case -EAGAIN:
 
3166
                if (retries == 0) {
 
3167
                        /* First time around. */
 
3168
                        ut_print_timestamp(stderr);
 
3169
                        fprintf(stderr,
 
3170
                                "  InnoDB: Warning: io_setup() failed"
 
3171
                                " with EAGAIN. Will make %d attempts"
 
3172
                                " before giving up.\n",
 
3173
                                OS_AIO_IO_SETUP_RETRY_ATTEMPTS);
 
3174
                }
 
3175
 
 
3176
                if (retries < OS_AIO_IO_SETUP_RETRY_ATTEMPTS) {
 
3177
                        ++retries;
 
3178
                        fprintf(stderr,
 
3179
                                "InnoDB: Warning: io_setup() attempt"
 
3180
                                " %lu failed.\n",
 
3181
                                retries);
 
3182
                        os_thread_sleep(OS_AIO_IO_SETUP_RETRY_SLEEP);
 
3183
                        goto retry;
 
3184
                }
 
3185
 
 
3186
                /* Have tried enough. Better call it a day. */
 
3187
                ut_print_timestamp(stderr);
 
3188
                fprintf(stderr,
 
3189
                        "  InnoDB: Error: io_setup() failed"
 
3190
                        " with EAGAIN after %d attempts.\n",
 
3191
                        OS_AIO_IO_SETUP_RETRY_ATTEMPTS);
 
3192
                break;
 
3193
 
 
3194
        case -ENOSYS:
 
3195
                ut_print_timestamp(stderr);
 
3196
                fprintf(stderr,
 
3197
                        "  InnoDB: Error: Linux Native AIO interface"
 
3198
                        " is not supported on this platform. Please"
 
3199
                        " check your OS documentation and install"
 
3200
                        " appropriate binary of InnoDB.\n");
 
3201
 
 
3202
                break;
 
3203
 
 
3204
        default:
 
3205
                ut_print_timestamp(stderr);
 
3206
                fprintf(stderr,
 
3207
                        "  InnoDB: Error: Linux Native AIO setup"
 
3208
                        " returned following error[%d]\n", -ret);
 
3209
                break;
 
3210
        }
 
3211
 
 
3212
        fprintf(stderr,
 
3213
                "InnoDB: You can disable Linux Native AIO by"
 
3214
                " setting innodb_native_aio = off in my.cnf\n");
 
3215
        return(FALSE);
 
3216
}
 
3217
#endif /* LINUX_NATIVE_AIO */
 
3218
 
 
3219
/******************************************************************//**
 
3220
Creates an aio wait array. Note that we return NULL in case of failure.
 
3221
We don't care about freeing memory here because we assume that a
 
3222
failure will result in server refusing to start up.
 
3223
@return own: aio array, NULL on failure */
 
3224
static
 
3225
os_aio_array_t*
 
3226
os_aio_array_create(
 
3227
/*================*/
 
3228
        ulint   n,              /*!< in: maximum number of pending aio
 
3229
                                operations allowed; n must be
 
3230
                                divisible by n_segments */
 
3231
        ulint   n_segments)     /*!< in: number of segments in the aio array */
 
3232
{
 
3233
        os_aio_array_t* array;
 
3234
        ulint           i;
 
3235
        os_aio_slot_t*  slot;
 
3236
#ifdef WIN_ASYNC_IO
 
3237
        OVERLAPPED*     over;
 
3238
#elif defined(LINUX_NATIVE_AIO)
 
3239
        struct io_event*        io_event = NULL;
 
3240
#endif
 
3241
        ut_a(n > 0);
 
3242
        ut_a(n_segments > 0);
 
3243
 
 
3244
        array = ut_malloc(sizeof(os_aio_array_t));
 
3245
 
 
3246
        array->mutex            = os_mutex_create();
 
3247
        array->not_full         = os_event_create(NULL);
 
3248
        array->is_empty         = os_event_create(NULL);
 
3249
 
 
3250
        os_event_set(array->is_empty);
 
3251
 
 
3252
        array->n_slots          = n;
 
3253
        array->n_segments       = n_segments;
 
3254
        array->n_reserved       = 0;
 
3255
        array->cur_seg          = 0;
 
3256
        array->slots            = ut_malloc(n * sizeof(os_aio_slot_t));
 
3257
#ifdef __WIN__
 
3258
        array->handles          = ut_malloc(n * sizeof(HANDLE));
 
3259
#endif
 
3260
 
 
3261
#if defined(LINUX_NATIVE_AIO)
 
3262
        array->aio_ctx = NULL;
 
3263
        array->aio_events = NULL;
 
3264
 
 
3265
        /* If we are not using native aio interface then skip this
 
3266
        part of initialization. */
 
3267
        if (!srv_use_native_aio) {
 
3268
                goto skip_native_aio;
 
3269
        }
 
3270
 
 
3271
        /* Initialize the io_context array. One io_context
 
3272
        per segment in the array. */
 
3273
 
 
3274
        array->aio_ctx = ut_malloc(n_segments *
 
3275
                                   sizeof(*array->aio_ctx));
 
3276
        for (i = 0; i < n_segments; ++i) {
 
3277
                if (!os_aio_linux_create_io_ctx(n/n_segments,
 
3278
                                           &array->aio_ctx[i])) {
 
3279
                        /* If something bad happened during aio setup
 
3280
                        we should call it a day and return right away.
 
3281
                        We don't care about any leaks because a failure
 
3282
                        to initialize the io subsystem means that the
 
3283
                        server (or atleast the innodb storage engine)
 
3284
                        is not going to startup. */
 
3285
                        return(NULL);
 
3286
                }
 
3287
        }
 
3288
 
 
3289
        /* Initialize the event array. One event per slot. */
 
3290
        io_event = ut_malloc(n * sizeof(*io_event));
 
3291
        memset(io_event, 0x0, sizeof(*io_event) * n);
 
3292
        array->aio_events = io_event;
 
3293
 
 
3294
skip_native_aio:
 
3295
#endif /* LINUX_NATIVE_AIO */
 
3296
        for (i = 0; i < n; i++) {
 
3297
                slot = os_aio_array_get_nth_slot(array, i);
 
3298
 
 
3299
                slot->pos = i;
 
3300
                slot->reserved = FALSE;
 
3301
#ifdef WIN_ASYNC_IO
 
3302
                slot->handle = CreateEvent(NULL,TRUE, FALSE, NULL);
 
3303
 
 
3304
                over = &(slot->control);
 
3305
 
 
3306
                over->hEvent = slot->handle;
 
3307
 
 
3308
                *((array->handles) + i) = over->hEvent;
 
3309
 
 
3310
#elif defined(LINUX_NATIVE_AIO)
 
3311
 
 
3312
                memset(&slot->control, 0x0, sizeof(slot->control));
 
3313
                slot->n_bytes = 0;
 
3314
                slot->ret = 0;
 
3315
#endif
 
3316
        }
 
3317
 
 
3318
        return(array);
 
3319
}
 
3320
 
 
3321
/************************************************************************//**
 
3322
Frees an aio wait array. */
 
3323
static
 
3324
void
 
3325
os_aio_array_free(
 
3326
/*==============*/
 
3327
        os_aio_array_t* array)  /*!< in, own: array to free */
 
3328
{
 
3329
#ifdef WIN_ASYNC_IO
 
3330
        ulint   i;
 
3331
 
 
3332
        for (i = 0; i < array->n_slots; i++) {
 
3333
                os_aio_slot_t*  slot = os_aio_array_get_nth_slot(array, i);
 
3334
                CloseHandle(slot->handle);
 
3335
        }
 
3336
#endif /* WIN_ASYNC_IO */
 
3337
 
 
3338
#ifdef __WIN__
 
3339
        ut_free(array->handles);
 
3340
#endif /* __WIN__ */
 
3341
        os_mutex_free(array->mutex);
 
3342
        os_event_free(array->not_full);
 
3343
        os_event_free(array->is_empty);
 
3344
 
 
3345
#if defined(LINUX_NATIVE_AIO)
 
3346
        if (srv_use_native_aio) {
 
3347
                ut_free(array->aio_events);
 
3348
                ut_free(array->aio_ctx);
 
3349
        }
 
3350
#endif /* LINUX_NATIVE_AIO */
 
3351
 
 
3352
        ut_free(array->slots);
 
3353
        ut_free(array);
 
3354
}
 
3355
 
 
3356
/***********************************************************************
 
3357
Initializes the asynchronous io system. Creates one array each for ibuf
 
3358
and log i/o. Also creates one array each for read and write where each
 
3359
array is divided logically into n_read_segs and n_write_segs
 
3360
respectively. The caller must create an i/o handler thread for each
 
3361
segment in these arrays. This function also creates the sync array.
 
3362
No i/o handler thread needs to be created for that */
 
3363
UNIV_INTERN
 
3364
ibool
 
3365
os_aio_init(
 
3366
/*========*/
 
3367
        ulint   n_per_seg,      /*<! in: maximum number of pending aio
 
3368
                                operations allowed per segment */
 
3369
        ulint   n_read_segs,    /*<! in: number of reader threads */
 
3370
        ulint   n_write_segs,   /*<! in: number of writer threads */
 
3371
        ulint   n_slots_sync)   /*<! in: number of slots in the sync aio
 
3372
                                array */
 
3373
{
 
3374
        ulint   i;
 
3375
        ulint   n_segments = 2 + n_read_segs + n_write_segs;
 
3376
 
 
3377
        ut_ad(n_segments >= 4);
 
3378
 
 
3379
        os_io_init_simple();
 
3380
 
 
3381
        for (i = 0; i < n_segments; i++) {
 
3382
                srv_set_io_thread_op_info(i, "not started yet");
 
3383
        }
 
3384
 
 
3385
 
 
3386
        /* fprintf(stderr, "Array n per seg %lu\n", n_per_seg); */
 
3387
 
 
3388
        os_aio_ibuf_array = os_aio_array_create(n_per_seg, 1);
 
3389
        if (os_aio_ibuf_array == NULL) {
 
3390
                goto err_exit;
 
3391
        }
 
3392
 
 
3393
        srv_io_thread_function[0] = "insert buffer thread";
 
3394
 
 
3395
        os_aio_log_array = os_aio_array_create(n_per_seg, 1);
 
3396
        if (os_aio_log_array == NULL) {
 
3397
                goto err_exit;
 
3398
        }
 
3399
 
 
3400
        srv_io_thread_function[1] = "log thread";
 
3401
 
 
3402
        os_aio_read_array = os_aio_array_create(n_read_segs * n_per_seg,
 
3403
                                                n_read_segs);
 
3404
        if (os_aio_read_array == NULL) {
 
3405
                goto err_exit;
 
3406
        }
 
3407
 
 
3408
        for (i = 2; i < 2 + n_read_segs; i++) {
 
3409
                ut_a(i < SRV_MAX_N_IO_THREADS);
 
3410
                srv_io_thread_function[i] = "read thread";
 
3411
        }
 
3412
 
 
3413
        os_aio_write_array = os_aio_array_create(n_write_segs * n_per_seg,
 
3414
                                                 n_write_segs);
 
3415
        if (os_aio_write_array == NULL) {
 
3416
                goto err_exit;
 
3417
        }
 
3418
 
 
3419
        for (i = 2 + n_read_segs; i < n_segments; i++) {
 
3420
                ut_a(i < SRV_MAX_N_IO_THREADS);
 
3421
                srv_io_thread_function[i] = "write thread";
 
3422
        }
 
3423
 
 
3424
        os_aio_sync_array = os_aio_array_create(n_slots_sync, 1);
 
3425
        if (os_aio_sync_array == NULL) {
 
3426
                goto err_exit;
 
3427
        }
 
3428
 
 
3429
 
 
3430
        os_aio_n_segments = n_segments;
 
3431
 
 
3432
        os_aio_validate();
 
3433
 
 
3434
        os_aio_segment_wait_events = ut_malloc(n_segments * sizeof(void*));
 
3435
 
 
3436
        for (i = 0; i < n_segments; i++) {
 
3437
                os_aio_segment_wait_events[i] = os_event_create(NULL);
 
3438
        }
 
3439
 
 
3440
        os_last_printout = time(NULL);
 
3441
 
 
3442
        return(TRUE);
 
3443
 
 
3444
err_exit:
 
3445
        return(FALSE);
 
3446
 
 
3447
}
 
3448
 
 
3449
/***********************************************************************
 
3450
Frees the asynchronous io system. */
 
3451
UNIV_INTERN
 
3452
void
 
3453
os_aio_free(void)
 
3454
/*=============*/
 
3455
{
 
3456
        ulint   i;
 
3457
 
 
3458
        os_aio_array_free(os_aio_ibuf_array);
 
3459
        os_aio_ibuf_array = NULL;
 
3460
        os_aio_array_free(os_aio_log_array);
 
3461
        os_aio_log_array = NULL;
 
3462
        os_aio_array_free(os_aio_read_array);
 
3463
        os_aio_read_array = NULL;
 
3464
        os_aio_array_free(os_aio_write_array);
 
3465
        os_aio_write_array = NULL;
 
3466
        os_aio_array_free(os_aio_sync_array);
 
3467
        os_aio_sync_array = NULL;
 
3468
 
 
3469
        for (i = 0; i < os_aio_n_segments; i++) {
 
3470
                os_event_free(os_aio_segment_wait_events[i]);
 
3471
        }
 
3472
 
 
3473
        ut_free(os_aio_segment_wait_events);
 
3474
        os_aio_segment_wait_events = 0;
 
3475
        os_aio_n_segments = 0;
 
3476
}
 
3477
 
 
3478
#ifdef WIN_ASYNC_IO
 
3479
/************************************************************************//**
 
3480
Wakes up all async i/o threads in the array in Windows async i/o at
 
3481
shutdown. */
 
3482
static
 
3483
void
 
3484
os_aio_array_wake_win_aio_at_shutdown(
 
3485
/*==================================*/
 
3486
        os_aio_array_t* array)  /*!< in: aio array */
 
3487
{
 
3488
        ulint   i;
 
3489
 
 
3490
        for (i = 0; i < array->n_slots; i++) {
 
3491
 
 
3492
                SetEvent((array->slots + i)->handle);
 
3493
        }
 
3494
}
 
3495
#endif
 
3496
 
 
3497
/************************************************************************//**
 
3498
Wakes up all async i/o threads so that they know to exit themselves in
 
3499
shutdown. */
 
3500
UNIV_INTERN
 
3501
void
 
3502
os_aio_wake_all_threads_at_shutdown(void)
 
3503
/*=====================================*/
 
3504
{
 
3505
        ulint   i;
 
3506
 
 
3507
#ifdef WIN_ASYNC_IO
 
3508
        /* This code wakes up all ai/o threads in Windows native aio */
 
3509
        os_aio_array_wake_win_aio_at_shutdown(os_aio_read_array);
 
3510
        os_aio_array_wake_win_aio_at_shutdown(os_aio_write_array);
 
3511
        os_aio_array_wake_win_aio_at_shutdown(os_aio_ibuf_array);
 
3512
        os_aio_array_wake_win_aio_at_shutdown(os_aio_log_array);
 
3513
 
 
3514
#elif defined(LINUX_NATIVE_AIO)
 
3515
 
 
3516
        /* When using native AIO interface the io helper threads
 
3517
        wait on io_getevents with a timeout value of 500ms. At
 
3518
        each wake up these threads check the server status.
 
3519
        No need to do anything to wake them up. */
 
3520
 
 
3521
        if (srv_use_native_aio) {
 
3522
                return;
 
3523
        }
 
3524
        /* Fall through to simulated AIO handler wakeup if we are
 
3525
        not using native AIO. */
 
3526
#endif
 
3527
        /* This loop wakes up all simulated ai/o threads */
 
3528
 
 
3529
        for (i = 0; i < os_aio_n_segments; i++) {
 
3530
 
 
3531
                os_event_set(os_aio_segment_wait_events[i]);
 
3532
        }
 
3533
}
 
3534
 
 
3535
/************************************************************************//**
 
3536
Waits until there are no pending writes in os_aio_write_array. There can
 
3537
be other, synchronous, pending writes. */
 
3538
UNIV_INTERN
 
3539
void
 
3540
os_aio_wait_until_no_pending_writes(void)
 
3541
/*=====================================*/
 
3542
{
 
3543
        os_event_wait(os_aio_write_array->is_empty);
 
3544
}
 
3545
 
 
3546
/**********************************************************************//**
 
3547
Calculates segment number for a slot.
 
3548
@return segment number (which is the number used by, for example,
 
3549
i/o-handler threads) */
 
3550
static
 
3551
ulint
 
3552
os_aio_get_segment_no_from_slot(
 
3553
/*============================*/
 
3554
        os_aio_array_t* array,  /*!< in: aio wait array */
 
3555
        os_aio_slot_t*  slot)   /*!< in: slot in this array */
 
3556
{
 
3557
        ulint   segment;
 
3558
        ulint   seg_len;
 
3559
 
 
3560
        if (array == os_aio_ibuf_array) {
 
3561
                segment = 0;
 
3562
 
 
3563
        } else if (array == os_aio_log_array) {
 
3564
                segment = 1;
 
3565
 
 
3566
        } else if (array == os_aio_read_array) {
 
3567
                seg_len = os_aio_read_array->n_slots
 
3568
                        / os_aio_read_array->n_segments;
 
3569
 
 
3570
                segment = 2 + slot->pos / seg_len;
 
3571
        } else {
 
3572
                ut_a(array == os_aio_write_array);
 
3573
                seg_len = os_aio_write_array->n_slots
 
3574
                        / os_aio_write_array->n_segments;
 
3575
 
 
3576
                segment = os_aio_read_array->n_segments + 2
 
3577
                        + slot->pos / seg_len;
 
3578
        }
 
3579
 
 
3580
        return(segment);
 
3581
}
 
3582
 
 
3583
/**********************************************************************//**
 
3584
Calculates local segment number and aio array from global segment number.
 
3585
@return local segment number within the aio array */
 
3586
static
 
3587
ulint
 
3588
os_aio_get_array_and_local_segment(
 
3589
/*===============================*/
 
3590
        os_aio_array_t** array,         /*!< out: aio wait array */
 
3591
        ulint            global_segment)/*!< in: global segment number */
 
3592
{
 
3593
        ulint   segment;
 
3594
 
 
3595
        ut_a(global_segment < os_aio_n_segments);
 
3596
 
 
3597
        if (global_segment == 0) {
 
3598
                *array = os_aio_ibuf_array;
 
3599
                segment = 0;
 
3600
 
 
3601
        } else if (global_segment == 1) {
 
3602
                *array = os_aio_log_array;
 
3603
                segment = 0;
 
3604
 
 
3605
        } else if (global_segment < os_aio_read_array->n_segments + 2) {
 
3606
                *array = os_aio_read_array;
 
3607
 
 
3608
                segment = global_segment - 2;
 
3609
        } else {
 
3610
                *array = os_aio_write_array;
 
3611
 
 
3612
                segment = global_segment - (os_aio_read_array->n_segments + 2);
 
3613
        }
 
3614
 
 
3615
        return(segment);
 
3616
}
 
3617
 
 
3618
/*******************************************************************//**
 
3619
Requests for a slot in the aio array. If no slot is available, waits until
 
3620
not_full-event becomes signaled.
 
3621
@return pointer to slot */
 
3622
static
 
3623
os_aio_slot_t*
 
3624
os_aio_array_reserve_slot(
 
3625
/*======================*/
 
3626
        ulint           type,   /*!< in: OS_FILE_READ or OS_FILE_WRITE */
 
3627
        os_aio_array_t* array,  /*!< in: aio array */
 
3628
        fil_node_t*     message1,/*!< in: message to be passed along with
 
3629
                                the aio operation */
 
3630
        void*           message2,/*!< in: message to be passed along with
 
3631
                                the aio operation */
 
3632
        os_file_t       file,   /*!< in: file handle */
 
3633
        const char*     name,   /*!< in: name of the file or path as a
 
3634
                                null-terminated string */
 
3635
        void*           buf,    /*!< in: buffer where to read or from which
 
3636
                                to write */
 
3637
        ulint           offset, /*!< in: least significant 32 bits of file
 
3638
                                offset */
 
3639
        ulint           offset_high, /*!< in: most significant 32 bits of
 
3640
                                offset */
 
3641
        ulint           len)    /*!< in: length of the block to read or write */
 
3642
{
 
3643
        os_aio_slot_t*  slot = NULL;
 
3644
#ifdef WIN_ASYNC_IO
 
3645
        OVERLAPPED*     control;
 
3646
 
 
3647
#elif defined(LINUX_NATIVE_AIO)
 
3648
 
 
3649
        struct iocb*    iocb;
 
3650
        off_t           aio_offset;
 
3651
 
 
3652
#endif
 
3653
        ulint           i;
 
3654
        ulint           counter;
 
3655
        ulint           slots_per_seg;
 
3656
        ulint           local_seg;
 
3657
 
 
3658
#ifdef WIN_ASYNC_IO
 
3659
        ut_a((len & 0xFFFFFFFFUL) == len);
 
3660
#endif
 
3661
 
 
3662
        /* No need of a mutex. Only reading constant fields */
 
3663
        slots_per_seg = array->n_slots / array->n_segments;
 
3664
 
 
3665
        /* We attempt to keep adjacent blocks in the same local
 
3666
        segment. This can help in merging IO requests when we are
 
3667
        doing simulated AIO */
 
3668
        local_seg = (offset >> (UNIV_PAGE_SIZE_SHIFT + 6))
 
3669
                    % array->n_segments;
 
3670
 
 
3671
loop:
 
3672
        os_mutex_enter(array->mutex);
 
3673
 
 
3674
        if (array->n_reserved == array->n_slots) {
 
3675
                os_mutex_exit(array->mutex);
 
3676
 
 
3677
                if (!srv_use_native_aio) {
 
3678
                        /* If the handler threads are suspended, wake them
 
3679
                        so that we get more slots */
 
3680
 
 
3681
                        os_aio_simulated_wake_handler_threads();
 
3682
                }
 
3683
 
 
3684
                os_event_wait(array->not_full);
 
3685
 
 
3686
                goto loop;
 
3687
        }
 
3688
 
 
3689
        /* We start our search for an available slot from our preferred
 
3690
        local segment and do a full scan of the array. We are
 
3691
        guaranteed to find a slot in full scan. */
 
3692
        for (i = local_seg * slots_per_seg, counter = 0;
 
3693
             counter < array->n_slots; i++, counter++) {
 
3694
 
 
3695
                i %= array->n_slots;
 
3696
                slot = os_aio_array_get_nth_slot(array, i);
 
3697
 
 
3698
                if (slot->reserved == FALSE) {
 
3699
                        goto found;
 
3700
                }
 
3701
        }
 
3702
 
 
3703
        /* We MUST always be able to get hold of a reserved slot. */
 
3704
        ut_error;
 
3705
 
 
3706
found:
 
3707
        ut_a(slot->reserved == FALSE);
 
3708
        array->n_reserved++;
 
3709
 
 
3710
        if (array->n_reserved == 1) {
 
3711
                os_event_reset(array->is_empty);
 
3712
        }
 
3713
 
 
3714
        if (array->n_reserved == array->n_slots) {
 
3715
                os_event_reset(array->not_full);
 
3716
        }
 
3717
 
 
3718
        slot->reserved = TRUE;
 
3719
        slot->reservation_time = time(NULL);
 
3720
        slot->message1 = message1;
 
3721
        slot->message2 = message2;
 
3722
        slot->file     = file;
 
3723
        slot->name     = name;
 
3724
        slot->len      = len;
 
3725
        slot->type     = type;
 
3726
        slot->buf      = buf;
 
3727
        slot->offset   = offset;
 
3728
        slot->offset_high = offset_high;
 
3729
        slot->io_already_done = FALSE;
 
3730
 
 
3731
#ifdef WIN_ASYNC_IO
 
3732
        control = &(slot->control);
 
3733
        control->Offset = (DWORD)offset;
 
3734
        control->OffsetHigh = (DWORD)offset_high;
 
3735
        ResetEvent(slot->handle);
 
3736
 
 
3737
#elif defined(LINUX_NATIVE_AIO)
 
3738
 
 
3739
        /* If we are not using native AIO skip this part. */
 
3740
        if (!srv_use_native_aio) {
 
3741
                goto skip_native_aio;
 
3742
        }
 
3743
 
 
3744
        /* Check if we are dealing with 64 bit arch.
 
3745
        If not then make sure that offset fits in 32 bits. */
 
3746
        if (sizeof(aio_offset) == 8) {
 
3747
                aio_offset = offset_high;
 
3748
                aio_offset <<= 32;
 
3749
                aio_offset += offset;
 
3750
        } else {
 
3751
                ut_a(offset_high == 0);
 
3752
                aio_offset = offset;
 
3753
        }
 
3754
 
 
3755
        iocb = &slot->control;
 
3756
 
 
3757
        if (type == OS_FILE_READ) {
 
3758
                io_prep_pread(iocb, file, buf, len, aio_offset);
 
3759
        } else {
 
3760
                ut_a(type == OS_FILE_WRITE);
 
3761
                io_prep_pwrite(iocb, file, buf, len, aio_offset);
 
3762
        }
 
3763
 
 
3764
        iocb->data = (void*)slot;
 
3765
        slot->n_bytes = 0;
 
3766
        slot->ret = 0;
 
3767
        /*fprintf(stderr, "Filled up Linux native iocb.\n");*/
 
3768
        
 
3769
 
 
3770
skip_native_aio:
 
3771
#endif /* LINUX_NATIVE_AIO */
 
3772
        os_mutex_exit(array->mutex);
 
3773
 
 
3774
        return(slot);
 
3775
}
 
3776
 
 
3777
/*******************************************************************//**
 
3778
Frees a slot in the aio array. */
 
3779
static
 
3780
void
 
3781
os_aio_array_free_slot(
 
3782
/*===================*/
 
3783
        os_aio_array_t* array,  /*!< in: aio array */
 
3784
        os_aio_slot_t*  slot)   /*!< in: pointer to slot */
 
3785
{
 
3786
        ut_ad(array);
 
3787
        ut_ad(slot);
 
3788
 
 
3789
        os_mutex_enter(array->mutex);
 
3790
 
 
3791
        ut_ad(slot->reserved);
 
3792
 
 
3793
        slot->reserved = FALSE;
 
3794
 
 
3795
        array->n_reserved--;
 
3796
 
 
3797
        if (array->n_reserved == array->n_slots - 1) {
 
3798
                os_event_set(array->not_full);
 
3799
        }
 
3800
 
 
3801
        if (array->n_reserved == 0) {
 
3802
                os_event_set(array->is_empty);
 
3803
        }
 
3804
 
 
3805
#ifdef WIN_ASYNC_IO
 
3806
 
 
3807
        ResetEvent(slot->handle);
 
3808
 
 
3809
#elif defined(LINUX_NATIVE_AIO)
 
3810
 
 
3811
        if (srv_use_native_aio) {
 
3812
                memset(&slot->control, 0x0, sizeof(slot->control));
 
3813
                slot->n_bytes = 0;
 
3814
                slot->ret = 0;
 
3815
                /*fprintf(stderr, "Freed up Linux native slot.\n");*/
 
3816
        } else {
 
3817
                /* These fields should not be used if we are not
 
3818
                using native AIO. */
 
3819
                ut_ad(slot->n_bytes == 0);
 
3820
                ut_ad(slot->ret == 0);
 
3821
        }
 
3822
 
 
3823
#endif
 
3824
        os_mutex_exit(array->mutex);
 
3825
}
 
3826
 
 
3827
/**********************************************************************//**
 
3828
Wakes up a simulated aio i/o-handler thread if it has something to do. */
 
3829
static
 
3830
void
 
3831
os_aio_simulated_wake_handler_thread(
 
3832
/*=================================*/
 
3833
        ulint   global_segment) /*!< in: the number of the segment in the aio
 
3834
                                arrays */
 
3835
{
 
3836
        os_aio_array_t* array;
 
3837
        os_aio_slot_t*  slot;
 
3838
        ulint           segment;
 
3839
        ulint           n;
 
3840
        ulint           i;
 
3841
 
 
3842
        ut_ad(!srv_use_native_aio);
 
3843
 
 
3844
        segment = os_aio_get_array_and_local_segment(&array, global_segment);
 
3845
 
 
3846
        n = array->n_slots / array->n_segments;
 
3847
 
 
3848
        /* Look through n slots after the segment * n'th slot */
 
3849
 
 
3850
        os_mutex_enter(array->mutex);
 
3851
 
 
3852
        for (i = 0; i < n; i++) {
 
3853
                slot = os_aio_array_get_nth_slot(array, i + segment * n);
 
3854
 
 
3855
                if (slot->reserved) {
 
3856
                        /* Found an i/o request */
 
3857
 
 
3858
                        break;
 
3859
                }
 
3860
        }
 
3861
 
 
3862
        os_mutex_exit(array->mutex);
 
3863
 
 
3864
        if (i < n) {
 
3865
                os_event_set(os_aio_segment_wait_events[global_segment]);
 
3866
        }
 
3867
}
 
3868
 
 
3869
/**********************************************************************//**
 
3870
Wakes up simulated aio i/o-handler threads if they have something to do. */
 
3871
UNIV_INTERN
 
3872
void
 
3873
os_aio_simulated_wake_handler_threads(void)
 
3874
/*=======================================*/
 
3875
{
 
3876
        ulint   i;
 
3877
 
 
3878
        if (srv_use_native_aio) {
 
3879
                /* We do not use simulated aio: do nothing */
 
3880
 
 
3881
                return;
 
3882
        }
 
3883
 
 
3884
        os_aio_recommend_sleep_for_read_threads = FALSE;
 
3885
 
 
3886
        for (i = 0; i < os_aio_n_segments; i++) {
 
3887
                os_aio_simulated_wake_handler_thread(i);
 
3888
        }
 
3889
}
 
3890
 
 
3891
/**********************************************************************//**
 
3892
This function can be called if one wants to post a batch of reads and
 
3893
prefers an i/o-handler thread to handle them all at once later. You must
 
3894
call os_aio_simulated_wake_handler_threads later to ensure the threads
 
3895
are not left sleeping! */
 
3896
UNIV_INTERN
 
3897
void
 
3898
os_aio_simulated_put_read_threads_to_sleep(void)
 
3899
/*============================================*/
 
3900
{
 
3901
 
 
3902
/* The idea of putting background IO threads to sleep is only for
 
3903
Windows when using simulated AIO. Windows XP seems to schedule
 
3904
background threads too eagerly to allow for coalescing during
 
3905
readahead requests. */
 
3906
#ifdef __WIN__
 
3907
        os_aio_array_t* array;
 
3908
        ulint           g;
 
3909
 
 
3910
        if (srv_use_native_aio) {
 
3911
                /* We do not use simulated aio: do nothing */
 
3912
 
 
3913
                return;
 
3914
        }
 
3915
 
 
3916
        os_aio_recommend_sleep_for_read_threads = TRUE;
 
3917
 
 
3918
        for (g = 0; g < os_aio_n_segments; g++) {
 
3919
                os_aio_get_array_and_local_segment(&array, g);
 
3920
 
 
3921
                if (array == os_aio_read_array) {
 
3922
 
 
3923
                        os_event_reset(os_aio_segment_wait_events[g]);
 
3924
                }
 
3925
        }
 
3926
#endif /* __WIN__ */
 
3927
}
 
3928
 
 
3929
#if defined(LINUX_NATIVE_AIO)
 
3930
/*******************************************************************//**
 
3931
Dispatch an AIO request to the kernel.
 
3932
@return TRUE on success. */
 
3933
static
 
3934
ibool
 
3935
os_aio_linux_dispatch(
 
3936
/*==================*/
 
3937
        os_aio_array_t* array,  /*!< in: io request array. */
 
3938
        os_aio_slot_t*  slot)   /*!< in: an already reserved slot. */
 
3939
{
 
3940
        int             ret;
 
3941
        ulint           io_ctx_index;
 
3942
        struct iocb*    iocb;
 
3943
 
 
3944
        ut_ad(slot != NULL);
 
3945
        ut_ad(array);
 
3946
 
 
3947
        ut_a(slot->reserved);
 
3948
 
 
3949
        /* Find out what we are going to work with.
 
3950
        The iocb struct is directly in the slot.
 
3951
        The io_context is one per segment. */
 
3952
 
 
3953
        iocb = &slot->control;
 
3954
        io_ctx_index = (slot->pos * array->n_segments) / array->n_slots;
 
3955
 
 
3956
        ret = io_submit(array->aio_ctx[io_ctx_index], 1, &iocb);
 
3957
 
 
3958
#if defined(UNIV_AIO_DEBUG)
 
3959
        fprintf(stderr,
 
3960
                "io_submit[%c] ret[%d]: slot[%p] ctx[%p] seg[%lu]\n",
 
3961
                (slot->type == OS_FILE_WRITE) ? 'w' : 'r', ret, slot,
 
3962
                array->aio_ctx[io_ctx_index], (ulong)io_ctx_index);
 
3963
#endif
 
3964
 
 
3965
        /* io_submit returns number of successfully
 
3966
        queued requests or -errno. */
 
3967
        if (UNIV_UNLIKELY(ret != 1)) {
 
3968
                errno = -ret;
 
3969
                return(FALSE);
 
3970
        }
 
3971
 
 
3972
        return(TRUE);
 
3973
}
 
3974
#endif /* LINUX_NATIVE_AIO */
 
3975
 
 
3976
 
 
3977
/*******************************************************************//**
 
3978
NOTE! Use the corresponding macro os_aio(), not directly this function!
 
3979
Requests an asynchronous i/o operation.
 
3980
@return TRUE if request was queued successfully, FALSE if fail */
 
3981
UNIV_INTERN
 
3982
ibool
 
3983
os_aio_func(
 
3984
/*========*/
 
3985
        ulint           type,   /*!< in: OS_FILE_READ or OS_FILE_WRITE */
 
3986
        ulint           mode,   /*!< in: OS_AIO_NORMAL, ..., possibly ORed
 
3987
                                to OS_AIO_SIMULATED_WAKE_LATER: the
 
3988
                                last flag advises this function not to wake
 
3989
                                i/o-handler threads, but the caller will
 
3990
                                do the waking explicitly later, in this
 
3991
                                way the caller can post several requests in
 
3992
                                a batch; NOTE that the batch must not be
 
3993
                                so big that it exhausts the slots in aio
 
3994
                                arrays! NOTE that a simulated batch
 
3995
                                may introduce hidden chances of deadlocks,
 
3996
                                because i/os are not actually handled until
 
3997
                                all have been posted: use with great
 
3998
                                caution! */
 
3999
        const char*     name,   /*!< in: name of the file or path as a
 
4000
                                null-terminated string */
 
4001
        os_file_t       file,   /*!< in: handle to a file */
 
4002
        void*           buf,    /*!< in: buffer where to read or from which
 
4003
                                to write */
 
4004
        ulint           offset, /*!< in: least significant 32 bits of file
 
4005
                                offset where to read or write */
 
4006
        ulint           offset_high, /*!< in: most significant 32 bits of
 
4007
                                offset */
 
4008
        ulint           n,      /*!< in: number of bytes to read or write */
 
4009
        fil_node_t*     message1,/*!< in: message for the aio handler
 
4010
                                (can be used to identify a completed
 
4011
                                aio operation); ignored if mode is
 
4012
                                OS_AIO_SYNC */
 
4013
        void*           message2)/*!< in: message for the aio handler
 
4014
                                (can be used to identify a completed
 
4015
                                aio operation); ignored if mode is
 
4016
                                OS_AIO_SYNC */
 
4017
{
 
4018
        os_aio_array_t* array;
 
4019
        os_aio_slot_t*  slot;
 
4020
#ifdef WIN_ASYNC_IO
 
4021
        ibool           retval;
 
4022
        BOOL            ret             = TRUE;
 
4023
        DWORD           len             = (DWORD) n;
 
4024
        struct fil_node_struct * dummy_mess1;
 
4025
        void*           dummy_mess2;
 
4026
        ulint           dummy_type;
 
4027
#endif /* WIN_ASYNC_IO */
 
4028
        ibool           retry;
 
4029
        ulint           wake_later;
 
4030
 
 
4031
        ut_ad(file);
 
4032
        ut_ad(buf);
 
4033
        ut_ad(n > 0);
 
4034
        ut_ad(n % OS_FILE_LOG_BLOCK_SIZE == 0);
 
4035
        ut_ad(offset % OS_FILE_LOG_BLOCK_SIZE == 0);
 
4036
        ut_ad(os_aio_validate_skip());
 
4037
#ifdef WIN_ASYNC_IO
 
4038
        ut_ad((n & 0xFFFFFFFFUL) == n);
 
4039
#endif
 
4040
 
 
4041
        wake_later = mode & OS_AIO_SIMULATED_WAKE_LATER;
 
4042
        mode = mode & (~OS_AIO_SIMULATED_WAKE_LATER);
 
4043
 
 
4044
        if (mode == OS_AIO_SYNC
 
4045
#ifdef WIN_ASYNC_IO
 
4046
            && !srv_use_native_aio
 
4047
#endif /* WIN_ASYNC_IO */
 
4048
            ) {
 
4049
                /* This is actually an ordinary synchronous read or write:
 
4050
                no need to use an i/o-handler thread. NOTE that if we use
 
4051
                Windows async i/o, Windows does not allow us to use
 
4052
                ordinary synchronous os_file_read etc. on the same file,
 
4053
                therefore we have built a special mechanism for synchronous
 
4054
                wait in the Windows case.
 
4055
                Also note that the Performance Schema instrumentation has
 
4056
                been performed by current os_aio_func()'s wrapper function
 
4057
                pfs_os_aio_func(). So we would no longer need to call
 
4058
                Performance Schema instrumented os_file_read() and
 
4059
                os_file_write(). Instead, we should use os_file_read_func()
 
4060
                and os_file_write_func() */
 
4061
 
 
4062
                if (type == OS_FILE_READ) {
 
4063
                        return(os_file_read_func(file, buf, offset,
 
4064
                                            offset_high, n));
 
4065
                }
 
4066
 
 
4067
                ut_a(type == OS_FILE_WRITE);
 
4068
 
 
4069
                return(os_file_write_func(name, file, buf, offset,
 
4070
                                          offset_high, n));
 
4071
        }
 
4072
 
 
4073
try_again:
 
4074
        switch (mode) {
 
4075
        case OS_AIO_NORMAL:
 
4076
                array = (type == OS_FILE_READ)
 
4077
                        ? os_aio_read_array
 
4078
                        : os_aio_write_array;
 
4079
                break;
 
4080
        case OS_AIO_IBUF:
 
4081
                ut_ad(type == OS_FILE_READ);
 
4082
                /* Reduce probability of deadlock bugs in connection with ibuf:
 
4083
                do not let the ibuf i/o handler sleep */
 
4084
 
 
4085
                wake_later = FALSE;
 
4086
 
 
4087
                array = os_aio_ibuf_array;
 
4088
                break;
 
4089
        case OS_AIO_LOG:
 
4090
                array = os_aio_log_array;
 
4091
                break;
 
4092
        case OS_AIO_SYNC:
 
4093
                array = os_aio_sync_array;
 
4094
 
 
4095
#if defined(LINUX_NATIVE_AIO)
 
4096
                /* In Linux native AIO we don't use sync IO array. */
 
4097
                ut_a(!srv_use_native_aio);
 
4098
#endif /* LINUX_NATIVE_AIO */
 
4099
                break;
 
4100
        default:
 
4101
                ut_error;
 
4102
                array = NULL; /* Eliminate compiler warning */
 
4103
        }
 
4104
 
 
4105
        slot = os_aio_array_reserve_slot(type, array, message1, message2, file,
 
4106
                                         name, buf, offset, offset_high, n);
 
4107
        if (type == OS_FILE_READ) {
 
4108
                if (srv_use_native_aio) {
 
4109
                        os_n_file_reads++;
 
4110
                        os_bytes_read_since_printout += n;
 
4111
#ifdef WIN_ASYNC_IO
 
4112
                        ret = ReadFile(file, buf, (DWORD)n, &len,
 
4113
                                       &(slot->control));
 
4114
 
 
4115
#elif defined(LINUX_NATIVE_AIO)
 
4116
                        if (!os_aio_linux_dispatch(array, slot)) {
 
4117
                                goto err_exit;
 
4118
                        }
 
4119
#endif
 
4120
                } else {
 
4121
                        if (!wake_later) {
 
4122
                                os_aio_simulated_wake_handler_thread(
 
4123
                                        os_aio_get_segment_no_from_slot(
 
4124
                                                array, slot));
 
4125
                        }
 
4126
                }
 
4127
        } else if (type == OS_FILE_WRITE) {
 
4128
                if (srv_use_native_aio) {
 
4129
                        os_n_file_writes++;
 
4130
#ifdef WIN_ASYNC_IO
 
4131
                        ret = WriteFile(file, buf, (DWORD)n, &len,
 
4132
                                        &(slot->control));
 
4133
 
 
4134
#elif defined(LINUX_NATIVE_AIO)
 
4135
                        if (!os_aio_linux_dispatch(array, slot)) {
 
4136
                                goto err_exit;
 
4137
                        }
 
4138
#endif
 
4139
                } else {
 
4140
                        if (!wake_later) {
 
4141
                                os_aio_simulated_wake_handler_thread(
 
4142
                                        os_aio_get_segment_no_from_slot(
 
4143
                                                array, slot));
 
4144
                        }
 
4145
                }
 
4146
        } else {
 
4147
                ut_error;
 
4148
        }
 
4149
 
 
4150
#ifdef WIN_ASYNC_IO
 
4151
        if (srv_use_native_aio) {
 
4152
                if ((ret && len == n)
 
4153
                    || (!ret && GetLastError() == ERROR_IO_PENDING)) {
 
4154
                        /* aio was queued successfully! */
 
4155
 
 
4156
                        if (mode == OS_AIO_SYNC) {
 
4157
                                /* We want a synchronous i/o operation on a
 
4158
                                file where we also use async i/o: in Windows
 
4159
                                we must use the same wait mechanism as for
 
4160
                                async i/o */
 
4161
 
 
4162
                                retval = os_aio_windows_handle(ULINT_UNDEFINED,
 
4163
                                                               slot->pos,
 
4164
                                                               &dummy_mess1,
 
4165
                                                               &dummy_mess2,
 
4166
                                                               &dummy_type);
 
4167
 
 
4168
                                return(retval);
 
4169
                        }
 
4170
 
 
4171
                        return(TRUE);
 
4172
                }
 
4173
 
 
4174
                goto err_exit;
 
4175
        }
 
4176
#endif /* WIN_ASYNC_IO */
 
4177
        /* aio was queued successfully! */
 
4178
        return(TRUE);
 
4179
 
 
4180
#if defined LINUX_NATIVE_AIO || defined WIN_ASYNC_IO
 
4181
err_exit:
 
4182
#endif /* LINUX_NATIVE_AIO || WIN_ASYNC_IO */
 
4183
        os_aio_array_free_slot(array, slot);
 
4184
 
 
4185
        retry = os_file_handle_error(name,
 
4186
                                     type == OS_FILE_READ
 
4187
                                     ? "aio read" : "aio write");
 
4188
        if (retry) {
 
4189
 
 
4190
                goto try_again;
 
4191
        }
 
4192
 
 
4193
        return(FALSE);
 
4194
}
 
4195
 
 
4196
#ifdef WIN_ASYNC_IO
 
4197
/**********************************************************************//**
 
4198
This function is only used in Windows asynchronous i/o.
 
4199
Waits for an aio operation to complete. This function is used to wait the
 
4200
for completed requests. The aio array of pending requests is divided
 
4201
into segments. The thread specifies which segment or slot it wants to wait
 
4202
for. NOTE: this function will also take care of freeing the aio slot,
 
4203
therefore no other thread is allowed to do the freeing!
 
4204
@return TRUE if the aio operation succeeded */
 
4205
UNIV_INTERN
 
4206
ibool
 
4207
os_aio_windows_handle(
 
4208
/*==================*/
 
4209
        ulint   segment,        /*!< in: the number of the segment in the aio
 
4210
                                arrays to wait for; segment 0 is the ibuf
 
4211
                                i/o thread, segment 1 the log i/o thread,
 
4212
                                then follow the non-ibuf read threads, and as
 
4213
                                the last are the non-ibuf write threads; if
 
4214
                                this is ULINT_UNDEFINED, then it means that
 
4215
                                sync aio is used, and this parameter is
 
4216
                                ignored */
 
4217
        ulint   pos,            /*!< this parameter is used only in sync aio:
 
4218
                                wait for the aio slot at this position */
 
4219
        fil_node_t**message1,   /*!< out: the messages passed with the aio
 
4220
                                request; note that also in the case where
 
4221
                                the aio operation failed, these output
 
4222
                                parameters are valid and can be used to
 
4223
                                restart the operation, for example */
 
4224
        void**  message2,
 
4225
        ulint*  type)           /*!< out: OS_FILE_WRITE or ..._READ */
 
4226
{
 
4227
        ulint           orig_seg        = segment;
 
4228
        os_aio_array_t* array;
 
4229
        os_aio_slot_t*  slot;
 
4230
        ulint           n;
 
4231
        ulint           i;
 
4232
        ibool           ret_val;
 
4233
        BOOL            ret;
 
4234
        DWORD           len;
 
4235
        BOOL            retry           = FALSE;
 
4236
 
 
4237
        if (segment == ULINT_UNDEFINED) {
 
4238
                array = os_aio_sync_array;
 
4239
                segment = 0;
 
4240
        } else {
 
4241
                segment = os_aio_get_array_and_local_segment(&array, segment);
 
4242
        }
 
4243
 
 
4244
        /* NOTE! We only access constant fields in os_aio_array. Therefore
 
4245
        we do not have to acquire the protecting mutex yet */
 
4246
 
 
4247
        ut_ad(os_aio_validate_skip());
 
4248
        ut_ad(segment < array->n_segments);
 
4249
 
 
4250
        n = array->n_slots / array->n_segments;
 
4251
 
 
4252
        if (array == os_aio_sync_array) {
 
4253
                WaitForSingleObject(
 
4254
                        os_aio_array_get_nth_slot(array, pos)->handle,
 
4255
                        INFINITE);
 
4256
                i = pos;
 
4257
        } else {
 
4258
                srv_set_io_thread_op_info(orig_seg, "wait Windows aio");
 
4259
                i = WaitForMultipleObjects((DWORD) n,
 
4260
                                           array->handles + segment * n,
 
4261
                                           FALSE,
 
4262
                                           INFINITE);
 
4263
        }
 
4264
 
 
4265
        os_mutex_enter(array->mutex);
 
4266
 
 
4267
        if (srv_shutdown_state == SRV_SHUTDOWN_EXIT_THREADS
 
4268
            && array->n_reserved == 0) {
 
4269
                *message1 = NULL;
 
4270
                *message2 = NULL;
 
4271
                os_mutex_exit(array->mutex);
 
4272
                return(TRUE);
 
4273
        }
 
4274
 
 
4275
        ut_a(i >= WAIT_OBJECT_0 && i <= WAIT_OBJECT_0 + n);
 
4276
 
 
4277
        slot = os_aio_array_get_nth_slot(array, i + segment * n);
 
4278
 
 
4279
        ut_a(slot->reserved);
 
4280
 
 
4281
        if (orig_seg != ULINT_UNDEFINED) {
 
4282
                srv_set_io_thread_op_info(orig_seg,
 
4283
                                          "get windows aio return value");
 
4284
        }
 
4285
 
 
4286
        ret = GetOverlappedResult(slot->file, &(slot->control), &len, TRUE);
 
4287
 
 
4288
        *message1 = slot->message1;
 
4289
        *message2 = slot->message2;
 
4290
 
 
4291
        *type = slot->type;
 
4292
 
 
4293
        if (ret && len == slot->len) {
 
4294
                ret_val = TRUE;
 
4295
 
 
4296
#ifdef UNIV_DO_FLUSH
 
4297
                if (slot->type == OS_FILE_WRITE
 
4298
                    && !os_do_not_call_flush_at_each_write) {
 
4299
                        if (!os_file_flush(slot->file)) {
 
4300
                                ut_error;
 
4301
                        }
 
4302
                }
 
4303
#endif /* UNIV_DO_FLUSH */
 
4304
        } else if (os_file_handle_error(slot->name, "Windows aio")) {
 
4305
 
 
4306
                retry = TRUE;
 
4307
        } else {
 
4308
 
 
4309
                ret_val = FALSE;
 
4310
        }
 
4311
 
 
4312
        os_mutex_exit(array->mutex);
 
4313
 
 
4314
        if (retry) {
 
4315
                /* retry failed read/write operation synchronously.
 
4316
                No need to hold array->mutex. */
 
4317
 
 
4318
#ifdef UNIV_PFS_IO
 
4319
                /* This read/write does not go through os_file_read
 
4320
                and os_file_write APIs, need to register with
 
4321
                performance schema explicitly here. */
 
4322
                struct PSI_file_locker* locker = NULL;
 
4323
                register_pfs_file_io_begin(locker, slot->file, slot->len,
 
4324
                                           (slot->type == OS_FILE_WRITE)
 
4325
                                                ? PSI_FILE_WRITE
 
4326
                                                : PSI_FILE_READ,
 
4327
                                            __FILE__, __LINE__);
 
4328
#endif
 
4329
 
 
4330
                ut_a((slot->len & 0xFFFFFFFFUL) == slot->len);
 
4331
 
 
4332
                switch (slot->type) {
 
4333
                case OS_FILE_WRITE:
 
4334
                        ret = WriteFile(slot->file, slot->buf,
 
4335
                                        (DWORD) slot->len, &len,
 
4336
                                        &(slot->control));
 
4337
 
 
4338
                        break;
 
4339
                case OS_FILE_READ:
 
4340
                        ret = ReadFile(slot->file, slot->buf,
 
4341
                                       (DWORD) slot->len, &len,
 
4342
                                       &(slot->control));
 
4343
 
 
4344
                        break;
 
4345
                default:
 
4346
                        ut_error;
 
4347
                }
 
4348
 
 
4349
#ifdef UNIV_PFS_IO
 
4350
                register_pfs_file_io_end(locker, len);
 
4351
#endif
 
4352
 
 
4353
                if (!ret && GetLastError() == ERROR_IO_PENDING) {
 
4354
                        /* aio was queued successfully!
 
4355
                        We want a synchronous i/o operation on a
 
4356
                        file where we also use async i/o: in Windows
 
4357
                        we must use the same wait mechanism as for
 
4358
                        async i/o */
 
4359
 
 
4360
                        ret = GetOverlappedResult(slot->file,
 
4361
                                                  &(slot->control),
 
4362
                                                  &len, TRUE);
 
4363
                }
 
4364
 
 
4365
                ret_val = ret && len == slot->len;
 
4366
        }
 
4367
 
 
4368
        os_aio_array_free_slot(array, slot);
 
4369
 
 
4370
        return(ret_val);
 
4371
}
 
4372
#endif
 
4373
 
 
4374
#if defined(LINUX_NATIVE_AIO)
 
4375
/******************************************************************//**
 
4376
This function is only used in Linux native asynchronous i/o. This is
 
4377
called from within the io-thread. If there are no completed IO requests
 
4378
in the slot array, the thread calls this function to collect more
 
4379
requests from the kernel.
 
4380
The io-thread waits on io_getevents(), which is a blocking call, with
 
4381
a timeout value. Unless the system is very heavy loaded, keeping the
 
4382
io-thread very busy, the io-thread will spend most of its time waiting
 
4383
in this function.
 
4384
The io-thread also exits in this function. It checks server status at
 
4385
each wakeup and that is why we use timed wait in io_getevents(). */
 
4386
static
 
4387
void
 
4388
os_aio_linux_collect(
 
4389
/*=================*/
 
4390
        os_aio_array_t* array,          /*!< in/out: slot array. */
 
4391
        ulint           segment,        /*!< in: local segment no. */
 
4392
        ulint           seg_size)       /*!< in: segment size. */
 
4393
{
 
4394
        int                     i;
 
4395
        int                     ret;
 
4396
        ulint                   start_pos;
 
4397
        ulint                   end_pos;
 
4398
        struct timespec         timeout;
 
4399
        struct io_event*        events;
 
4400
        struct io_context*      io_ctx;
 
4401
 
 
4402
        /* sanity checks. */
 
4403
        ut_ad(array != NULL);
 
4404
        ut_ad(seg_size > 0);
 
4405
        ut_ad(segment < array->n_segments);
 
4406
 
 
4407
        /* Which part of event array we are going to work on. */
 
4408
        events = &array->aio_events[segment * seg_size];
 
4409
 
 
4410
        /* Which io_context we are going to use. */
 
4411
        io_ctx = array->aio_ctx[segment];
 
4412
 
 
4413
        /* Starting point of the segment we will be working on. */
 
4414
        start_pos = segment * seg_size;
 
4415
 
 
4416
        /* End point. */
 
4417
        end_pos = start_pos + seg_size;
 
4418
 
 
4419
retry:
 
4420
 
 
4421
        /* Initialize the events. The timeout value is arbitrary.
 
4422
        We probably need to experiment with it a little. */
 
4423
        memset(events, 0, sizeof(*events) * seg_size);
 
4424
        timeout.tv_sec = 0;
 
4425
        timeout.tv_nsec = OS_AIO_REAP_TIMEOUT;
 
4426
 
 
4427
        ret = io_getevents(io_ctx, 1, seg_size, events, &timeout);
 
4428
 
 
4429
        if (ret > 0) {
 
4430
                for (i = 0; i < ret; i++) {
 
4431
                        os_aio_slot_t*  slot;
 
4432
                        struct iocb*    control;
 
4433
 
 
4434
                        control = (struct iocb *)events[i].obj;
 
4435
                        ut_a(control != NULL);
 
4436
 
 
4437
                        slot = (os_aio_slot_t *) control->data;
 
4438
 
 
4439
                        /* Some sanity checks. */
 
4440
                        ut_a(slot != NULL);
 
4441
                        ut_a(slot->reserved);
 
4442
 
 
4443
#if defined(UNIV_AIO_DEBUG)
 
4444
                        fprintf(stderr,
 
4445
                                "io_getevents[%c]: slot[%p] ctx[%p]"
 
4446
                                " seg[%lu]\n",
 
4447
                                (slot->type == OS_FILE_WRITE) ? 'w' : 'r',
 
4448
                                slot, io_ctx, segment);
 
4449
#endif
 
4450
 
 
4451
                        /* We are not scribbling previous segment. */
 
4452
                        ut_a(slot->pos >= start_pos);
 
4453
 
 
4454
                        /* We have not overstepped to next segment. */
 
4455
                        ut_a(slot->pos < end_pos);
 
4456
 
 
4457
                        /* Mark this request as completed. The error handling
 
4458
                        will be done in the calling function. */
 
4459
                        os_mutex_enter(array->mutex);
 
4460
                        slot->n_bytes = events[i].res;
 
4461
                        slot->ret = events[i].res2;
 
4462
                        slot->io_already_done = TRUE;
 
4463
                        os_mutex_exit(array->mutex);
 
4464
                }
 
4465
                return;
 
4466
        }
 
4467
 
 
4468
        if (UNIV_UNLIKELY(srv_shutdown_state == SRV_SHUTDOWN_EXIT_THREADS)) {
 
4469
                return;
 
4470
        }
 
4471
 
 
4472
        /* This error handling is for any error in collecting the
 
4473
        IO requests. The errors, if any, for any particular IO
 
4474
        request are simply passed on to the calling routine. */
 
4475
 
 
4476
        switch (ret) {
 
4477
        case -EAGAIN:
 
4478
                /* Not enough resources! Try again. */
 
4479
        case -EINTR:
 
4480
                /* Interrupted! I have tested the behaviour in case of an
 
4481
                interrupt. If we have some completed IOs available then
 
4482
                the return code will be the number of IOs. We get EINTR only
 
4483
                if there are no completed IOs and we have been interrupted. */
 
4484
        case 0:
 
4485
                /* No pending request! Go back and check again. */
 
4486
                goto retry;
 
4487
        }
 
4488
 
 
4489
        /* All other errors should cause a trap for now. */
 
4490
        ut_print_timestamp(stderr);
 
4491
        fprintf(stderr,
 
4492
                "  InnoDB: unexpected ret_code[%d] from io_getevents()!\n",
 
4493
                ret);
 
4494
        ut_error;
 
4495
}
 
4496
 
 
4497
/**********************************************************************//**
 
4498
This function is only used in Linux native asynchronous i/o.
 
4499
Waits for an aio operation to complete. This function is used to wait for
 
4500
the completed requests. The aio array of pending requests is divided
 
4501
into segments. The thread specifies which segment or slot it wants to wait
 
4502
for. NOTE: this function will also take care of freeing the aio slot,
 
4503
therefore no other thread is allowed to do the freeing!
 
4504
@return TRUE if the IO was successful */
 
4505
UNIV_INTERN
 
4506
ibool
 
4507
os_aio_linux_handle(
 
4508
/*================*/
 
4509
        ulint   global_seg,     /*!< in: segment number in the aio array
 
4510
                                to wait for; segment 0 is the ibuf
 
4511
                                i/o thread, segment 1 is log i/o thread,
 
4512
                                then follow the non-ibuf read threads,
 
4513
                                and the last are the non-ibuf write
 
4514
                                threads. */
 
4515
        fil_node_t**message1,   /*!< out: the messages passed with the */
 
4516
        void**  message2,       /*!< aio request; note that in case the
 
4517
                                aio operation failed, these output
 
4518
                                parameters are valid and can be used to
 
4519
                                restart the operation. */
 
4520
        ulint*  type)           /*!< out: OS_FILE_WRITE or ..._READ */
 
4521
{
 
4522
        ulint           segment;
 
4523
        os_aio_array_t* array;
 
4524
        os_aio_slot_t*  slot;
 
4525
        ulint           n;
 
4526
        ulint           i;
 
4527
        ibool           ret = FALSE;
 
4528
 
 
4529
        /* Should never be doing Sync IO here. */
 
4530
        ut_a(global_seg != ULINT_UNDEFINED);
 
4531
 
 
4532
        /* Find the array and the local segment. */
 
4533
        segment = os_aio_get_array_and_local_segment(&array, global_seg);
 
4534
        n = array->n_slots / array->n_segments;
 
4535
 
 
4536
        /* Loop until we have found a completed request. */
 
4537
        for (;;) {
 
4538
                ibool   any_reserved = FALSE;
 
4539
                os_mutex_enter(array->mutex);
 
4540
                for (i = 0; i < n; ++i) {
 
4541
                        slot = os_aio_array_get_nth_slot(
 
4542
                                array, i + segment * n);
 
4543
                        if (!slot->reserved) {
 
4544
                                continue;
 
4545
                        } else if (slot->io_already_done) {
 
4546
                                /* Something for us to work on. */
 
4547
                                goto found;
 
4548
                        } else {
 
4549
                                any_reserved = TRUE;
 
4550
                        }
 
4551
                }
 
4552
 
 
4553
                os_mutex_exit(array->mutex);
 
4554
 
 
4555
                /* There is no completed request.
 
4556
                If there is no pending request at all,
 
4557
                and the system is being shut down, exit. */
 
4558
                if (UNIV_UNLIKELY
 
4559
                    (!any_reserved
 
4560
                     && srv_shutdown_state == SRV_SHUTDOWN_EXIT_THREADS)) {
 
4561
                        *message1 = NULL;
 
4562
                        *message2 = NULL;
 
4563
                        return(TRUE);
 
4564
                }
 
4565
 
 
4566
                /* Wait for some request. Note that we return
 
4567
                from wait iff we have found a request. */
 
4568
 
 
4569
                srv_set_io_thread_op_info(global_seg,
 
4570
                        "waiting for completed aio requests");
 
4571
                os_aio_linux_collect(array, segment, n);
 
4572
        }
 
4573
 
 
4574
found:
 
4575
        /* Note that it may be that there are more then one completed
 
4576
        IO requests. We process them one at a time. We may have a case
 
4577
        here to improve the performance slightly by dealing with all
 
4578
        requests in one sweep. */
 
4579
        srv_set_io_thread_op_info(global_seg,
 
4580
                                "processing completed aio requests");
 
4581
 
 
4582
        /* Ensure that we are scribbling only our segment. */
 
4583
        ut_a(i < n);
 
4584
 
 
4585
        ut_ad(slot != NULL);
 
4586
        ut_ad(slot->reserved);
 
4587
        ut_ad(slot->io_already_done);
 
4588
 
 
4589
        *message1 = slot->message1;
 
4590
        *message2 = slot->message2;
 
4591
 
 
4592
        *type = slot->type;
 
4593
 
 
4594
        if ((slot->ret == 0) && (slot->n_bytes == (long)slot->len)) {
 
4595
                ret = TRUE;
 
4596
 
 
4597
#ifdef UNIV_DO_FLUSH
 
4598
                if (slot->type == OS_FILE_WRITE
 
4599
                    && !os_do_not_call_flush_at_each_write)
 
4600
                    && !os_file_flush(slot->file) {
 
4601
                        ut_error;
 
4602
                }
 
4603
#endif /* UNIV_DO_FLUSH */
 
4604
        } else {
 
4605
                errno = -slot->ret;
 
4606
 
 
4607
                /* os_file_handle_error does tell us if we should retry
 
4608
                this IO. As it stands now, we don't do this retry when
 
4609
                reaping requests from a different context than
 
4610
                the dispatcher. This non-retry logic is the same for
 
4611
                windows and linux native AIO.
 
4612
                We should probably look into this to transparently
 
4613
                re-submit the IO. */
 
4614
                os_file_handle_error(slot->name, "Linux aio");
 
4615
 
 
4616
                ret = FALSE;
 
4617
        }
 
4618
 
 
4619
        os_mutex_exit(array->mutex);
 
4620
 
 
4621
        os_aio_array_free_slot(array, slot);
 
4622
 
 
4623
        return(ret);
 
4624
}
 
4625
#endif /* LINUX_NATIVE_AIO */
 
4626
 
 
4627
/**********************************************************************//**
 
4628
Does simulated aio. This function should be called by an i/o-handler
 
4629
thread.
 
4630
@return TRUE if the aio operation succeeded */
 
4631
UNIV_INTERN
 
4632
ibool
 
4633
os_aio_simulated_handle(
 
4634
/*====================*/
 
4635
        ulint   global_segment, /*!< in: the number of the segment in the aio
 
4636
                                arrays to wait for; segment 0 is the ibuf
 
4637
                                i/o thread, segment 1 the log i/o thread,
 
4638
                                then follow the non-ibuf read threads, and as
 
4639
                                the last are the non-ibuf write threads */
 
4640
        fil_node_t**message1,   /*!< out: the messages passed with the aio
 
4641
                                request; note that also in the case where
 
4642
                                the aio operation failed, these output
 
4643
                                parameters are valid and can be used to
 
4644
                                restart the operation, for example */
 
4645
        void**  message2,
 
4646
        ulint*  type)           /*!< out: OS_FILE_WRITE or ..._READ */
 
4647
{
 
4648
        os_aio_array_t* array;
 
4649
        ulint           segment;
 
4650
        os_aio_slot_t*  slot;
 
4651
        os_aio_slot_t*  slot2;
 
4652
        os_aio_slot_t*  consecutive_ios[OS_AIO_MERGE_N_CONSECUTIVE];
 
4653
        ulint           n_consecutive;
 
4654
        ulint           total_len;
 
4655
        ulint           offs;
 
4656
        ulint           lowest_offset;
 
4657
        ulint           biggest_age;
 
4658
        ulint           age;
 
4659
        byte*           combined_buf;
 
4660
        byte*           combined_buf2;
 
4661
        ibool           ret;
 
4662
        ibool           any_reserved;
 
4663
        ulint           n;
 
4664
        ulint           i;
 
4665
 
 
4666
        /* Fix compiler warning */
 
4667
        *consecutive_ios = NULL;
 
4668
 
 
4669
        segment = os_aio_get_array_and_local_segment(&array, global_segment);
 
4670
 
 
4671
restart:
 
4672
        /* NOTE! We only access constant fields in os_aio_array. Therefore
 
4673
        we do not have to acquire the protecting mutex yet */
 
4674
 
 
4675
        srv_set_io_thread_op_info(global_segment,
 
4676
                                  "looking for i/o requests (a)");
 
4677
        ut_ad(os_aio_validate_skip());
 
4678
        ut_ad(segment < array->n_segments);
 
4679
 
 
4680
        n = array->n_slots / array->n_segments;
 
4681
 
 
4682
        /* Look through n slots after the segment * n'th slot */
 
4683
 
 
4684
        if (array == os_aio_read_array
 
4685
            && os_aio_recommend_sleep_for_read_threads) {
 
4686
 
 
4687
                /* Give other threads chance to add several i/os to the array
 
4688
                at once. */
 
4689
 
 
4690
                goto recommended_sleep;
 
4691
        }
 
4692
 
 
4693
        srv_set_io_thread_op_info(global_segment,
 
4694
                                  "looking for i/o requests (b)");
 
4695
 
 
4696
        /* Check if there is a slot for which the i/o has already been
 
4697
        done */
 
4698
        any_reserved = FALSE;
 
4699
 
 
4700
        os_mutex_enter(array->mutex);
 
4701
 
 
4702
        for (i = 0; i < n; i++) {
 
4703
                slot = os_aio_array_get_nth_slot(array, i + segment * n);
 
4704
 
 
4705
                if (!slot->reserved) {
 
4706
                        continue;
 
4707
                } else if (slot->io_already_done) {
 
4708
 
 
4709
                        if (os_aio_print_debug) {
 
4710
                                fprintf(stderr,
 
4711
                                        "InnoDB: i/o for slot %lu"
 
4712
                                        " already done, returning\n",
 
4713
                                        (ulong) i);
 
4714
                        }
 
4715
 
 
4716
                        ret = TRUE;
 
4717
 
 
4718
                        goto slot_io_done;
 
4719
                } else {
 
4720
                        any_reserved = TRUE;
 
4721
                }
 
4722
        }
 
4723
 
 
4724
        /* There is no completed request.
 
4725
        If there is no pending request at all,
 
4726
        and the system is being shut down, exit. */
 
4727
        if (UNIV_UNLIKELY
 
4728
            (!any_reserved
 
4729
             && srv_shutdown_state == SRV_SHUTDOWN_EXIT_THREADS)) {
 
4730
                os_mutex_exit(array->mutex);
 
4731
                *message1 = NULL;
 
4732
                *message2 = NULL;
 
4733
                return(TRUE);
 
4734
        }
 
4735
 
 
4736
        n_consecutive = 0;
 
4737
 
 
4738
        /* If there are at least 2 seconds old requests, then pick the oldest
 
4739
        one to prevent starvation. If several requests have the same age,
 
4740
        then pick the one at the lowest offset. */
 
4741
 
 
4742
        biggest_age = 0;
 
4743
        lowest_offset = ULINT_MAX;
 
4744
 
 
4745
        for (i = 0; i < n; i++) {
 
4746
                slot = os_aio_array_get_nth_slot(array, i + segment * n);
 
4747
 
 
4748
                if (slot->reserved) {
 
4749
                        age = (ulint)difftime(time(NULL),
 
4750
                                              slot->reservation_time);
 
4751
 
 
4752
                        if ((age >= 2 && age > biggest_age)
 
4753
                            || (age >= 2 && age == biggest_age
 
4754
                                && slot->offset < lowest_offset)) {
 
4755
 
 
4756
                                /* Found an i/o request */
 
4757
                                consecutive_ios[0] = slot;
 
4758
 
 
4759
                                n_consecutive = 1;
 
4760
 
 
4761
                                biggest_age = age;
 
4762
                                lowest_offset = slot->offset;
 
4763
                        }
 
4764
                }
 
4765
        }
 
4766
 
 
4767
        if (n_consecutive == 0) {
 
4768
                /* There were no old requests. Look for an i/o request at the
 
4769
                lowest offset in the array (we ignore the high 32 bits of the
 
4770
                offset in these heuristics) */
 
4771
 
 
4772
                lowest_offset = ULINT_MAX;
 
4773
 
 
4774
                for (i = 0; i < n; i++) {
 
4775
                        slot = os_aio_array_get_nth_slot(array,
 
4776
                                                         i + segment * n);
 
4777
 
 
4778
                        if (slot->reserved && slot->offset < lowest_offset) {
 
4779
 
 
4780
                                /* Found an i/o request */
 
4781
                                consecutive_ios[0] = slot;
 
4782
 
 
4783
                                n_consecutive = 1;
 
4784
 
 
4785
                                lowest_offset = slot->offset;
 
4786
                        }
 
4787
                }
 
4788
        }
 
4789
 
 
4790
        if (n_consecutive == 0) {
 
4791
 
 
4792
                /* No i/o requested at the moment */
 
4793
 
 
4794
                goto wait_for_io;
 
4795
        }
 
4796
 
 
4797
        /* if n_consecutive != 0, then we have assigned
 
4798
        something valid to consecutive_ios[0] */
 
4799
        ut_ad(n_consecutive != 0);
 
4800
        ut_ad(consecutive_ios[0] != NULL);
 
4801
 
 
4802
        slot = consecutive_ios[0];
 
4803
 
 
4804
        /* Check if there are several consecutive blocks to read or write */
 
4805
 
 
4806
consecutive_loop:
 
4807
        for (i = 0; i < n; i++) {
 
4808
                slot2 = os_aio_array_get_nth_slot(array, i + segment * n);
 
4809
 
 
4810
                if (slot2->reserved && slot2 != slot
 
4811
                    && slot2->offset == slot->offset + slot->len
 
4812
                    /* check that sum does not wrap over */
 
4813
                    && slot->offset + slot->len > slot->offset
 
4814
                    && slot2->offset_high == slot->offset_high
 
4815
                    && slot2->type == slot->type
 
4816
                    && slot2->file == slot->file) {
 
4817
 
 
4818
                        /* Found a consecutive i/o request */
 
4819
 
 
4820
                        consecutive_ios[n_consecutive] = slot2;
 
4821
                        n_consecutive++;
 
4822
 
 
4823
                        slot = slot2;
 
4824
 
 
4825
                        if (n_consecutive < OS_AIO_MERGE_N_CONSECUTIVE) {
 
4826
 
 
4827
                                goto consecutive_loop;
 
4828
                        } else {
 
4829
                                break;
 
4830
                        }
 
4831
                }
 
4832
        }
 
4833
 
 
4834
        srv_set_io_thread_op_info(global_segment, "consecutive i/o requests");
 
4835
 
 
4836
        /* We have now collected n_consecutive i/o requests in the array;
 
4837
        allocate a single buffer which can hold all data, and perform the
 
4838
        i/o */
 
4839
 
 
4840
        total_len = 0;
 
4841
        slot = consecutive_ios[0];
 
4842
 
 
4843
        for (i = 0; i < n_consecutive; i++) {
 
4844
                total_len += consecutive_ios[i]->len;
 
4845
        }
 
4846
 
 
4847
        if (n_consecutive == 1) {
 
4848
                /* We can use the buffer of the i/o request */
 
4849
                combined_buf = slot->buf;
 
4850
                combined_buf2 = NULL;
 
4851
        } else {
 
4852
                combined_buf2 = ut_malloc(total_len + UNIV_PAGE_SIZE);
 
4853
 
 
4854
                ut_a(combined_buf2);
 
4855
 
 
4856
                combined_buf = ut_align(combined_buf2, UNIV_PAGE_SIZE);
 
4857
        }
 
4858
 
 
4859
        /* We release the array mutex for the time of the i/o: NOTE that
 
4860
        this assumes that there is just one i/o-handler thread serving
 
4861
        a single segment of slots! */
 
4862
 
 
4863
        os_mutex_exit(array->mutex);
 
4864
 
 
4865
        if (slot->type == OS_FILE_WRITE && n_consecutive > 1) {
 
4866
                /* Copy the buffers to the combined buffer */
 
4867
                offs = 0;
 
4868
 
 
4869
                for (i = 0; i < n_consecutive; i++) {
 
4870
 
 
4871
                        ut_memcpy(combined_buf + offs, consecutive_ios[i]->buf,
 
4872
                                  consecutive_ios[i]->len);
 
4873
                        offs += consecutive_ios[i]->len;
 
4874
                }
 
4875
        }
 
4876
 
 
4877
        srv_set_io_thread_op_info(global_segment, "doing file i/o");
 
4878
 
 
4879
        if (os_aio_print_debug) {
 
4880
                fprintf(stderr,
 
4881
                        "InnoDB: doing i/o of type %lu at offset %lu %lu,"
 
4882
                        " length %lu\n",
 
4883
                        (ulong) slot->type, (ulong) slot->offset_high,
 
4884
                        (ulong) slot->offset, (ulong) total_len);
 
4885
        }
 
4886
 
 
4887
        /* Do the i/o with ordinary, synchronous i/o functions: */
 
4888
        if (slot->type == OS_FILE_WRITE) {
 
4889
                ret = os_file_write(slot->name, slot->file, combined_buf,
 
4890
                                    slot->offset, slot->offset_high,
 
4891
                                    total_len);
 
4892
        } else {
 
4893
                ret = os_file_read(slot->file, combined_buf,
 
4894
                                   slot->offset, slot->offset_high, total_len);
 
4895
        }
 
4896
 
 
4897
        ut_a(ret);
 
4898
        srv_set_io_thread_op_info(global_segment, "file i/o done");
 
4899
 
 
4900
#if 0
 
4901
        fprintf(stderr,
 
4902
                "aio: %lu consecutive %lu:th segment, first offs %lu blocks\n",
 
4903
                n_consecutive, global_segment, slot->offset / UNIV_PAGE_SIZE);
 
4904
#endif
 
4905
 
 
4906
        if (slot->type == OS_FILE_READ && n_consecutive > 1) {
 
4907
                /* Copy the combined buffer to individual buffers */
 
4908
                offs = 0;
 
4909
 
 
4910
                for (i = 0; i < n_consecutive; i++) {
 
4911
 
 
4912
                        ut_memcpy(consecutive_ios[i]->buf, combined_buf + offs,
 
4913
                                  consecutive_ios[i]->len);
 
4914
                        offs += consecutive_ios[i]->len;
 
4915
                }
 
4916
        }
 
4917
 
 
4918
        if (combined_buf2) {
 
4919
                ut_free(combined_buf2);
 
4920
        }
 
4921
 
 
4922
        os_mutex_enter(array->mutex);
 
4923
 
 
4924
        /* Mark the i/os done in slots */
 
4925
 
 
4926
        for (i = 0; i < n_consecutive; i++) {
 
4927
                consecutive_ios[i]->io_already_done = TRUE;
 
4928
        }
 
4929
 
 
4930
        /* We return the messages for the first slot now, and if there were
 
4931
        several slots, the messages will be returned with subsequent calls
 
4932
        of this function */
 
4933
 
 
4934
slot_io_done:
 
4935
 
 
4936
        ut_a(slot->reserved);
 
4937
 
 
4938
        *message1 = slot->message1;
 
4939
        *message2 = slot->message2;
 
4940
 
 
4941
        *type = slot->type;
 
4942
 
 
4943
        os_mutex_exit(array->mutex);
 
4944
 
 
4945
        os_aio_array_free_slot(array, slot);
 
4946
 
 
4947
        return(ret);
 
4948
 
 
4949
wait_for_io:
 
4950
        srv_set_io_thread_op_info(global_segment, "resetting wait event");
 
4951
 
 
4952
        /* We wait here until there again can be i/os in the segment
 
4953
        of this thread */
 
4954
 
 
4955
        os_event_reset(os_aio_segment_wait_events[global_segment]);
 
4956
 
 
4957
        os_mutex_exit(array->mutex);
 
4958
 
 
4959
recommended_sleep:
 
4960
        srv_set_io_thread_op_info(global_segment, "waiting for i/o request");
 
4961
 
 
4962
        os_event_wait(os_aio_segment_wait_events[global_segment]);
 
4963
 
 
4964
        if (os_aio_print_debug) {
 
4965
                fprintf(stderr,
 
4966
                        "InnoDB: i/o handler thread for i/o"
 
4967
                        " segment %lu wakes up\n",
 
4968
                        (ulong) global_segment);
 
4969
        }
 
4970
 
 
4971
        goto restart;
 
4972
}
 
4973
 
 
4974
/**********************************************************************//**
 
4975
Validates the consistency of an aio array.
 
4976
@return TRUE if ok */
 
4977
static
 
4978
ibool
 
4979
os_aio_array_validate(
 
4980
/*==================*/
 
4981
        os_aio_array_t* array)  /*!< in: aio wait array */
 
4982
{
 
4983
        os_aio_slot_t*  slot;
 
4984
        ulint           n_reserved      = 0;
 
4985
        ulint           i;
 
4986
 
 
4987
        ut_a(array);
 
4988
 
 
4989
        os_mutex_enter(array->mutex);
 
4990
 
 
4991
        ut_a(array->n_slots > 0);
 
4992
        ut_a(array->n_segments > 0);
 
4993
 
 
4994
        for (i = 0; i < array->n_slots; i++) {
 
4995
                slot = os_aio_array_get_nth_slot(array, i);
 
4996
 
 
4997
                if (slot->reserved) {
 
4998
                        n_reserved++;
 
4999
                        ut_a(slot->len > 0);
 
5000
                }
 
5001
        }
 
5002
 
 
5003
        ut_a(array->n_reserved == n_reserved);
 
5004
 
 
5005
        os_mutex_exit(array->mutex);
 
5006
 
 
5007
        return(TRUE);
 
5008
}
 
5009
 
 
5010
/**********************************************************************//**
 
5011
Validates the consistency the aio system.
 
5012
@return TRUE if ok */
 
5013
UNIV_INTERN
 
5014
ibool
 
5015
os_aio_validate(void)
 
5016
/*=================*/
 
5017
{
 
5018
        os_aio_array_validate(os_aio_read_array);
 
5019
        os_aio_array_validate(os_aio_write_array);
 
5020
        os_aio_array_validate(os_aio_ibuf_array);
 
5021
        os_aio_array_validate(os_aio_log_array);
 
5022
        os_aio_array_validate(os_aio_sync_array);
 
5023
 
 
5024
        return(TRUE);
 
5025
}
 
5026
 
 
5027
/**********************************************************************//**
 
5028
Prints pending IO requests per segment of an aio array.
 
5029
We probably don't need per segment statistics but they can help us
 
5030
during development phase to see if the IO requests are being
 
5031
distributed as expected. */
 
5032
static
 
5033
void
 
5034
os_aio_print_segment_info(
 
5035
/*======================*/
 
5036
        FILE*           file,   /*!< in: file where to print */
 
5037
        ulint*          n_seg,  /*!< in: pending IO array */
 
5038
        os_aio_array_t* array)  /*!< in: array to process */
 
5039
{
 
5040
        ulint   i;
 
5041
 
 
5042
        ut_ad(array);
 
5043
        ut_ad(n_seg);
 
5044
        ut_ad(array->n_segments > 0);
 
5045
 
 
5046
        if (array->n_segments == 1) {
 
5047
                return;
 
5048
        }
 
5049
 
 
5050
        fprintf(file, " [");
 
5051
        for (i = 0; i < array->n_segments; i++) {
 
5052
                if (i != 0) {
 
5053
                        fprintf(file, ", ");
 
5054
                }
 
5055
 
 
5056
                fprintf(file, "%lu", n_seg[i]);
 
5057
        }
 
5058
        fprintf(file, "] ");
 
5059
}
 
5060
 
 
5061
/**********************************************************************//**
 
5062
Prints info of the aio arrays. */
 
5063
UNIV_INTERN
 
5064
void
 
5065
os_aio_print(
 
5066
/*=========*/
 
5067
        FILE*   file)   /*!< in: file where to print */
 
5068
{
 
5069
        os_aio_array_t* array;
 
5070
        os_aio_slot_t*  slot;
 
5071
        ulint           n_reserved;
 
5072
        ulint           n_res_seg[SRV_MAX_N_IO_THREADS];
 
5073
        time_t          current_time;
 
5074
        double          time_elapsed;
 
5075
        double          avg_bytes_read;
 
5076
        ulint           i;
 
5077
 
 
5078
        for (i = 0; i < srv_n_file_io_threads; i++) {
 
5079
                fprintf(file, "I/O thread %lu state: %s (%s)", (ulong) i,
 
5080
                        srv_io_thread_op_info[i],
 
5081
                        srv_io_thread_function[i]);
 
5082
 
 
5083
#ifndef __WIN__
 
5084
                if (os_aio_segment_wait_events[i]->is_set) {
 
5085
                        fprintf(file, " ev set");
 
5086
                }
 
5087
#endif
 
5088
 
 
5089
                fprintf(file, "\n");
 
5090
        }
 
5091
 
 
5092
        fputs("Pending normal aio reads:", file);
 
5093
 
 
5094
        array = os_aio_read_array;
 
5095
loop:
 
5096
        ut_a(array);
 
5097
 
 
5098
        os_mutex_enter(array->mutex);
 
5099
 
 
5100
        ut_a(array->n_slots > 0);
 
5101
        ut_a(array->n_segments > 0);
 
5102
 
 
5103
        n_reserved = 0;
 
5104
 
 
5105
        memset(n_res_seg, 0x0, sizeof(n_res_seg));
 
5106
 
 
5107
        for (i = 0; i < array->n_slots; i++) {
 
5108
                ulint   seg_no;
 
5109
 
 
5110
                slot = os_aio_array_get_nth_slot(array, i);
 
5111
 
 
5112
                seg_no = (i * array->n_segments) / array->n_slots;
 
5113
                if (slot->reserved) {
 
5114
                        n_reserved++;
 
5115
                        n_res_seg[seg_no]++;
 
5116
#if 0
 
5117
                        fprintf(stderr, "Reserved slot, messages %p %p\n",
 
5118
                                (void*) slot->message1,
 
5119
                                (void*) slot->message2);
 
5120
#endif
 
5121
                        ut_a(slot->len > 0);
 
5122
                }
 
5123
        }
 
5124
 
 
5125
        ut_a(array->n_reserved == n_reserved);
 
5126
 
 
5127
        fprintf(file, " %lu", (ulong) n_reserved);
 
5128
 
 
5129
        os_aio_print_segment_info(file, n_res_seg, array);
 
5130
 
 
5131
        os_mutex_exit(array->mutex);
 
5132
 
 
5133
        if (array == os_aio_read_array) {
 
5134
                fputs(", aio writes:", file);
 
5135
 
 
5136
                array = os_aio_write_array;
 
5137
 
 
5138
                goto loop;
 
5139
        }
 
5140
 
 
5141
        if (array == os_aio_write_array) {
 
5142
                fputs(",\n ibuf aio reads:", file);
 
5143
                array = os_aio_ibuf_array;
 
5144
 
 
5145
                goto loop;
 
5146
        }
 
5147
 
 
5148
        if (array == os_aio_ibuf_array) {
 
5149
                fputs(", log i/o's:", file);
 
5150
                array = os_aio_log_array;
 
5151
 
 
5152
                goto loop;
 
5153
        }
 
5154
 
 
5155
        if (array == os_aio_log_array) {
 
5156
                fputs(", sync i/o's:", file);
 
5157
                array = os_aio_sync_array;
 
5158
 
 
5159
                goto loop;
 
5160
        }
 
5161
 
 
5162
        putc('\n', file);
 
5163
        current_time = time(NULL);
 
5164
        time_elapsed = 0.001 + difftime(current_time, os_last_printout);
 
5165
 
 
5166
        fprintf(file,
 
5167
                "Pending flushes (fsync) log: %lu; buffer pool: %lu\n"
 
5168
                "%lu OS file reads, %lu OS file writes, %lu OS fsyncs\n",
 
5169
                (ulong) fil_n_pending_log_flushes,
 
5170
                (ulong) fil_n_pending_tablespace_flushes,
 
5171
                (ulong) os_n_file_reads, (ulong) os_n_file_writes,
 
5172
                (ulong) os_n_fsyncs);
 
5173
 
 
5174
        if (os_file_n_pending_preads != 0 || os_file_n_pending_pwrites != 0) {
 
5175
                fprintf(file,
 
5176
                        "%lu pending preads, %lu pending pwrites\n",
 
5177
                        (ulong) os_file_n_pending_preads,
 
5178
                        (ulong) os_file_n_pending_pwrites);
 
5179
        }
 
5180
 
 
5181
        if (os_n_file_reads == os_n_file_reads_old) {
 
5182
                avg_bytes_read = 0.0;
 
5183
        } else {
 
5184
                avg_bytes_read = (double) os_bytes_read_since_printout
 
5185
                        / (os_n_file_reads - os_n_file_reads_old);
 
5186
        }
 
5187
 
 
5188
        fprintf(file,
 
5189
                "%.2f reads/s, %lu avg bytes/read,"
 
5190
                " %.2f writes/s, %.2f fsyncs/s\n",
 
5191
                (os_n_file_reads - os_n_file_reads_old)
 
5192
                / time_elapsed,
 
5193
                (ulong)avg_bytes_read,
 
5194
                (os_n_file_writes - os_n_file_writes_old)
 
5195
                / time_elapsed,
 
5196
                (os_n_fsyncs - os_n_fsyncs_old)
 
5197
                / time_elapsed);
 
5198
 
 
5199
        os_n_file_reads_old = os_n_file_reads;
 
5200
        os_n_file_writes_old = os_n_file_writes;
 
5201
        os_n_fsyncs_old = os_n_fsyncs;
 
5202
        os_bytes_read_since_printout = 0;
 
5203
 
 
5204
        os_last_printout = current_time;
 
5205
}
 
5206
 
 
5207
/**********************************************************************//**
 
5208
Refreshes the statistics used to print per-second averages. */
 
5209
UNIV_INTERN
 
5210
void
 
5211
os_aio_refresh_stats(void)
 
5212
/*======================*/
 
5213
{
 
5214
        os_n_file_reads_old = os_n_file_reads;
 
5215
        os_n_file_writes_old = os_n_file_writes;
 
5216
        os_n_fsyncs_old = os_n_fsyncs;
 
5217
        os_bytes_read_since_printout = 0;
 
5218
 
 
5219
        os_last_printout = time(NULL);
 
5220
}
 
5221
 
 
5222
#ifdef UNIV_DEBUG
 
5223
/**********************************************************************//**
 
5224
Checks that all slots in the system have been freed, that is, there are
 
5225
no pending io operations.
 
5226
@return TRUE if all free */
 
5227
UNIV_INTERN
 
5228
ibool
 
5229
os_aio_all_slots_free(void)
 
5230
/*=======================*/
 
5231
{
 
5232
        os_aio_array_t* array;
 
5233
        ulint           n_res   = 0;
 
5234
 
 
5235
        array = os_aio_read_array;
 
5236
 
 
5237
        os_mutex_enter(array->mutex);
 
5238
 
 
5239
        n_res += array->n_reserved;
 
5240
 
 
5241
        os_mutex_exit(array->mutex);
 
5242
 
 
5243
        array = os_aio_write_array;
 
5244
 
 
5245
        os_mutex_enter(array->mutex);
 
5246
 
 
5247
        n_res += array->n_reserved;
 
5248
 
 
5249
        os_mutex_exit(array->mutex);
 
5250
 
 
5251
        array = os_aio_ibuf_array;
 
5252
 
 
5253
        os_mutex_enter(array->mutex);
 
5254
 
 
5255
        n_res += array->n_reserved;
 
5256
 
 
5257
        os_mutex_exit(array->mutex);
 
5258
 
 
5259
        array = os_aio_log_array;
 
5260
 
 
5261
        os_mutex_enter(array->mutex);
 
5262
 
 
5263
        n_res += array->n_reserved;
 
5264
 
 
5265
        os_mutex_exit(array->mutex);
 
5266
 
 
5267
        array = os_aio_sync_array;
 
5268
 
 
5269
        os_mutex_enter(array->mutex);
 
5270
 
 
5271
        n_res += array->n_reserved;
 
5272
 
 
5273
        os_mutex_exit(array->mutex);
 
5274
 
 
5275
        if (n_res == 0) {
 
5276
 
 
5277
                return(TRUE);
 
5278
        }
 
5279
 
 
5280
        return(FALSE);
 
5281
}
 
5282
#endif /* UNIV_DEBUG */
 
5283
 
 
5284
#endif /* !UNIV_HOTBACKUP */