~drizzle-trunk/drizzle/development

« back to all changes in this revision

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

  • Committer: Jay Pipes
  • Date: 2009-01-30 04:38:21 UTC
  • mto: This revision was merged to the branch mainline in revision 830.
  • Revision ID: jpipes@serialcoder-20090130043821-4d7jg2ftabefamxb
Fixes for the QUARTER() function to use new Temporal system and throw
errors on bad datetime values.

Added test case for QUARTER() function and modified func_time.test existing
test to correctly throw errors and report NULL, not 0 on NULL input.

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 under
14
 
the terms of the GNU General Public License as published by the Free Software
15
 
Foundation; version 2 of the License.
16
 
 
17
 
This program is distributed in the hope that it will be useful, but WITHOUT
18
 
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
19
 
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
20
 
 
21
 
You should have received a copy of the GNU General Public License along with
22
 
this program; if not, write to the Free Software Foundation, Inc., 51 Franklin
23
 
St, Fifth Floor, Boston, MA 02110-1301 USA
24
 
 
25
 
*****************************************************************************/
26
 
 
27
 
/**************************************************//**
28
 
@file os/os0file.c
 
1
/******************************************************
29
2
The interface to the operating system file i/o primitives
30
3
 
 
4
(c) 1995 Innobase Oy
 
5
 
31
6
Created 10/21/1995 Heikki Tuuri
32
7
*******************************************************/
33
8
 
34
9
#include "os0file.h"
35
 
 
36
 
#ifdef UNIV_NONINL
37
 
#include "os0file.ic"
38
 
#endif
39
 
 
 
10
#include "os0sync.h"
 
11
#include "os0thread.h"
40
12
#include "ut0mem.h"
41
13
#include "srv0srv.h"
42
14
#include "srv0start.h"
43
15
#include "fil0fil.h"
44
16
#include "buf0buf.h"
 
17
 
 
18
#if defined(UNIV_HOTBACKUP) && defined(__WIN__)
 
19
/* Add includes for the _stat() call to compile on Windows */
 
20
#include <sys/types.h>
 
21
#include <sys/stat.h>
45
22
#include <errno.h>
46
 
#include <fcntl.h>
47
 
#include <limits.h>
48
 
#include <unistd.h>
49
 
#ifndef UNIV_HOTBACKUP
50
 
# include "os0sync.h"
51
 
# include "os0thread.h"
52
 
#else /* !UNIV_HOTBACKUP */
53
 
# ifdef __WIN__
54
 
/* Add includes for the _stat() call to compile on Windows */
55
 
#  include <sys/types.h>
56
 
#  include <sys/stat.h>
57
 
# endif /* __WIN__ */
58
 
#endif /* !UNIV_HOTBACKUP */
59
 
 
60
 
#if defined(LINUX_NATIVE_AIO)
61
 
#include <libaio.h>
62
 
#endif
 
23
#endif /* UNIV_HOTBACKUP */
63
24
 
64
25
/* This specifies the file permissions InnoDB uses when it creates files in
65
26
Unix; the value of os_innodb_umask is initialized in ha_innodb.cc to
66
27
my_umask */
67
28
 
68
29
#ifndef __WIN__
69
 
/** Umask for creating files */
70
30
UNIV_INTERN ulint       os_innodb_umask
71
31
                        = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP;
72
32
#else
73
 
/** Umask for creating files */
74
33
UNIV_INTERN ulint       os_innodb_umask         = 0;
75
34
#endif
76
35
 
82
41
/* We do not call os_file_flush in every os_file_write. */
83
42
#endif /* UNIV_DO_FLUSH */
84
43
 
85
 
#ifndef UNIV_HOTBACKUP
86
44
/* We use these mutexes to protect lseek + file i/o operation, if the
87
45
OS does not provide an atomic pread or pwrite, or similar */
88
46
#define OS_FILE_N_SEEK_MUTEXES  16
91
49
/* In simulated aio, merge at most this many consecutive i/os */
92
50
#define OS_AIO_MERGE_N_CONSECUTIVE      64
93
51
 
94
 
/**********************************************************************
95
 
 
96
 
InnoDB AIO Implementation:
97
 
=========================
98
 
 
99
 
We support native AIO for windows and linux. For rest of the platforms
100
 
we simulate AIO by special io-threads servicing the IO-requests.
101
 
 
102
 
Simulated AIO:
103
 
==============
104
 
 
105
 
In platforms where we 'simulate' AIO following is a rough explanation
106
 
of the high level design.
107
 
There are four io-threads (for ibuf, log, read, write).
108
 
All synchronous IO requests are serviced by the calling thread using
109
 
os_file_write/os_file_read. The Asynchronous requests are queued up
110
 
in an array (there are four such arrays) by the calling thread. 
111
 
Later these requests are picked up by the io-thread and are serviced
112
 
synchronously.
113
 
 
114
 
Windows native AIO:
115
 
==================
116
 
 
117
 
If srv_use_native_aio is not set then windows follow the same
118
 
code as simulated AIO. If the flag is set then native AIO interface
119
 
is used. On windows, one of the limitation is that if a file is opened
120
 
for AIO no synchronous IO can be done on it. Therefore we have an
121
 
extra fifth array to queue up synchronous IO requests.
122
 
There are innodb_file_io_threads helper threads. These threads work
123
 
on the four arrays mentioned above in Simulated AIO. No thread is
124
 
required for the sync array.
125
 
If a synchronous IO request is made, it is first queued in the sync
126
 
array. Then the calling thread itself waits on the request, thus
127
 
making the call synchronous.
128
 
If an AIO request is made the calling thread not only queues it in the
129
 
array but also submits the requests. The helper thread then collects
130
 
the completed IO request and calls completion routine on it.
131
 
 
132
 
Linux native AIO:
133
 
=================
134
 
 
135
 
If we have libaio installed on the system and innodb_use_native_aio
136
 
is set to TRUE we follow the code path of native AIO, otherwise we
137
 
do simulated AIO.
138
 
There are innodb_file_io_threads helper threads. These threads work
139
 
on the four arrays mentioned above in Simulated AIO.
140
 
If a synchronous IO request is made, it is handled by calling
141
 
os_file_write/os_file_read.
142
 
If an AIO request is made the calling thread not only queues it in the
143
 
array but also submits the requests. The helper thread then collects
144
 
the completed IO request and calls completion routine on it.
145
 
 
146
 
**********************************************************************/
147
 
 
148
 
/** Flag: enable debug printout for asynchronous i/o */
 
52
/* If this flag is TRUE, then we will use the native aio of the
 
53
OS (provided we compiled Innobase with it in), otherwise we will
 
54
use simulated aio we build below with threads */
 
55
 
 
56
UNIV_INTERN ibool       os_aio_use_native_aio   = FALSE;
 
57
 
149
58
UNIV_INTERN ibool       os_aio_print_debug      = FALSE;
150
59
 
151
 
#ifdef UNIV_PFS_IO
152
 
/* Keys to register InnoDB I/O with performance schema */
153
 
UNIV_INTERN mysql_pfs_key_t  innodb_file_data_key;
154
 
UNIV_INTERN mysql_pfs_key_t  innodb_file_log_key;
155
 
UNIV_INTERN mysql_pfs_key_t  innodb_file_temp_key;
156
 
#endif /* UNIV_PFS_IO */
157
 
 
158
 
/** The asynchronous i/o array slot structure */
 
60
/* The aio array slot structure */
159
61
typedef struct os_aio_slot_struct       os_aio_slot_t;
160
62
 
161
 
/** The asynchronous i/o array slot structure */
162
63
struct os_aio_slot_struct{
163
 
        ibool           is_read;        /*!< TRUE if a read operation */
164
 
        ulint           pos;            /*!< index of the slot in the aio
 
64
        ibool           is_read;        /* TRUE if a read operation */
 
65
        ulint           pos;            /* index of the slot in the aio
165
66
                                        array */
166
 
        ibool           reserved;       /*!< TRUE if this slot is reserved */
167
 
        time_t          reservation_time;/*!< time when reserved */
168
 
        ulint           len;            /*!< length of the block to read or
 
67
        ibool           reserved;       /* TRUE if this slot is reserved */
 
68
        time_t          reservation_time;/* time when reserved */
 
69
        ulint           len;            /* length of the block to read or
169
70
                                        write */
170
 
        byte*           buf;            /*!< buffer used in i/o */
171
 
        ulint           type;           /*!< OS_FILE_READ or OS_FILE_WRITE */
172
 
        ulint           offset;         /*!< 32 low bits of file offset in
 
71
        byte*           buf;            /* buffer used in i/o */
 
72
        ulint           type;           /* OS_FILE_READ or OS_FILE_WRITE */
 
73
        ulint           offset;         /* 32 low bits of file offset in
173
74
                                        bytes */
174
 
        ulint           offset_high;    /*!< 32 high bits of file offset */
175
 
        os_file_t       file;           /*!< file where to read or write */
176
 
        const char*     name;           /*!< file name or path */
177
 
        ibool           io_already_done;/*!< used only in simulated aio:
 
75
        ulint           offset_high;    /* 32 high bits of file offset */
 
76
        os_file_t       file;           /* file where to read or write */
 
77
        const char*     name;           /* file name or path */
 
78
        ibool           io_already_done;/* used only in simulated aio:
178
79
                                        TRUE if the physical i/o already
179
80
                                        made and only the slot message
180
81
                                        needs to be passed to the caller
181
82
                                        of os_aio_simulated_handle */
182
 
        fil_node_t*     message1;       /*!< message which is given by the */
183
 
        void*           message2;       /*!< the requester of an aio operation
 
83
        fil_node_t*     message1;       /* message which is given by the */
 
84
        void*           message2;       /* the requester of an aio operation
184
85
                                        and which can be used to identify
185
86
                                        which pending aio operation was
186
87
                                        completed */
187
88
#ifdef WIN_ASYNC_IO
188
 
        HANDLE          handle;         /*!< handle object we need in the
 
89
        os_event_t      event;          /* event object we need in the
189
90
                                        OVERLAPPED struct */
190
 
        OVERLAPPED      control;        /*!< Windows control block for the
 
91
        OVERLAPPED      control;        /* Windows control block for the
191
92
                                        aio request */
192
 
#elif defined(LINUX_NATIVE_AIO)
193
 
        struct iocb     control;        /* Linux control block for aio */
194
 
        int             n_bytes;        /* bytes written/read. */
195
 
        int             ret;            /* AIO return code */
196
93
#endif
197
94
};
198
95
 
199
 
/** The asynchronous i/o array structure */
 
96
/* The aio array structure */
200
97
typedef struct os_aio_array_struct      os_aio_array_t;
201
98
 
202
 
/** The asynchronous i/o array structure */
203
99
struct os_aio_array_struct{
204
 
        os_mutex_t      mutex;  /*!< the mutex protecting the aio array */
205
 
        os_event_t      not_full;
206
 
                                /*!< The event which is set to the
207
 
                                signaled state when there is space in
208
 
                                the aio outside the ibuf segment */
209
 
        os_event_t      is_empty;
210
 
                                /*!< The event which is set to the
211
 
                                signaled state when there are no
212
 
                                pending i/os in this array */
213
 
        ulint           n_slots;/*!< Total number of slots in the aio
214
 
                                array.  This must be divisible by
215
 
                                n_threads. */
216
 
        ulint           n_segments;
217
 
                                /*!< Number of segments in the aio
218
 
                                array of pending aio requests. A
219
 
                                thread can wait separately for any one
220
 
                                of the segments. */
221
 
        ulint           cur_seg;/*!< We reserve IO requests in round
222
 
                                robin fashion to different segments.
223
 
                                This points to the segment that is to
224
 
                                be used to service next IO request. */
225
 
        ulint           n_reserved;
226
 
                                /*!< Number of reserved slots in the
227
 
                                aio array outside the ibuf segment */
228
 
        os_aio_slot_t*  slots;  /*!< Pointer to the slots in the array */
 
100
        os_mutex_t      mutex;    /* the mutex protecting the aio array */
 
101
        os_event_t      not_full; /* The event which is set to the signaled
 
102
                                  state when there is space in the aio
 
103
                                  outside the ibuf segment */
 
104
        os_event_t      is_empty; /* The event which is set to the signaled
 
105
                                  state when there are no pending i/os
 
106
                                  in this array */
 
107
        ulint           n_slots;  /* Total number of slots in the aio array.
 
108
                                  This must be divisible by n_threads. */
 
109
        ulint           n_segments;/* Number of segments in the aio array of
 
110
                                  pending aio requests. A thread can wait
 
111
                                  separately for any one of the segments. */
 
112
        ulint           n_reserved;/* Number of reserved slots in the
 
113
                                  aio array outside the ibuf segment */
 
114
        os_aio_slot_t*  slots;    /* Pointer to the slots in the array */
229
115
#ifdef __WIN__
230
 
        HANDLE*         handles;
231
 
                                /*!< Pointer to an array of OS native
232
 
                                event handles where we copied the
233
 
                                handles from slots, in the same
234
 
                                order. This can be used in
235
 
                                WaitForMultipleObjects; used only in
236
 
                                Windows */
237
 
#endif
238
 
 
239
 
#if defined(LINUX_NATIVE_AIO)
240
 
        io_context_t*           aio_ctx;
241
 
                                /* completion queue for IO. There is 
242
 
                                one such queue per segment. Each thread
243
 
                                will work on one ctx exclusively. */
244
 
        struct io_event*        aio_events;
245
 
                                /* The array to collect completed IOs.
246
 
                                There is one such event for each
247
 
                                possible pending IO. The size of the
248
 
                                array is equal to n_slots. */
 
116
        os_native_event_t* native_events;
 
117
                                  /* Pointer to an array of OS native event
 
118
                                  handles where we copied the handles from
 
119
                                  slots, in the same order. This can be used
 
120
                                  in WaitForMultipleObjects; used only in
 
121
                                  Windows */
249
122
#endif
250
123
};
251
124
 
252
 
#if defined(LINUX_NATIVE_AIO)
253
 
/** timeout for each io_getevents() call = 500ms. */
254
 
#define OS_AIO_REAP_TIMEOUT     (500000000UL)
255
 
 
256
 
/** time to sleep, in microseconds if io_setup() returns EAGAIN. */
257
 
#define OS_AIO_IO_SETUP_RETRY_SLEEP     (500000UL)
258
 
 
259
 
/** number of attempts before giving up on io_setup(). */
260
 
#define OS_AIO_IO_SETUP_RETRY_ATTEMPTS  5
261
 
#endif
262
 
 
263
 
/** Array of events used in simulated aio */
 
125
/* Array of events used in simulated aio */
264
126
static os_event_t*      os_aio_segment_wait_events      = NULL;
265
127
 
266
 
/** The aio arrays for non-ibuf i/o and ibuf i/o, as well as sync aio. These
267
 
are NULL when the module has not yet been initialized. @{ */
268
 
static os_aio_array_t*  os_aio_read_array       = NULL; /*!< Reads */
269
 
static os_aio_array_t*  os_aio_write_array      = NULL; /*!< Writes */
270
 
static os_aio_array_t*  os_aio_ibuf_array       = NULL; /*!< Insert buffer */
271
 
static os_aio_array_t*  os_aio_log_array        = NULL; /*!< Redo log */
272
 
static os_aio_array_t*  os_aio_sync_array       = NULL; /*!< Synchronous I/O */
273
 
/* @} */
 
128
/* The aio arrays for non-ibuf i/o and ibuf i/o, as well as sync aio. These
 
129
are NULL when the module has not yet been initialized. */
 
130
static os_aio_array_t*  os_aio_read_array       = NULL;
 
131
static os_aio_array_t*  os_aio_write_array      = NULL;
 
132
static os_aio_array_t*  os_aio_ibuf_array       = NULL;
 
133
static os_aio_array_t*  os_aio_log_array        = NULL;
 
134
static os_aio_array_t*  os_aio_sync_array       = NULL;
274
135
 
275
 
/** Number of asynchronous I/O segments.  Set by os_aio_init(). */
276
136
static ulint    os_aio_n_segments       = ULINT_UNDEFINED;
277
137
 
278
 
/** If the following is TRUE, read i/o handler threads try to
 
138
/* If the following is TRUE, read i/o handler threads try to
279
139
wait until a batch of new read requests have been posted */
280
140
static ibool    os_aio_recommend_sleep_for_read_threads = FALSE;
281
 
#endif /* !UNIV_HOTBACKUP */
282
141
 
283
142
UNIV_INTERN ulint       os_n_file_reads         = 0;
284
143
UNIV_INTERN ulint       os_bytes_read_since_printout = 0;
291
150
 
292
151
UNIV_INTERN ibool       os_has_said_disk_full   = FALSE;
293
152
 
294
 
#ifndef UNIV_HOTBACKUP
295
 
/** The mutex protecting the following counts of pending I/O operations */
 
153
/* The mutex protecting the following counts of pending I/O operations */
296
154
static os_mutex_t       os_file_count_mutex;
297
 
#endif /* !UNIV_HOTBACKUP */
298
 
/** Number of pending os_file_pread() operations */
299
155
UNIV_INTERN ulint       os_file_n_pending_preads  = 0;
300
 
/** Number of pending os_file_pwrite() operations */
301
156
UNIV_INTERN ulint       os_file_n_pending_pwrites = 0;
302
 
/** Number of pending write operations */
303
157
UNIV_INTERN ulint       os_n_pending_writes = 0;
304
 
/** Number of pending read operations */
305
158
UNIV_INTERN ulint       os_n_pending_reads = 0;
306
159
 
307
 
/***********************************************************************//**
308
 
Gets the operating system version. Currently works only on Windows.
309
 
@return OS_WIN95, OS_WIN31, OS_WINNT, OS_WIN2000, OS_WINXP, OS_WINVISTA,
310
 
OS_WIN7. */
 
160
/***************************************************************************
 
161
Gets the operating system version. Currently works only on Windows. */
311
162
UNIV_INTERN
312
163
ulint
313
164
os_get_os_version(void)
314
165
/*===================*/
 
166
                  /* out: OS_WIN95, OS_WIN31, OS_WINNT, OS_WIN2000 */
315
167
{
316
168
#ifdef __WIN__
317
169
        OSVERSIONINFO     os_info;
325
177
        } else if (os_info.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS) {
326
178
                return(OS_WIN95);
327
179
        } else if (os_info.dwPlatformId == VER_PLATFORM_WIN32_NT) {
328
 
                switch (os_info.dwMajorVersion) {
329
 
                case 3:
330
 
                case 4:
331
 
                        return OS_WINNT;
332
 
                case 5:
333
 
                        return (os_info.dwMinorVersion == 0) ? OS_WIN2000
334
 
                                                             : OS_WINXP;
335
 
                case 6:
336
 
                        return (os_info.dwMinorVersion == 0) ? OS_WINVISTA
337
 
                                                             : OS_WIN7;
338
 
                default:
339
 
                        return OS_WIN7;
 
180
                if (os_info.dwMajorVersion <= 4) {
 
181
                        return(OS_WINNT);
 
182
                } else {
 
183
                        return(OS_WIN2000);
340
184
                }
341
185
        } else {
342
186
                ut_error;
349
193
#endif
350
194
}
351
195
 
352
 
/***********************************************************************//**
 
196
/***************************************************************************
353
197
Retrieves the last error number if an error occurs in a file io function.
354
198
The number should be retrieved before any other OS calls (because they may
355
199
overwrite the error number). If the number is not known to this program,
356
 
the OS error number + 100 is returned.
357
 
@return error number, or OS error number + 100 */
 
200
the OS error number + 100 is returned. */
358
201
UNIV_INTERN
359
202
ulint
360
203
os_file_get_last_error(
361
204
/*===================*/
362
 
        ibool   report_all_errors)      /*!< in: TRUE if we want an error message
 
205
                                        /* out: error number, or OS error
 
206
                                        number + 100 */
 
207
        ibool   report_all_errors)      /* in: TRUE if we want an error message
363
208
                                        printed of all errors */
364
209
{
365
210
        ulint   err;
404
249
                                " software or another instance\n"
405
250
                                "InnoDB: of MySQL."
406
251
                                " Please close it to get rid of this error.\n");
407
 
                } else if (err == ERROR_WORKING_SET_QUOTA
408
 
                           || err == ERROR_NO_SYSTEM_RESOURCES) {
409
 
                        fprintf(stderr,
410
 
                                "InnoDB: The error means that there are no"
411
 
                                " sufficient system resources or quota to"
412
 
                                " complete the operation.\n");
413
 
                } else if (err == ERROR_OPERATION_ABORTED) {
414
 
                        fprintf(stderr,
415
 
                                "InnoDB: The error means that the I/O"
416
 
                                " operation has been aborted\n"
417
 
                                "InnoDB: because of either a thread exit"
418
 
                                " or an application request.\n"
419
 
                                "InnoDB: Retry attempt is made.\n");
420
252
                } else {
421
253
                        fprintf(stderr,
422
254
                                "InnoDB: Some operating system error numbers"
423
255
                                " are described at\n"
424
256
                                "InnoDB: "
425
 
                                REFMAN
 
257
                                "http://dev.mysql.com/doc/refman/5.1/en/"
426
258
                                "operating-system-error-codes.html\n");
427
259
                }
428
260
        }
438
270
        } else if (err == ERROR_SHARING_VIOLATION
439
271
                   || err == ERROR_LOCK_VIOLATION) {
440
272
                return(OS_FILE_SHARING_VIOLATION);
441
 
        } else if (err == ERROR_WORKING_SET_QUOTA
442
 
                   || err == ERROR_NO_SYSTEM_RESOURCES) {
443
 
                return(OS_FILE_INSUFFICIENT_RESOURCE);
444
 
        } else if (err == ERROR_OPERATION_ABORTED) {
445
 
                return(OS_FILE_OPERATION_ABORTED);
446
273
        } else {
447
274
                return(100 + err);
448
275
        }
486
313
                                "InnoDB: Some operating system"
487
314
                                " error numbers are described at\n"
488
315
                                "InnoDB: "
489
 
                                REFMAN
 
316
                                "http://dev.mysql.com/doc/refman/5.1/en/"
490
317
                                "operating-system-error-codes.html\n");
491
318
                }
492
319
        }
493
320
 
494
321
        fflush(stderr);
495
322
 
496
 
        switch (err) {
497
 
        case ENOSPC:
 
323
        if (err == ENOSPC) {
498
324
                return(OS_FILE_DISK_FULL);
499
 
        case ENOENT:
 
325
        } else if (err == ENOENT) {
500
326
                return(OS_FILE_NOT_FOUND);
501
 
        case EEXIST:
 
327
        } else if (err == EEXIST) {
502
328
                return(OS_FILE_ALREADY_EXISTS);
503
 
        case EXDEV:
504
 
        case ENOTDIR:
505
 
        case EISDIR:
 
329
        } else if (err == EXDEV || err == ENOTDIR || err == EISDIR) {
506
330
                return(OS_FILE_PATH_ERROR);
507
 
        case EAGAIN:
508
 
                if (srv_use_native_aio) {
509
 
                        return(OS_FILE_AIO_RESOURCES_RESERVED);
510
 
                }
511
 
                break;
512
 
        case EINTR:
513
 
                if (srv_use_native_aio) {
514
 
                        return(OS_FILE_AIO_INTERRUPTED);
515
 
                }
516
 
                break;
 
331
        } else {
 
332
                return(100 + err);
517
333
        }
518
 
        return(100 + err);
519
334
#endif
520
335
}
521
336
 
522
 
/****************************************************************//**
 
337
/********************************************************************
523
338
Does error handling when a file operation fails.
524
339
Conditionally exits (calling exit(3)) based on should_exit value and the
525
 
error type
526
 
@return TRUE if we should retry the operation */
 
340
error type */
527
341
static
528
342
ibool
529
343
os_file_handle_error_cond_exit(
530
344
/*===========================*/
531
 
        const char*     name,           /*!< in: name of a file or NULL */
532
 
        const char*     operation,      /*!< in: operation */
533
 
        ibool           should_exit)    /*!< in: call exit(3) if unknown error
 
345
                                        /* out: TRUE if we should retry the
 
346
                                        operation */
 
347
        const char*     name,           /* in: name of a file or NULL */
 
348
        const char*     operation,      /* in: operation */
 
349
        ibool           should_exit)    /* in: call exit(3) if unknown error
534
350
                                        and this parameter is TRUE */
535
351
{
536
352
        ulint   err;
565
381
        } else if (err == OS_FILE_AIO_RESOURCES_RESERVED) {
566
382
 
567
383
                return(TRUE);
568
 
        } else if (err == OS_FILE_AIO_INTERRUPTED) {
569
 
 
570
 
                return(TRUE);
571
384
        } else if (err == OS_FILE_ALREADY_EXISTS
572
385
                   || err == OS_FILE_PATH_ERROR) {
573
386
 
576
389
 
577
390
                os_thread_sleep(10000000);  /* 10 sec */
578
391
                return(TRUE);
579
 
        } else if (err == OS_FILE_INSUFFICIENT_RESOURCE) {
580
 
 
581
 
                os_thread_sleep(100000);        /* 100 ms */
582
 
                return(TRUE);
583
 
        } else if (err == OS_FILE_OPERATION_ABORTED) {
584
 
 
585
 
                os_thread_sleep(100000);        /* 100 ms */
586
 
                return(TRUE);
587
392
        } else {
588
393
                if (name) {
589
394
                        fprintf(stderr, "InnoDB: File name %s\n", name);
604
409
        return(FALSE);
605
410
}
606
411
 
607
 
/****************************************************************//**
608
 
Does error handling when a file operation fails.
609
 
@return TRUE if we should retry the operation */
 
412
/********************************************************************
 
413
Does error handling when a file operation fails. */
610
414
static
611
415
ibool
612
416
os_file_handle_error(
613
417
/*=================*/
614
 
        const char*     name,   /*!< in: name of a file or NULL */
615
 
        const char*     operation)/*!< in: operation */
 
418
                                /* out: TRUE if we should retry the
 
419
                                operation */
 
420
        const char*     name,   /* in: name of a file or NULL */
 
421
        const char*     operation)/* in: operation */
616
422
{
617
423
        /* exit in case of unknown error */
618
424
        return(os_file_handle_error_cond_exit(name, operation, TRUE));
619
425
}
620
426
 
621
 
/****************************************************************//**
622
 
Does error handling when a file operation fails.
623
 
@return TRUE if we should retry the operation */
 
427
/********************************************************************
 
428
Does error handling when a file operation fails. */
624
429
static
625
430
ibool
626
431
os_file_handle_error_no_exit(
627
432
/*=========================*/
628
 
        const char*     name,   /*!< in: name of a file or NULL */
629
 
        const char*     operation)/*!< in: operation */
 
433
                                /* out: TRUE if we should retry the
 
434
                                operation */
 
435
        const char*     name,   /* in: name of a file or NULL */
 
436
        const char*     operation)/* in: operation */
630
437
{
631
438
        /* don't exit in case of unknown error */
632
439
        return(os_file_handle_error_cond_exit(name, operation, FALSE));
634
441
 
635
442
#undef USE_FILE_LOCK
636
443
#define USE_FILE_LOCK
637
 
#if defined(UNIV_HOTBACKUP) || defined(__WIN__)
 
444
#if defined(UNIV_HOTBACKUP) || defined(__WIN__) || defined(__NETWARE__)
638
445
/* InnoDB Hot Backup does not lock the data files.
639
446
 * On Windows, mandatory locking is used.
640
447
 */
641
448
# undef USE_FILE_LOCK
642
449
#endif
643
450
#ifdef USE_FILE_LOCK
644
 
/****************************************************************//**
645
 
Obtain an exclusive lock on a file.
646
 
@return 0 on success */
 
451
/********************************************************************
 
452
Obtain an exclusive lock on a file. */
647
453
static
648
454
int
649
455
os_file_lock(
650
456
/*=========*/
651
 
        int             fd,     /*!< in: file descriptor */
652
 
        const char*     name)   /*!< in: file name */
 
457
                                /* out: 0 on success */
 
458
        int             fd,     /* in: file descriptor */
 
459
        const char*     name)   /* in: file name */
653
460
{
654
461
        struct flock lk;
655
462
        lk.l_type = F_WRLCK;
674
481
}
675
482
#endif /* USE_FILE_LOCK */
676
483
 
677
 
#ifndef UNIV_HOTBACKUP
678
 
/****************************************************************//**
 
484
/********************************************************************
679
485
Creates the seek mutexes used in positioned reads and writes. */
680
486
UNIV_INTERN
681
487
void
684
490
{
685
491
        ulint   i;
686
492
 
687
 
        os_file_count_mutex = os_mutex_create();
 
493
        os_file_count_mutex = os_mutex_create(NULL);
688
494
 
689
495
        for (i = 0; i < OS_FILE_N_SEEK_MUTEXES; i++) {
690
 
                os_file_seek_mutexes[i] = os_mutex_create();
 
496
                os_file_seek_mutexes[i] = os_mutex_create(NULL);
691
497
        }
692
498
}
693
499
 
694
 
/***********************************************************************//**
 
500
/***************************************************************************
695
501
Creates a temporary file.  This function is like tmpfile(3), but
696
502
the temporary file is created in the MySQL temporary directory.
697
 
@return temporary file handle, or NULL on error */
 
503
On Netware, this function is like tmpfile(3), because the C run-time
 
504
library of Netware does not expose the delete-on-close flag. */
698
505
UNIV_INTERN
699
506
FILE*
700
507
os_file_create_tmpfile(void)
701
508
/*========================*/
 
509
                        /* out: temporary file handle, or NULL on error */
702
510
{
 
511
#ifdef UNIV_HOTBACKUP
 
512
        ut_error;
 
513
 
 
514
        return(NULL);
 
515
#else
 
516
# ifdef __NETWARE__
 
517
        FILE*   file    = tmpfile();
 
518
# else /* __NETWARE__ */
703
519
        FILE*   file    = NULL;
704
520
        int     fd      = innobase_mysql_tmpfile();
705
521
 
706
522
        if (fd >= 0) {
707
523
                file = fdopen(fd, "w+b");
708
524
        }
 
525
# endif /* __NETWARE__ */
709
526
 
710
527
        if (!file) {
711
528
                ut_print_timestamp(stderr);
712
529
                fprintf(stderr,
713
530
                        "  InnoDB: Error: unable to create temporary file;"
714
531
                        " errno: %d\n", errno);
 
532
# ifndef __NETWARE__
715
533
                if (fd >= 0) {
716
534
                        close(fd);
717
535
                }
 
536
# endif /* !__NETWARE__ */
718
537
        }
719
538
 
720
539
        return(file);
 
540
#endif /* UNIV_HOTBACKUP */
721
541
}
722
 
#endif /* !UNIV_HOTBACKUP */
723
542
 
724
 
/***********************************************************************//**
 
543
/***************************************************************************
725
544
The os_file_opendir() function opens a directory stream corresponding to the
726
545
directory named by the dirname argument. The directory stream is positioned
727
546
at the first entry. In both Unix and Windows we automatically skip the '.'
728
 
and '..' items at the start of the directory listing.
729
 
@return directory stream, NULL if error */
 
547
and '..' items at the start of the directory listing. */
730
548
UNIV_INTERN
731
549
os_file_dir_t
732
550
os_file_opendir(
733
551
/*============*/
734
 
        const char*     dirname,        /*!< in: directory name; it must not
 
552
                                        /* out: directory stream, NULL if
 
553
                                        error */
 
554
        const char*     dirname,        /* in: directory name; it must not
735
555
                                        contain a trailing '\' or '/' */
736
 
        ibool           error_is_fatal) /*!< in: TRUE if we should treat an
 
556
        ibool           error_is_fatal) /* in: TRUE if we should treat an
737
557
                                        error as a fatal error; if we try to
738
558
                                        open symlinks then we do not wish a
739
559
                                        fatal error if it happens not to be
780
600
#endif
781
601
}
782
602
 
783
 
/***********************************************************************//**
784
 
Closes a directory stream.
785
 
@return 0 if success, -1 if failure */
 
603
/***************************************************************************
 
604
Closes a directory stream. */
786
605
UNIV_INTERN
787
606
int
788
607
os_file_closedir(
789
608
/*=============*/
790
 
        os_file_dir_t   dir)    /*!< in: directory stream */
 
609
                                /* out: 0 if success, -1 if failure */
 
610
        os_file_dir_t   dir)    /* in: directory stream */
791
611
{
792
612
#ifdef __WIN__
793
613
        BOOL            ret;
814
634
#endif
815
635
}
816
636
 
817
 
/***********************************************************************//**
 
637
/***************************************************************************
818
638
This function returns information of the next file in the directory. We jump
819
 
over the '.' and '..' entries in the directory.
820
 
@return 0 if ok, -1 if error, 1 if at the end of the directory */
 
639
over the '.' and '..' entries in the directory. */
821
640
UNIV_INTERN
822
641
int
823
642
os_file_readdir_next_file(
824
643
/*======================*/
825
 
        const char*     dirname,/*!< in: directory name or path */
826
 
        os_file_dir_t   dir,    /*!< in: directory stream */
827
 
        os_file_stat_t* info)   /*!< in/out: buffer where the info is returned */
 
644
                                /* out: 0 if ok, -1 if error, 1 if at the end
 
645
                                of the directory */
 
646
        const char*     dirname,/* in: directory name or path */
 
647
        os_file_dir_t   dir,    /* in: directory stream */
 
648
        os_file_stat_t* info)   /* in/out: buffer where the info is returned */
828
649
{
829
650
#ifdef __WIN__
830
651
        LPWIN32_FIND_DATA       lpFindFileData;
856
677
                        /* TODO: MySQL has apparently its own symlink
857
678
                        implementation in Windows, dbname.sym can
858
679
                        redirect a database directory:
859
 
                        REFMAN "windows-symbolic-links.html" */
 
680
                        http://dev.mysql.com/doc/refman/5.1/en/
 
681
                        windows-symbolic-links.html */
860
682
                        info->type = OS_FILE_TYPE_LINK;
861
683
                } else if (lpFindFileData->dwFileAttributes
862
684
                           & FILE_ATTRIBUTE_DIRECTORY) {
900
722
#ifdef HAVE_READDIR_R
901
723
        ret = readdir_r(dir, (struct dirent*)dirent_buf, &ent);
902
724
 
903
 
        if (ret != 0
904
 
#ifdef UNIV_AIX
905
 
            /* On AIX, only if we got non-NULL 'ent' (result) value and
906
 
            a non-zero 'ret' (return) value, it indicates a failed
907
 
            readdir_r() call. An NULL 'ent' with an non-zero 'ret'
908
 
            would indicate the "end of the directory" is reached. */
909
 
            && ent != NULL
910
 
#endif
911
 
           ) {
 
725
        if (ret != 0) {
912
726
                fprintf(stderr,
913
727
                        "InnoDB: cannot read directory %s, error %lu\n",
914
728
                        dirname, (ulong)ret);
947
761
        ret = stat(full_path, &statinfo);
948
762
 
949
763
        if (ret) {
950
 
 
951
 
                if (errno == ENOENT) {
952
 
                        /* readdir() returned a file that does not exist,
953
 
                        it must have been deleted in the meantime. Do what
954
 
                        would have happened if the file was deleted before
955
 
                        readdir() - ignore and go to the next entry.
956
 
                        If this is the last entry then info->name will still
957
 
                        contain the name of the deleted file when this
958
 
                        function returns, but this is not an issue since the
959
 
                        caller shouldn't be looking at info when end of
960
 
                        directory is returned. */
961
 
 
962
 
                        ut_free(full_path);
963
 
 
964
 
                        goto next_file;
965
 
                }
966
 
 
967
764
                os_file_handle_error_no_exit(full_path, "stat");
968
765
 
969
766
                ut_free(full_path);
989
786
#endif
990
787
}
991
788
 
992
 
/*****************************************************************//**
 
789
/*********************************************************************
993
790
This function attempts to create a directory named pathname. The new directory
994
791
gets default permissions. On Unix the permissions are (0770 & ~umask). If the
995
792
directory exists already, nothing is done and the call succeeds, unless the
996
 
fail_if_exists arguments is true.
997
 
@return TRUE if call succeeds, FALSE on error */
 
793
fail_if_exists arguments is true. */
998
794
UNIV_INTERN
999
795
ibool
1000
796
os_file_create_directory(
1001
797
/*=====================*/
1002
 
        const char*     pathname,       /*!< in: directory name as
 
798
                                        /* out: TRUE if call succeeds,
 
799
                                        FALSE on error */
 
800
        const char*     pathname,       /* in: directory name as
1003
801
                                        null-terminated string */
1004
 
        ibool           fail_if_exists) /*!< in: if TRUE, pre-existing directory
 
802
        ibool           fail_if_exists) /* in: if TRUE, pre-existing directory
1005
803
                                        is treated as an error. */
1006
804
{
1007
805
#ifdef __WIN__
1034
832
#endif
1035
833
}
1036
834
 
1037
 
/****************************************************************//**
1038
 
NOTE! Use the corresponding macro os_file_create_simple(), not directly
1039
 
this function!
1040
 
A simple function to open or create a file.
1041
 
@return own: handle to the file, not defined if error, error number
1042
 
can be retrieved with os_file_get_last_error */
 
835
/********************************************************************
 
836
A simple function to open or create a file. */
1043
837
UNIV_INTERN
1044
838
os_file_t
1045
 
os_file_create_simple_func(
1046
 
/*=======================*/
1047
 
        const char*     name,   /*!< in: name of the file or path as a
 
839
os_file_create_simple(
 
840
/*==================*/
 
841
                                /* out, own: handle to the file, not defined
 
842
                                if error, error number can be retrieved with
 
843
                                os_file_get_last_error */
 
844
        const char*     name,   /* in: name of the file or path as a
1048
845
                                null-terminated string */
1049
 
        ulint           create_mode,/*!< in: OS_FILE_OPEN if an existing file is
 
846
        ulint           create_mode,/* in: OS_FILE_OPEN if an existing file is
1050
847
                                opened (if does not exist, error), or
1051
848
                                OS_FILE_CREATE if a new file is created
1052
849
                                (if exists, error), or
1053
850
                                OS_FILE_CREATE_PATH if new file
1054
851
                                (if exists, error) and subdirectories along
1055
852
                                its path are created (if needed)*/
1056
 
        ulint           access_type,/*!< in: OS_FILE_READ_ONLY or
 
853
        ulint           access_type,/* in: OS_FILE_READ_ONLY or
1057
854
                                OS_FILE_READ_WRITE */
1058
 
        ibool*          success)/*!< out: TRUE if succeed, FALSE if error */
 
855
        ibool*          success)/* out: TRUE if succeed, FALSE if error */
1059
856
{
1060
857
#ifdef __WIN__
1061
858
        os_file_t       file;
1101
898
                          NULL, /* default security attributes */
1102
899
                          create_flag,
1103
900
                          attributes,
1104
 
                          NULL);        /*!< no template file */
 
901
                          NULL);        /* no template file */
1105
902
 
1106
903
        if (file == INVALID_HANDLE_VALUE) {
1107
904
                *success = FALSE;
1177
974
#endif /* __WIN__ */
1178
975
}
1179
976
 
1180
 
/****************************************************************//**
1181
 
NOTE! Use the corresponding macro
1182
 
os_file_create_simple_no_error_handling(), not directly this function!
1183
 
A simple function to open or create a file.
1184
 
@return own: handle to the file, not defined if error, error number
1185
 
can be retrieved with os_file_get_last_error */
 
977
/********************************************************************
 
978
A simple function to open or create a file. */
1186
979
UNIV_INTERN
1187
980
os_file_t
1188
 
os_file_create_simple_no_error_handling_func(
1189
 
/*=========================================*/
1190
 
        const char*     name,   /*!< in: name of the file or path as a
 
981
os_file_create_simple_no_error_handling(
 
982
/*====================================*/
 
983
                                /* out, own: handle to the file, not defined
 
984
                                if error, error number can be retrieved with
 
985
                                os_file_get_last_error */
 
986
        const char*     name,   /* in: name of the file or path as a
1191
987
                                null-terminated string */
1192
 
        ulint           create_mode,/*!< in: OS_FILE_OPEN if an existing file
 
988
        ulint           create_mode,/* in: OS_FILE_OPEN if an existing file
1193
989
                                is opened (if does not exist, error), or
1194
990
                                OS_FILE_CREATE if a new file is created
1195
991
                                (if exists, error) */
1196
 
        ulint           access_type,/*!< in: OS_FILE_READ_ONLY,
 
992
        ulint           access_type,/* in: OS_FILE_READ_ONLY,
1197
993
                                OS_FILE_READ_WRITE, or
1198
994
                                OS_FILE_READ_ALLOW_DELETE; the last option is
1199
995
                                used by a backup program reading the file */
1200
 
        ibool*          success)/*!< out: TRUE if succeed, FALSE if error */
 
996
        ibool*          success)/* out: TRUE if succeed, FALSE if error */
1201
997
{
1202
998
#ifdef __WIN__
1203
999
        os_file_t       file;
1224
1020
        } else if (access_type == OS_FILE_READ_ALLOW_DELETE) {
1225
1021
                access = GENERIC_READ;
1226
1022
                share_mode = FILE_SHARE_DELETE | FILE_SHARE_READ
1227
 
                        | FILE_SHARE_WRITE;     /*!< A backup program has to give
 
1023
                        | FILE_SHARE_WRITE;     /* A backup program has to give
1228
1024
                                                mysqld the maximum freedom to
1229
1025
                                                do what it likes with the
1230
1026
                                                file */
1239
1035
                          NULL, /* default security attributes */
1240
1036
                          create_flag,
1241
1037
                          attributes,
1242
 
                          NULL);        /*!< no template file */
 
1038
                          NULL);        /* no template file */
1243
1039
 
1244
1040
        if (file == INVALID_HANDLE_VALUE) {
1245
1041
                *success = FALSE;
1291
1087
#endif /* __WIN__ */
1292
1088
}
1293
1089
 
1294
 
/****************************************************************//**
 
1090
/********************************************************************
1295
1091
Tries to disable OS caching on an opened file descriptor. */
1296
1092
UNIV_INTERN
1297
1093
void
1298
1094
os_file_set_nocache(
1299
1095
/*================*/
1300
 
        int             fd,             /*!< in: file descriptor to alter */
1301
 
        const char*     file_name,      /*!< in: file name, used in the
 
1096
        int             fd,             /* in: file descriptor to alter */
 
1097
        const char*     file_name,      /* in: file name, used in the
1302
1098
                                        diagnostic message */
1303
 
        const char*     operation_name) /*!< in: "open" or "create"; used in the
 
1099
        const char*     operation_name) /* in: "open" or "create"; used in the
1304
1100
                                        diagnostic message */
1305
1101
{
1306
1102
        /* some versions of Solaris may not have DIRECTIO_ON */
1338
1134
#endif
1339
1135
}
1340
1136
 
1341
 
/****************************************************************//**
1342
 
NOTE! Use the corresponding macro os_file_create(), not directly
1343
 
this function!
1344
 
Opens an existing file or creates a new.
1345
 
@return own: handle to the file, not defined if error, error number
1346
 
can be retrieved with os_file_get_last_error */
 
1137
/********************************************************************
 
1138
Opens an existing file or creates a new. */
1347
1139
UNIV_INTERN
1348
1140
os_file_t
1349
 
os_file_create_func(
1350
 
/*================*/
1351
 
        const char*     name,   /*!< in: name of the file or path as a
 
1141
os_file_create(
 
1142
/*===========*/
 
1143
                                /* out, own: handle to the file, not defined
 
1144
                                if error, error number can be retrieved with
 
1145
                                os_file_get_last_error */
 
1146
        const char*     name,   /* in: name of the file or path as a
1352
1147
                                null-terminated string */
1353
 
        ulint           create_mode,/*!< in: OS_FILE_OPEN if an existing file
 
1148
        ulint           create_mode,/* in: OS_FILE_OPEN if an existing file
1354
1149
                                is opened (if does not exist, error), or
1355
1150
                                OS_FILE_CREATE if a new file is created
1356
1151
                                (if exists, error),
1358
1153
                                or an old overwritten;
1359
1154
                                OS_FILE_OPEN_RAW, if a raw device or disk
1360
1155
                                partition should be opened */
1361
 
        ulint           purpose,/*!< in: OS_FILE_AIO, if asynchronous,
 
1156
        ulint           purpose,/* in: OS_FILE_AIO, if asynchronous,
1362
1157
                                non-buffered i/o is desired,
1363
1158
                                OS_FILE_NORMAL, if any normal file;
1364
1159
                                NOTE that it also depends on type, os_aio_..
1365
1160
                                and srv_.. variables whether we really use
1366
1161
                                async i/o or unbuffered i/o: look in the
1367
1162
                                function source code for the exact rules */
1368
 
        ulint           type,   /*!< in: OS_DATA_FILE or OS_LOG_FILE */
1369
 
        ibool*          success)/*!< out: TRUE if succeed, FALSE if error */
 
1163
        ulint           type,   /* in: OS_DATA_FILE or OS_LOG_FILE */
 
1164
        ibool*          success)/* out: TRUE if succeed, FALSE if error */
1370
1165
{
1371
1166
#ifdef __WIN__
1372
1167
        os_file_t       file;
1397
1192
                buffering of writes in the OS */
1398
1193
                attributes = 0;
1399
1194
#ifdef WIN_ASYNC_IO
1400
 
                if (srv_use_native_aio) {
 
1195
                if (os_aio_use_native_aio) {
1401
1196
                        attributes = attributes | FILE_FLAG_OVERLAPPED;
1402
1197
                }
1403
1198
#endif
1404
1199
#ifdef UNIV_NON_BUFFERED_IO
1405
 
# ifndef UNIV_HOTBACKUP
1406
1200
                if (type == OS_LOG_FILE && srv_flush_log_at_trx_commit == 2) {
1407
1201
                        /* Do not use unbuffered i/o to log files because
1408
1202
                        value 2 denotes that we do not flush the log at every
1411
1205
                           == SRV_WIN_IO_UNBUFFERED) {
1412
1206
                        attributes = attributes | FILE_FLAG_NO_BUFFERING;
1413
1207
                }
1414
 
# else /* !UNIV_HOTBACKUP */
1415
 
                attributes = attributes | FILE_FLAG_NO_BUFFERING;
1416
 
# endif /* !UNIV_HOTBACKUP */
1417
 
#endif /* UNIV_NON_BUFFERED_IO */
 
1208
#endif
1418
1209
        } else if (purpose == OS_FILE_NORMAL) {
1419
1210
                attributes = 0;
1420
1211
#ifdef UNIV_NON_BUFFERED_IO
1421
 
# ifndef UNIV_HOTBACKUP
1422
1212
                if (type == OS_LOG_FILE && srv_flush_log_at_trx_commit == 2) {
1423
1213
                        /* Do not use unbuffered i/o to log files because
1424
1214
                        value 2 denotes that we do not flush the log at every
1427
1217
                           == SRV_WIN_IO_UNBUFFERED) {
1428
1218
                        attributes = attributes | FILE_FLAG_NO_BUFFERING;
1429
1219
                }
1430
 
# else /* !UNIV_HOTBACKUP */
1431
 
                attributes = attributes | FILE_FLAG_NO_BUFFERING;
1432
 
# endif /* !UNIV_HOTBACKUP */
1433
 
#endif /* UNIV_NON_BUFFERED_IO */
 
1220
#endif
1434
1221
        } else {
1435
1222
                attributes = 0;
1436
1223
                ut_error;
1453
1240
                          NULL, /* default security attributes */
1454
1241
                          create_flag,
1455
1242
                          attributes,
1456
 
                          NULL);        /*!< no template file */
 
1243
                          NULL);        /* no template file */
1457
1244
 
1458
1245
        if (file == INVALID_HANDLE_VALUE) {
1459
1246
                *success = FALSE;
1460
1247
 
1461
1248
                /* When srv_file_per_table is on, file creation failure may not
1462
1249
                be critical to the whole instance. Do not crash the server in
1463
 
                case of unknown errors.
1464
 
                Please note "srv_file_per_table" is a global variable with
1465
 
                no explicit synchronization protection. It could be
1466
 
                changed during this execution path. It might not have the
1467
 
                same value as the one when building the table definition */
 
1250
                case of unknown errors. */
1468
1251
                if (srv_file_per_table) {
1469
1252
                        retry = os_file_handle_error_no_exit(name,
1470
1253
                                                create_mode == OS_FILE_CREATE ?
1488
1271
        int             create_flag;
1489
1272
        ibool           retry;
1490
1273
        const char*     mode_str        = NULL;
 
1274
        const char*     type_str        = NULL;
 
1275
        const char*     purpose_str     = NULL;
1491
1276
 
1492
1277
try_again:
1493
1278
        ut_a(name);
1507
1292
                ut_error;
1508
1293
        }
1509
1294
 
1510
 
        ut_a(type == OS_LOG_FILE || type == OS_DATA_FILE);
1511
 
        ut_a(purpose == OS_FILE_AIO || purpose == OS_FILE_NORMAL);
1512
 
 
 
1295
        if (type == OS_LOG_FILE) {
 
1296
                type_str = "LOG";
 
1297
        } else if (type == OS_DATA_FILE) {
 
1298
                type_str = "DATA";
 
1299
        } else {
 
1300
                ut_error;
 
1301
        }
 
1302
 
 
1303
        if (purpose == OS_FILE_AIO) {
 
1304
                purpose_str = "AIO";
 
1305
        } else if (purpose == OS_FILE_NORMAL) {
 
1306
                purpose_str = "NORMAL";
 
1307
        } else {
 
1308
                ut_error;
 
1309
        }
 
1310
 
 
1311
#if 0
 
1312
        fprintf(stderr, "Opening file %s, mode %s, type %s, purpose %s\n",
 
1313
                name, mode_str, type_str, purpose_str);
 
1314
#endif
1513
1315
#ifdef O_SYNC
1514
1316
        /* We let O_SYNC only affect log files; note that we map O_DSYNC to
1515
1317
        O_SYNC because the datasync options seemed to corrupt files in 2001
1532
1334
 
1533
1335
                /* When srv_file_per_table is on, file creation failure may not
1534
1336
                be critical to the whole instance. Do not crash the server in
1535
 
                case of unknown errors.
1536
 
                Please note "srv_file_per_table" is a global variable with
1537
 
                no explicit synchronization protection. It could be
1538
 
                changed during this execution path. It might not have the
1539
 
                same value as the one when building the table definition */
 
1337
                case of unknown errors. */
1540
1338
                if (srv_file_per_table) {
1541
1339
                        retry = os_file_handle_error_no_exit(name,
1542
1340
                                                create_mode == OS_FILE_CREATE ?
1595
1393
#endif /* __WIN__ */
1596
1394
}
1597
1395
 
1598
 
/***********************************************************************//**
1599
 
Deletes a file if it exists. The file has to be closed before calling this.
1600
 
@return TRUE if success */
 
1396
/***************************************************************************
 
1397
Deletes a file if it exists. The file has to be closed before calling this. */
1601
1398
UNIV_INTERN
1602
1399
ibool
1603
1400
os_file_delete_if_exists(
1604
1401
/*=====================*/
1605
 
        const char*     name)   /*!< in: file path as a null-terminated string */
 
1402
                                /* out: TRUE if success */
 
1403
        const char*     name)   /* in: file path as a null-terminated string */
1606
1404
{
1607
1405
#ifdef __WIN__
1608
1406
        BOOL    ret;
1657
1455
#endif
1658
1456
}
1659
1457
 
1660
 
/***********************************************************************//**
1661
 
Deletes a file. The file has to be closed before calling this.
1662
 
@return TRUE if success */
 
1458
/***************************************************************************
 
1459
Deletes a file. The file has to be closed before calling this. */
1663
1460
UNIV_INTERN
1664
1461
ibool
1665
1462
os_file_delete(
1666
1463
/*===========*/
1667
 
        const char*     name)   /*!< in: file path as a null-terminated string */
 
1464
                                /* out: TRUE if success */
 
1465
        const char*     name)   /* in: file path as a null-terminated string */
1668
1466
{
1669
1467
#ifdef __WIN__
1670
1468
        BOOL    ret;
1720
1518
#endif
1721
1519
}
1722
1520
 
1723
 
/***********************************************************************//**
1724
 
NOTE! Use the corresponding macro os_file_rename(), not directly this function!
 
1521
/***************************************************************************
1725
1522
Renames a file (can also move it to another directory). It is safest that the
1726
 
file is closed before calling this function.
1727
 
@return TRUE if success */
 
1523
file is closed before calling this function. */
1728
1524
UNIV_INTERN
1729
1525
ibool
1730
 
os_file_rename_func(
1731
 
/*================*/
1732
 
        const char*     oldpath,/*!< in: old file path as a null-terminated
 
1526
os_file_rename(
 
1527
/*===========*/
 
1528
                                /* out: TRUE if success */
 
1529
        const char*     oldpath,/* in: old file path as a null-terminated
1733
1530
                                string */
1734
 
        const char*     newpath)/*!< in: new file path */
 
1531
        const char*     newpath)/* in: new file path */
1735
1532
{
1736
1533
#ifdef __WIN__
1737
1534
        BOOL    ret;
1760
1557
#endif
1761
1558
}
1762
1559
 
1763
 
/***********************************************************************//**
1764
 
NOTE! Use the corresponding macro os_file_close(), not directly this function!
 
1560
/***************************************************************************
1765
1561
Closes a file handle. In case of error, error number can be retrieved with
1766
 
os_file_get_last_error.
1767
 
@return TRUE if success */
 
1562
os_file_get_last_error. */
1768
1563
UNIV_INTERN
1769
1564
ibool
1770
 
os_file_close_func(
1771
 
/*===============*/
1772
 
        os_file_t       file)   /*!< in, own: handle to a file */
 
1565
os_file_close(
 
1566
/*==========*/
 
1567
                                /* out: TRUE if success */
 
1568
        os_file_t       file)   /* in, own: handle to a file */
1773
1569
{
1774
1570
#ifdef __WIN__
1775
1571
        BOOL    ret;
1800
1596
#endif
1801
1597
}
1802
1598
 
1803
 
#ifdef UNIV_HOTBACKUP
1804
 
/***********************************************************************//**
1805
 
Closes a file handle.
1806
 
@return TRUE if success */
 
1599
/***************************************************************************
 
1600
Closes a file handle. */
1807
1601
UNIV_INTERN
1808
1602
ibool
1809
1603
os_file_close_no_error_handling(
1810
1604
/*============================*/
1811
 
        os_file_t       file)   /*!< in, own: handle to a file */
 
1605
                                /* out: TRUE if success */
 
1606
        os_file_t       file)   /* in, own: handle to a file */
1812
1607
{
1813
1608
#ifdef __WIN__
1814
1609
        BOOL    ret;
1835
1630
        return(TRUE);
1836
1631
#endif
1837
1632
}
1838
 
#endif /* UNIV_HOTBACKUP */
1839
1633
 
1840
 
/***********************************************************************//**
1841
 
Gets a file size.
1842
 
@return TRUE if success */
 
1634
/***************************************************************************
 
1635
Gets a file size. */
1843
1636
UNIV_INTERN
1844
1637
ibool
1845
1638
os_file_get_size(
1846
1639
/*=============*/
1847
 
        os_file_t       file,   /*!< in: handle to a file */
1848
 
        ulint*          size,   /*!< out: least significant 32 bits of file
 
1640
                                /* out: TRUE if success */
 
1641
        os_file_t       file,   /* in: handle to a file */
 
1642
        ulint*          size,   /* out: least significant 32 bits of file
1849
1643
                                size */
1850
 
        ulint*          size_high)/*!< out: most significant 32 bits of size */
 
1644
        ulint*          size_high)/* out: most significant 32 bits of size */
1851
1645
{
1852
1646
#ifdef __WIN__
1853
1647
        DWORD   high;
1885
1679
#endif
1886
1680
}
1887
1681
 
1888
 
/***********************************************************************//**
1889
 
Gets file size as a 64-bit integer ib_int64_t.
1890
 
@return size in bytes, -1 if error */
 
1682
/***************************************************************************
 
1683
Gets file size as a 64-bit integer ib_int64_t. */
1891
1684
UNIV_INTERN
1892
1685
ib_int64_t
1893
1686
os_file_get_size_as_iblonglong(
1894
1687
/*===========================*/
1895
 
        os_file_t       file)   /*!< in: handle to a file */
 
1688
                                /* out: size in bytes, -1 if error */
 
1689
        os_file_t       file)   /* in: handle to a file */
1896
1690
{
1897
1691
        ulint   size;
1898
1692
        ulint   size_high;
1908
1702
        return((((ib_int64_t)size_high) << 32) + (ib_int64_t)size);
1909
1703
}
1910
1704
 
1911
 
/***********************************************************************//**
1912
 
Write the specified number of zeros to a newly created file.
1913
 
@return TRUE if success */
 
1705
/***************************************************************************
 
1706
Write the specified number of zeros to a newly created file. */
1914
1707
UNIV_INTERN
1915
1708
ibool
1916
1709
os_file_set_size(
1917
1710
/*=============*/
1918
 
        const char*     name,   /*!< in: name of the file or path as a
 
1711
                                /* out: TRUE if success */
 
1712
        const char*     name,   /* in: name of the file or path as a
1919
1713
                                null-terminated string */
1920
 
        os_file_t       file,   /*!< in: handle to a file */
1921
 
        ulint           size,   /*!< in: least significant 32 bits of file
 
1714
        os_file_t       file,   /* in: handle to a file */
 
1715
        ulint           size,   /* in: least significant 32 bits of file
1922
1716
                                size */
1923
 
        ulint           size_high)/*!< in: most significant 32 bits of size */
 
1717
        ulint           size_high)/* in: most significant 32 bits of size */
1924
1718
{
1925
1719
        ib_int64_t      current_size;
1926
1720
        ib_int64_t      desired_size;
1997
1791
        return(FALSE);
1998
1792
}
1999
1793
 
2000
 
/***********************************************************************//**
2001
 
Truncates a file at its current position.
2002
 
@return TRUE if success */
 
1794
/***************************************************************************
 
1795
Truncates a file at its current position. */
2003
1796
UNIV_INTERN
2004
1797
ibool
2005
1798
os_file_set_eof(
2006
1799
/*============*/
2007
 
        FILE*           file)   /*!< in: file to be truncated */
 
1800
                                /* out: TRUE if success */
 
1801
        FILE*           file)   /* in: file to be truncated */
2008
1802
{
2009
1803
#ifdef __WIN__
2010
1804
        HANDLE h = (HANDLE) _get_osfhandle(fileno(file));
2015
1809
}
2016
1810
 
2017
1811
#ifndef __WIN__
2018
 
/***********************************************************************//**
 
1812
/***************************************************************************
2019
1813
Wrapper to fsync(2) that retries the call on some errors.
2020
1814
Returns the value 0 if successful; otherwise the value -1 is returned and
2021
 
the global variable errno is set to indicate the error.
2022
 
@return 0 if success, -1 otherwise */
 
1815
the global variable errno is set to indicate the error. */
2023
1816
 
2024
1817
static
2025
1818
int
2026
1819
os_file_fsync(
2027
1820
/*==========*/
2028
 
        os_file_t       file)   /*!< in: handle to a file */
 
1821
                                /* out: 0 if success, -1 otherwise */
 
1822
        os_file_t       file)   /* in: handle to a file */
2029
1823
{
2030
1824
        int     ret;
2031
1825
        int     failures;
2063
1857
}
2064
1858
#endif /* !__WIN__ */
2065
1859
 
2066
 
/***********************************************************************//**
2067
 
NOTE! Use the corresponding macro os_file_flush(), not directly this function!
2068
 
Flushes the write buffers of a given file to the disk.
2069
 
@return TRUE if success */
 
1860
/***************************************************************************
 
1861
Flushes the write buffers of a given file to the disk. */
2070
1862
UNIV_INTERN
2071
1863
ibool
2072
 
os_file_flush_func(
2073
 
/*===============*/
2074
 
        os_file_t       file)   /*!< in, own: handle to a file */
 
1864
os_file_flush(
 
1865
/*==========*/
 
1866
                                /* out: TRUE if success */
 
1867
        os_file_t       file)   /* in, own: handle to a file */
2075
1868
{
2076
1869
#ifdef __WIN__
2077
1870
        BOOL    ret;
2163
1956
}
2164
1957
 
2165
1958
#ifndef __WIN__
2166
 
/*******************************************************************//**
2167
 
Does a synchronous read operation in Posix.
2168
 
@return number of bytes read, -1 if error */
 
1959
/***********************************************************************
 
1960
Does a synchronous read operation in Posix. */
2169
1961
static
2170
1962
ssize_t
2171
1963
os_file_pread(
2172
1964
/*==========*/
2173
 
        os_file_t       file,   /*!< in: handle to a file */
2174
 
        void*           buf,    /*!< in: buffer where to read */
2175
 
        ulint           n,      /*!< in: number of bytes to read */
2176
 
        ulint           offset, /*!< in: least significant 32 bits of file
 
1965
                                /* out: number of bytes read, -1 if error */
 
1966
        os_file_t       file,   /* in: handle to a file */
 
1967
        void*           buf,    /* in: buffer where to read */
 
1968
        ulint           n,      /* in: number of bytes to read */
 
1969
        ulint           offset, /* in: least significant 32 bits of file
2177
1970
                                offset from where to read */
2178
 
        ulint           offset_high) /*!< in: most significant 32 bits of
 
1971
        ulint           offset_high) /* in: most significant 32 bits of
2179
1972
                                offset */
2180
1973
{
2181
1974
        off_t   offs;
2182
 
#if defined(HAVE_PREAD) && !defined(HAVE_BROKEN_PREAD)
2183
1975
        ssize_t n_bytes;
2184
 
#endif /* HAVE_PREAD && !HAVE_BROKEN_PREAD */
2185
1976
 
2186
1977
        ut_a((offset & 0xFFFFFFFFUL) == offset);
2187
1978
 
2220
2011
        {
2221
2012
                off_t   ret_offset;
2222
2013
                ssize_t ret;
2223
 
#ifndef UNIV_HOTBACKUP
2224
2014
                ulint   i;
2225
 
#endif /* !UNIV_HOTBACKUP */
2226
2015
 
2227
2016
                os_mutex_enter(os_file_count_mutex);
2228
2017
                os_n_pending_reads++;
2229
2018
                os_mutex_exit(os_file_count_mutex);
2230
2019
 
2231
 
#ifndef UNIV_HOTBACKUP
2232
2020
                /* Protect the seek / read operation with a mutex */
2233
2021
                i = ((ulint) file) % OS_FILE_N_SEEK_MUTEXES;
2234
2022
 
2235
2023
                os_mutex_enter(os_file_seek_mutexes[i]);
2236
 
#endif /* !UNIV_HOTBACKUP */
2237
2024
 
2238
2025
                ret_offset = lseek(file, offs, SEEK_SET);
2239
2026
 
2243
2030
                        ret = read(file, buf, (ssize_t)n);
2244
2031
                }
2245
2032
 
2246
 
#ifndef UNIV_HOTBACKUP
2247
2033
                os_mutex_exit(os_file_seek_mutexes[i]);
2248
 
#endif /* !UNIV_HOTBACKUP */
2249
2034
 
2250
2035
                os_mutex_enter(os_file_count_mutex);
2251
2036
                os_n_pending_reads--;
2256
2041
#endif
2257
2042
}
2258
2043
 
2259
 
/*******************************************************************//**
2260
 
Does a synchronous write operation in Posix.
2261
 
@return number of bytes written, -1 if error */
 
2044
/***********************************************************************
 
2045
Does a synchronous write operation in Posix. */
2262
2046
static
2263
2047
ssize_t
2264
2048
os_file_pwrite(
2265
2049
/*===========*/
2266
 
        os_file_t       file,   /*!< in: handle to a file */
2267
 
        const void*     buf,    /*!< in: buffer from where to write */
2268
 
        ulint           n,      /*!< in: number of bytes to write */
2269
 
        ulint           offset, /*!< in: least significant 32 bits of file
 
2050
                                /* out: number of bytes written, -1 if error */
 
2051
        os_file_t       file,   /* in: handle to a file */
 
2052
        const void*     buf,    /* in: buffer from where to write */
 
2053
        ulint           n,      /* in: number of bytes to write */
 
2054
        ulint           offset, /* in: least significant 32 bits of file
2270
2055
                                offset where to write */
2271
 
        ulint           offset_high) /*!< in: most significant 32 bits of
 
2056
        ulint           offset_high) /* in: most significant 32 bits of
2272
2057
                                offset */
2273
2058
{
2274
2059
        ssize_t ret;
2323
2108
#else
2324
2109
        {
2325
2110
                off_t   ret_offset;
2326
 
# ifndef UNIV_HOTBACKUP
2327
2111
                ulint   i;
2328
 
# endif /* !UNIV_HOTBACKUP */
2329
2112
 
2330
2113
                os_mutex_enter(os_file_count_mutex);
2331
2114
                os_n_pending_writes++;
2332
2115
                os_mutex_exit(os_file_count_mutex);
2333
2116
 
2334
 
# ifndef UNIV_HOTBACKUP
2335
2117
                /* Protect the seek / write operation with a mutex */
2336
2118
                i = ((ulint) file) % OS_FILE_N_SEEK_MUTEXES;
2337
2119
 
2338
2120
                os_mutex_enter(os_file_seek_mutexes[i]);
2339
 
# endif /* UNIV_HOTBACKUP */
2340
2121
 
2341
2122
                ret_offset = lseek(file, offs, SEEK_SET);
2342
2123
 
2362
2143
# endif /* UNIV_DO_FLUSH */
2363
2144
 
2364
2145
func_exit:
2365
 
# ifndef UNIV_HOTBACKUP
2366
2146
                os_mutex_exit(os_file_seek_mutexes[i]);
2367
 
# endif /* !UNIV_HOTBACKUP */
2368
2147
 
2369
2148
                os_mutex_enter(os_file_count_mutex);
2370
2149
                os_n_pending_writes--;
2376
2155
}
2377
2156
#endif
2378
2157
 
2379
 
/*******************************************************************//**
2380
 
NOTE! Use the corresponding macro os_file_read(), not directly this
2381
 
function!
2382
 
Requests a synchronous positioned read operation.
2383
 
@return TRUE if request was successful, FALSE if fail */
 
2158
/***********************************************************************
 
2159
Requests a synchronous positioned read operation. */
2384
2160
UNIV_INTERN
2385
2161
ibool
2386
 
os_file_read_func(
2387
 
/*==============*/
2388
 
        os_file_t       file,   /*!< in: handle to a file */
2389
 
        void*           buf,    /*!< in: buffer where to read */
2390
 
        ulint           offset, /*!< in: least significant 32 bits of file
 
2162
os_file_read(
 
2163
/*=========*/
 
2164
                                /* out: TRUE if request was
 
2165
                                successful, FALSE if fail */
 
2166
        os_file_t       file,   /* in: handle to a file */
 
2167
        void*           buf,    /* in: buffer where to read */
 
2168
        ulint           offset, /* in: least significant 32 bits of file
2391
2169
                                offset where to read */
2392
 
        ulint           offset_high, /*!< in: most significant 32 bits of
 
2170
        ulint           offset_high, /* in: most significant 32 bits of
2393
2171
                                offset */
2394
 
        ulint           n)      /*!< in: number of bytes to read */
 
2172
        ulint           n)      /* in: number of bytes to read */
2395
2173
{
2396
2174
#ifdef __WIN__
2397
2175
        BOOL            ret;
2400
2178
        DWORD           low;
2401
2179
        DWORD           high;
2402
2180
        ibool           retry;
2403
 
#ifndef UNIV_HOTBACKUP
2404
2181
        ulint           i;
2405
 
#endif /* !UNIV_HOTBACKUP */
2406
2182
 
2407
2183
        ut_a((offset & 0xFFFFFFFFUL) == offset);
2408
2184
 
2421
2197
        os_n_pending_reads++;
2422
2198
        os_mutex_exit(os_file_count_mutex);
2423
2199
 
2424
 
#ifndef UNIV_HOTBACKUP
2425
2200
        /* Protect the seek / read operation with a mutex */
2426
2201
        i = ((ulint) file) % OS_FILE_N_SEEK_MUTEXES;
2427
2202
 
2428
2203
        os_mutex_enter(os_file_seek_mutexes[i]);
2429
 
#endif /* !UNIV_HOTBACKUP */
2430
2204
 
2431
2205
        ret2 = SetFilePointer(file, low, &high, FILE_BEGIN);
2432
2206
 
2433
2207
        if (ret2 == 0xFFFFFFFF && GetLastError() != NO_ERROR) {
2434
2208
 
2435
 
#ifndef UNIV_HOTBACKUP
2436
2209
                os_mutex_exit(os_file_seek_mutexes[i]);
2437
 
#endif /* !UNIV_HOTBACKUP */
2438
2210
 
2439
2211
                os_mutex_enter(os_file_count_mutex);
2440
2212
                os_n_pending_reads--;
2445
2217
 
2446
2218
        ret = ReadFile(file, buf, (DWORD) n, &len, NULL);
2447
2219
 
2448
 
#ifndef UNIV_HOTBACKUP
2449
2220
        os_mutex_exit(os_file_seek_mutexes[i]);
2450
 
#endif /* !UNIV_HOTBACKUP */
2451
2221
 
2452
2222
        os_mutex_enter(os_file_count_mutex);
2453
2223
        os_n_pending_reads--;
2456
2226
        if (ret && len == n) {
2457
2227
                return(TRUE);
2458
2228
        }
2459
 
#else /* __WIN__ */
 
2229
#else
2460
2230
        ibool   retry;
2461
2231
        ssize_t ret;
2462
2232
 
2475
2245
                "InnoDB: Was only able to read %ld.\n",
2476
2246
                (ulong)n, (ulong)offset_high,
2477
2247
                (ulong)offset, (long)ret);
2478
 
#endif /* __WIN__ */
 
2248
#endif
2479
2249
#ifdef __WIN__
2480
2250
error_handling:
2481
2251
#endif
2501
2271
        return(FALSE);
2502
2272
}
2503
2273
 
2504
 
/*******************************************************************//**
2505
 
NOTE! Use the corresponding macro os_file_read_no_error_handling(),
2506
 
not directly this function!
 
2274
/***********************************************************************
2507
2275
Requests a synchronous positioned read operation. This function does not do
2508
 
any error handling. In case of error it returns FALSE.
2509
 
@return TRUE if request was successful, FALSE if fail */
 
2276
any error handling. In case of error it returns FALSE. */
2510
2277
UNIV_INTERN
2511
2278
ibool
2512
 
os_file_read_no_error_handling_func(
2513
 
/*================================*/
2514
 
        os_file_t       file,   /*!< in: handle to a file */
2515
 
        void*           buf,    /*!< in: buffer where to read */
2516
 
        ulint           offset, /*!< in: least significant 32 bits of file
 
2279
os_file_read_no_error_handling(
 
2280
/*===========================*/
 
2281
                                /* out: TRUE if request was
 
2282
                                successful, FALSE if fail */
 
2283
        os_file_t       file,   /* in: handle to a file */
 
2284
        void*           buf,    /* in: buffer where to read */
 
2285
        ulint           offset, /* in: least significant 32 bits of file
2517
2286
                                offset where to read */
2518
 
        ulint           offset_high, /*!< in: most significant 32 bits of
 
2287
        ulint           offset_high, /* in: most significant 32 bits of
2519
2288
                                offset */
2520
 
        ulint           n)      /*!< in: number of bytes to read */
 
2289
        ulint           n)      /* in: number of bytes to read */
2521
2290
{
2522
2291
#ifdef __WIN__
2523
2292
        BOOL            ret;
2526
2295
        DWORD           low;
2527
2296
        DWORD           high;
2528
2297
        ibool           retry;
2529
 
#ifndef UNIV_HOTBACKUP
2530
2298
        ulint           i;
2531
 
#endif /* !UNIV_HOTBACKUP */
2532
2299
 
2533
2300
        ut_a((offset & 0xFFFFFFFFUL) == offset);
2534
2301
 
2547
2314
        os_n_pending_reads++;
2548
2315
        os_mutex_exit(os_file_count_mutex);
2549
2316
 
2550
 
#ifndef UNIV_HOTBACKUP
2551
2317
        /* Protect the seek / read operation with a mutex */
2552
2318
        i = ((ulint) file) % OS_FILE_N_SEEK_MUTEXES;
2553
2319
 
2554
2320
        os_mutex_enter(os_file_seek_mutexes[i]);
2555
 
#endif /* !UNIV_HOTBACKUP */
2556
2321
 
2557
2322
        ret2 = SetFilePointer(file, low, &high, FILE_BEGIN);
2558
2323
 
2559
2324
        if (ret2 == 0xFFFFFFFF && GetLastError() != NO_ERROR) {
2560
2325
 
2561
 
#ifndef UNIV_HOTBACKUP
2562
2326
                os_mutex_exit(os_file_seek_mutexes[i]);
2563
 
#endif /* !UNIV_HOTBACKUP */
2564
2327
 
2565
2328
                os_mutex_enter(os_file_count_mutex);
2566
2329
                os_n_pending_reads--;
2571
2334
 
2572
2335
        ret = ReadFile(file, buf, (DWORD) n, &len, NULL);
2573
2336
 
2574
 
#ifndef UNIV_HOTBACKUP
2575
2337
        os_mutex_exit(os_file_seek_mutexes[i]);
2576
 
#endif /* !UNIV_HOTBACKUP */
2577
2338
 
2578
2339
        os_mutex_enter(os_file_count_mutex);
2579
2340
        os_n_pending_reads--;
2582
2343
        if (ret && len == n) {
2583
2344
                return(TRUE);
2584
2345
        }
2585
 
#else /* __WIN__ */
 
2346
#else
2586
2347
        ibool   retry;
2587
2348
        ssize_t ret;
2588
2349
 
2595
2356
 
2596
2357
                return(TRUE);
2597
2358
        }
2598
 
#endif /* __WIN__ */
 
2359
#endif
2599
2360
#ifdef __WIN__
2600
2361
error_handling:
2601
2362
#endif
2608
2369
        return(FALSE);
2609
2370
}
2610
2371
 
2611
 
/*******************************************************************//**
 
2372
/***********************************************************************
2612
2373
Rewind file to its start, read at most size - 1 bytes from it to str, and
2613
2374
NUL-terminate str. All errors are silently ignored. This function is
2614
2375
mostly meant to be used with temporary files. */
2616
2377
void
2617
2378
os_file_read_string(
2618
2379
/*================*/
2619
 
        FILE*   file,   /*!< in: file to read from */
2620
 
        char*   str,    /*!< in: buffer where to read */
2621
 
        ulint   size)   /*!< in: size of buffer */
 
2380
        FILE*   file,   /* in: file to read from */
 
2381
        char*   str,    /* in: buffer where to read */
 
2382
        ulint   size)   /* in: size of buffer */
2622
2383
{
2623
2384
        size_t  flen;
2624
2385
 
2631
2392
        str[flen] = '\0';
2632
2393
}
2633
2394
 
2634
 
/*******************************************************************//**
2635
 
NOTE! Use the corresponding macro os_file_write(), not directly
2636
 
this function!
2637
 
Requests a synchronous write operation.
2638
 
@return TRUE if request was successful, FALSE if fail */
 
2395
/***********************************************************************
 
2396
Requests a synchronous write operation. */
2639
2397
UNIV_INTERN
2640
2398
ibool
2641
 
os_file_write_func(
2642
 
/*===============*/
2643
 
        const char*     name,   /*!< in: name of the file or path as a
 
2399
os_file_write(
 
2400
/*==========*/
 
2401
                                /* out: TRUE if request was
 
2402
                                successful, FALSE if fail */
 
2403
        const char*     name,   /* in: name of the file or path as a
2644
2404
                                null-terminated string */
2645
 
        os_file_t       file,   /*!< in: handle to a file */
2646
 
        const void*     buf,    /*!< in: buffer from which to write */
2647
 
        ulint           offset, /*!< in: least significant 32 bits of file
 
2405
        os_file_t       file,   /* in: handle to a file */
 
2406
        const void*     buf,    /* in: buffer from which to write */
 
2407
        ulint           offset, /* in: least significant 32 bits of file
2648
2408
                                offset where to write */
2649
 
        ulint           offset_high, /*!< in: most significant 32 bits of
 
2409
        ulint           offset_high, /* in: most significant 32 bits of
2650
2410
                                offset */
2651
 
        ulint           n)      /*!< in: number of bytes to write */
 
2411
        ulint           n)      /* in: number of bytes to write */
2652
2412
{
2653
2413
#ifdef __WIN__
2654
2414
        BOOL            ret;
2656
2416
        DWORD           ret2;
2657
2417
        DWORD           low;
2658
2418
        DWORD           high;
 
2419
        ulint           i;
2659
2420
        ulint           n_retries       = 0;
2660
2421
        ulint           err;
2661
 
#ifndef UNIV_HOTBACKUP
2662
 
        ulint           i;
2663
 
#endif /* !UNIV_HOTBACKUP */
2664
2422
 
2665
2423
        ut_a((offset & 0xFFFFFFFF) == offset);
2666
2424
 
2677
2435
        os_n_pending_writes++;
2678
2436
        os_mutex_exit(os_file_count_mutex);
2679
2437
 
2680
 
#ifndef UNIV_HOTBACKUP
2681
2438
        /* Protect the seek / write operation with a mutex */
2682
2439
        i = ((ulint) file) % OS_FILE_N_SEEK_MUTEXES;
2683
2440
 
2684
2441
        os_mutex_enter(os_file_seek_mutexes[i]);
2685
 
#endif /* !UNIV_HOTBACKUP */
2686
2442
 
2687
2443
        ret2 = SetFilePointer(file, low, &high, FILE_BEGIN);
2688
2444
 
2689
2445
        if (ret2 == 0xFFFFFFFF && GetLastError() != NO_ERROR) {
2690
2446
 
2691
 
#ifndef UNIV_HOTBACKUP
2692
2447
                os_mutex_exit(os_file_seek_mutexes[i]);
2693
 
#endif /* !UNIV_HOTBACKUP */
2694
2448
 
2695
2449
                os_mutex_enter(os_file_count_mutex);
2696
2450
                os_n_pending_writes--;
2706
2460
                        "InnoDB: Some operating system error numbers"
2707
2461
                        " are described at\n"
2708
2462
                        "InnoDB: "
2709
 
                        REFMAN "operating-system-error-codes.html\n",
 
2463
                        "http://dev.mysql.com/doc/refman/5.1/en/"
 
2464
                        "operating-system-error-codes.html\n",
2710
2465
                        name, (ulong) offset_high, (ulong) offset,
2711
2466
                        (ulong) GetLastError());
2712
2467
 
2724
2479
        }
2725
2480
# endif /* UNIV_DO_FLUSH */
2726
2481
 
2727
 
#ifndef UNIV_HOTBACKUP
2728
2482
        os_mutex_exit(os_file_seek_mutexes[i]);
2729
 
#endif /* !UNIV_HOTBACKUP */
2730
2483
 
2731
2484
        os_mutex_enter(os_file_count_mutex);
2732
2485
        os_n_pending_writes--;
2779
2532
                        "InnoDB: Some operating system error numbers"
2780
2533
                        " are described at\n"
2781
2534
                        "InnoDB: "
2782
 
                        REFMAN "operating-system-error-codes.html\n");
 
2535
                        "http://dev.mysql.com/doc/refman/5.1/en/"
 
2536
                        "operating-system-error-codes.html\n");
2783
2537
 
2784
2538
                os_has_said_disk_full = TRUE;
2785
2539
        }
2821
2575
                        "InnoDB: Some operating system error numbers"
2822
2576
                        " are described at\n"
2823
2577
                        "InnoDB: "
2824
 
                        REFMAN "operating-system-error-codes.html\n");
 
2578
                        "http://dev.mysql.com/doc/refman/5.1/en/"
 
2579
                        "operating-system-error-codes.html\n");
2825
2580
 
2826
2581
                os_has_said_disk_full = TRUE;
2827
2582
        }
2830
2585
#endif
2831
2586
}
2832
2587
 
2833
 
/*******************************************************************//**
2834
 
Check the existence and type of the given file.
2835
 
@return TRUE if call succeeded */
 
2588
/***********************************************************************
 
2589
Check the existence and type of the given file. */
2836
2590
UNIV_INTERN
2837
2591
ibool
2838
2592
os_file_status(
2839
2593
/*===========*/
2840
 
        const char*     path,   /*!< in:        pathname of the file */
2841
 
        ibool*          exists, /*!< out: TRUE if file exists */
2842
 
        os_file_type_t* type)   /*!< out: type of the file (if it exists) */
 
2594
                                /* out: TRUE if call succeeded */
 
2595
        const char*     path,   /* in:  pathname of the file */
 
2596
        ibool*          exists, /* out: TRUE if file exists */
 
2597
        os_file_type_t* type)   /* out: type of the file (if it exists) */
2843
2598
{
2844
2599
#ifdef __WIN__
2845
2600
        int             ret;
2902
2657
#endif
2903
2658
}
2904
2659
 
2905
 
/*******************************************************************//**
2906
 
This function returns information about the specified file
2907
 
@return TRUE if stat information found */
 
2660
/***********************************************************************
 
2661
This function returns information about the specified file */
2908
2662
UNIV_INTERN
2909
2663
ibool
2910
2664
os_file_get_status(
2911
2665
/*===============*/
2912
 
        const char*     path,           /*!< in:        pathname of the file */
2913
 
        os_file_stat_t* stat_info)      /*!< information of a file in a
 
2666
                                        /* out: TRUE if stat
 
2667
                                        information found */
 
2668
        const char*     path,           /* in:  pathname of the file */
 
2669
        os_file_stat_t* stat_info)      /* information of a file in a
2914
2670
                                        directory */
2915
2671
{
2916
2672
#ifdef __WIN__
2987
2743
#  define OS_FILE_PATH_SEPARATOR        '/'
2988
2744
#endif
2989
2745
 
2990
 
/****************************************************************//**
 
2746
/********************************************************************
2991
2747
The function os_file_dirname returns a directory component of a
2992
2748
null-terminated pathname string.  In the usual case, dirname returns
2993
2749
the string up to, but not including, the final '/', and basename
3013
2769
       "/"            "/"            "/"
3014
2770
       "."            "."            "."
3015
2771
       ".."           "."            ".."
3016
 
 
3017
 
@return own: directory component of the pathname */
 
2772
*/
3018
2773
UNIV_INTERN
3019
2774
char*
3020
2775
os_file_dirname(
3021
2776
/*============*/
3022
 
        const char*     path)   /*!< in: pathname */
 
2777
                                /* out, own: directory component of the
 
2778
                                pathname */
 
2779
        const char*     path)   /* in: pathname */
3023
2780
{
3024
2781
        /* Find the offset of the last slash */
3025
2782
        const char* last_slash = strrchr(path, OS_FILE_PATH_SEPARATOR);
3042
2799
        return(mem_strdupl(path, last_slash - path));
3043
2800
}
3044
2801
 
3045
 
/****************************************************************//**
3046
 
Creates all missing subdirectories along the given path.
3047
 
@return TRUE if call succeeded FALSE otherwise */
 
2802
/********************************************************************
 
2803
Creates all missing subdirectories along the given path. */
3048
2804
UNIV_INTERN
3049
2805
ibool
3050
2806
os_file_create_subdirs_if_needed(
3051
2807
/*=============================*/
3052
 
        const char*     path)   /*!< in: path name */
 
2808
                                /* out: TRUE if call succeeded
 
2809
                                   FALSE otherwise */
 
2810
        const char*     path)   /* in: path name */
3053
2811
{
3054
2812
        char*           subdir;
3055
2813
        ibool           success, subdir_exists;
3082
2840
        return(success);
3083
2841
}
3084
2842
 
3085
 
#ifndef UNIV_HOTBACKUP
3086
 
/****************************************************************//**
3087
 
Returns a pointer to the nth slot in the aio array.
3088
 
@return pointer to slot */
 
2843
/********************************************************************
 
2844
Returns a pointer to the nth slot in the aio array. */
3089
2845
static
3090
2846
os_aio_slot_t*
3091
2847
os_aio_array_get_nth_slot(
3092
2848
/*======================*/
3093
 
        os_aio_array_t*         array,  /*!< in: aio array */
3094
 
        ulint                   index)  /*!< in: index of the slot */
 
2849
                                        /* out: pointer to slot */
 
2850
        os_aio_array_t*         array,  /* in: aio array */
 
2851
        ulint                   index)  /* in: index of the slot */
3095
2852
{
3096
2853
        ut_a(index < array->n_slots);
3097
2854
 
3098
2855
        return((array->slots) + index);
3099
2856
}
3100
2857
 
3101
 
#if defined(LINUX_NATIVE_AIO)
3102
 
/******************************************************************//**
3103
 
Creates an io_context for native linux AIO.
3104
 
@return TRUE on success. */
3105
 
static
3106
 
ibool
3107
 
os_aio_linux_create_io_ctx(
3108
 
/*=======================*/
3109
 
        ulint           max_events,     /*!< in: number of events. */
3110
 
        io_context_t*   io_ctx)         /*!< out: io_ctx to initialize. */
3111
 
{
3112
 
        int     ret;
3113
 
        ulint   retries = 0;
3114
 
 
3115
 
retry:
3116
 
        memset(io_ctx, 0x0, sizeof(*io_ctx));
3117
 
 
3118
 
        /* Initialize the io_ctx. Tell it how many pending
3119
 
        IO requests this context will handle. */
3120
 
 
3121
 
        ret = io_setup(max_events, io_ctx);
3122
 
        if (ret == 0) {
3123
 
#if defined(UNIV_AIO_DEBUG)
3124
 
                fprintf(stderr,
3125
 
                        "InnoDB: Linux native AIO:"
3126
 
                        " initialized io_ctx for segment\n");
3127
 
#endif
3128
 
                /* Success. Return now. */
3129
 
                return(TRUE);
3130
 
        }
3131
 
 
3132
 
        /* If we hit EAGAIN we'll make a few attempts before failing. */
3133
 
 
3134
 
        switch (ret) {
3135
 
        case -EAGAIN:
3136
 
                if (retries == 0) {
3137
 
                        /* First time around. */
3138
 
                        ut_print_timestamp(stderr);
3139
 
                        fprintf(stderr,
3140
 
                                "  InnoDB: Warning: io_setup() failed"
3141
 
                                " with EAGAIN. Will make %d attempts"
3142
 
                                " before giving up.\n",
3143
 
                                OS_AIO_IO_SETUP_RETRY_ATTEMPTS);
3144
 
                }
3145
 
 
3146
 
                if (retries < OS_AIO_IO_SETUP_RETRY_ATTEMPTS) {
3147
 
                        ++retries;
3148
 
                        fprintf(stderr,
3149
 
                                "InnoDB: Warning: io_setup() attempt"
3150
 
                                " %lu failed.\n",
3151
 
                                retries);
3152
 
                        os_thread_sleep(OS_AIO_IO_SETUP_RETRY_SLEEP);
3153
 
                        goto retry;
3154
 
                }
3155
 
 
3156
 
                /* Have tried enough. Better call it a day. */
3157
 
                ut_print_timestamp(stderr);
3158
 
                fprintf(stderr,
3159
 
                        "  InnoDB: Error: io_setup() failed"
3160
 
                        " with EAGAIN after %d attempts.\n",
3161
 
                        OS_AIO_IO_SETUP_RETRY_ATTEMPTS);
3162
 
                break;
3163
 
 
3164
 
        case -ENOSYS:
3165
 
                ut_print_timestamp(stderr);
3166
 
                fprintf(stderr,
3167
 
                        "  InnoDB: Error: Linux Native AIO interface"
3168
 
                        " is not supported on this platform. Please"
3169
 
                        " check your OS documentation and install"
3170
 
                        " appropriate binary of InnoDB.\n");
3171
 
 
3172
 
                break;
3173
 
 
3174
 
        default:
3175
 
                ut_print_timestamp(stderr);
3176
 
                fprintf(stderr,
3177
 
                        "  InnoDB: Error: Linux Native AIO setup"
3178
 
                        " returned following error[%d]\n", -ret);
3179
 
                break;
3180
 
        }
3181
 
 
3182
 
        fprintf(stderr,
3183
 
                "InnoDB: You can disable Linux Native AIO by"
3184
 
                " setting innodb_native_aio = off in my.cnf\n");
3185
 
        return(FALSE);
3186
 
}
3187
 
#endif /* LINUX_NATIVE_AIO */
3188
 
 
3189
 
/******************************************************************//**
3190
 
Creates an aio wait array. Note that we return NULL in case of failure.
3191
 
We don't care about freeing memory here because we assume that a
3192
 
failure will result in server refusing to start up.
3193
 
@return own: aio array, NULL on failure */
 
2858
/****************************************************************************
 
2859
Creates an aio wait array. */
3194
2860
static
3195
2861
os_aio_array_t*
3196
2862
os_aio_array_create(
3197
2863
/*================*/
3198
 
        ulint   n,              /*!< in: maximum number of pending aio
3199
 
                                operations allowed; n must be
3200
 
                                divisible by n_segments */
3201
 
        ulint   n_segments)     /*!< in: number of segments in the aio array */
 
2864
                                /* out, own: aio array */
 
2865
        ulint   n,              /* in: maximum number of pending aio operations
 
2866
                                allowed; n must be divisible by n_segments */
 
2867
        ulint   n_segments)     /* in: number of segments in the aio array */
3202
2868
{
3203
2869
        os_aio_array_t* array;
3204
2870
        ulint           i;
3205
2871
        os_aio_slot_t*  slot;
3206
2872
#ifdef WIN_ASYNC_IO
3207
2873
        OVERLAPPED*     over;
3208
 
#elif defined(LINUX_NATIVE_AIO)
3209
 
        struct io_event*        io_event = NULL;
3210
2874
#endif
3211
2875
        ut_a(n > 0);
3212
2876
        ut_a(n_segments > 0);
3213
2877
 
3214
2878
        array = ut_malloc(sizeof(os_aio_array_t));
3215
2879
 
3216
 
        array->mutex            = os_mutex_create();
 
2880
        array->mutex            = os_mutex_create(NULL);
3217
2881
        array->not_full         = os_event_create(NULL);
3218
2882
        array->is_empty         = os_event_create(NULL);
3219
2883
 
3222
2886
        array->n_slots          = n;
3223
2887
        array->n_segments       = n_segments;
3224
2888
        array->n_reserved       = 0;
3225
 
        array->cur_seg          = 0;
3226
2889
        array->slots            = ut_malloc(n * sizeof(os_aio_slot_t));
3227
2890
#ifdef __WIN__
3228
 
        array->handles          = ut_malloc(n * sizeof(HANDLE));
 
2891
        array->native_events    = ut_malloc(n * sizeof(os_native_event_t));
3229
2892
#endif
3230
 
 
3231
 
#if defined(LINUX_NATIVE_AIO)
3232
 
        array->aio_ctx = NULL;
3233
 
        array->aio_events = NULL;
3234
 
 
3235
 
        /* If we are not using native aio interface then skip this
3236
 
        part of initialization. */
3237
 
        if (!srv_use_native_aio) {
3238
 
                goto skip_native_aio;
3239
 
        }
3240
 
 
3241
 
        /* Initialize the io_context array. One io_context
3242
 
        per segment in the array. */
3243
 
 
3244
 
        array->aio_ctx = ut_malloc(n_segments *
3245
 
                                   sizeof(*array->aio_ctx));
3246
 
        for (i = 0; i < n_segments; ++i) {
3247
 
                if (!os_aio_linux_create_io_ctx(n/n_segments,
3248
 
                                           &array->aio_ctx[i])) {
3249
 
                        /* If something bad happened during aio setup
3250
 
                        we should call it a day and return right away.
3251
 
                        We don't care about any leaks because a failure
3252
 
                        to initialize the io subsystem means that the
3253
 
                        server (or atleast the innodb storage engine)
3254
 
                        is not going to startup. */
3255
 
                        return(NULL);
3256
 
                }
3257
 
        }
3258
 
 
3259
 
        /* Initialize the event array. One event per slot. */
3260
 
        io_event = ut_malloc(n * sizeof(*io_event));
3261
 
        memset(io_event, 0x0, sizeof(*io_event) * n);
3262
 
        array->aio_events = io_event;
3263
 
 
3264
 
skip_native_aio:
3265
 
#endif /* LINUX_NATIVE_AIO */
3266
2893
        for (i = 0; i < n; i++) {
3267
2894
                slot = os_aio_array_get_nth_slot(array, i);
3268
2895
 
3269
2896
                slot->pos = i;
3270
2897
                slot->reserved = FALSE;
3271
2898
#ifdef WIN_ASYNC_IO
3272
 
                slot->handle = CreateEvent(NULL,TRUE, FALSE, NULL);
 
2899
                slot->event = os_event_create(NULL);
3273
2900
 
3274
2901
                over = &(slot->control);
3275
2902
 
3276
 
                over->hEvent = slot->handle;
3277
 
 
3278
 
                *((array->handles) + i) = over->hEvent;
3279
 
 
3280
 
#elif defined(LINUX_NATIVE_AIO)
3281
 
 
3282
 
                memset(&slot->control, 0x0, sizeof(slot->control));
3283
 
                slot->n_bytes = 0;
3284
 
                slot->ret = 0;
 
2903
                over->hEvent = slot->event->handle;
 
2904
 
 
2905
                *((array->native_events) + i) = over->hEvent;
3285
2906
#endif
3286
2907
        }
3287
2908
 
3288
2909
        return(array);
3289
2910
}
3290
2911
 
3291
 
/************************************************************************//**
3292
 
Frees an aio wait array. */
3293
 
static
 
2912
/****************************************************************************
 
2913
Initializes the asynchronous io system. Calls also os_io_init_simple.
 
2914
Creates a separate aio array for
 
2915
non-ibuf read and write, a third aio array for the ibuf i/o, with just one
 
2916
segment, two aio arrays for log reads and writes with one segment, and a
 
2917
synchronous aio array of the specified size. The combined number of segments
 
2918
in the three first aio arrays is the parameter n_segments given to the
 
2919
function. The caller must create an i/o handler thread for each segment in
 
2920
the four first arrays, but not for the sync aio array. */
 
2921
UNIV_INTERN
3294
2922
void
3295
 
os_aio_array_free(
3296
 
/*==============*/
3297
 
        os_aio_array_t* array)  /*!< in, own: array to free */
3298
 
{
3299
 
#ifdef WIN_ASYNC_IO
3300
 
        ulint   i;
3301
 
 
3302
 
        for (i = 0; i < array->n_slots; i++) {
3303
 
                os_aio_slot_t*  slot = os_aio_array_get_nth_slot(array, i);
3304
 
                CloseHandle(slot->handle);
3305
 
        }
3306
 
#endif /* WIN_ASYNC_IO */
3307
 
 
3308
 
#ifdef __WIN__
3309
 
        ut_free(array->handles);
3310
 
#endif /* __WIN__ */
3311
 
        os_mutex_free(array->mutex);
3312
 
        os_event_free(array->not_full);
3313
 
        os_event_free(array->is_empty);
3314
 
 
3315
 
#if defined(LINUX_NATIVE_AIO)
3316
 
        if (srv_use_native_aio) {
3317
 
                ut_free(array->aio_events);
3318
 
                ut_free(array->aio_ctx);
3319
 
        }
3320
 
#endif /* LINUX_NATIVE_AIO */
3321
 
 
3322
 
        ut_free(array->slots);
3323
 
        ut_free(array);
3324
 
}
3325
 
 
3326
 
/***********************************************************************
3327
 
Initializes the asynchronous io system. Creates one array each for ibuf
3328
 
and log i/o. Also creates one array each for read and write where each
3329
 
array is divided logically into n_read_segs and n_write_segs
3330
 
respectively. The caller must create an i/o handler thread for each
3331
 
segment in these arrays. This function also creates the sync array.
3332
 
No i/o handler thread needs to be created for that */
3333
 
UNIV_INTERN
3334
 
ibool
3335
2923
os_aio_init(
3336
2924
/*========*/
3337
 
        ulint   n_per_seg,      /*<! in: maximum number of pending aio
3338
 
                                operations allowed per segment */
3339
 
        ulint   n_read_segs,    /*<! in: number of reader threads */
3340
 
        ulint   n_write_segs,   /*<! in: number of writer threads */
3341
 
        ulint   n_slots_sync)   /*<! in: number of slots in the sync aio
3342
 
                                array */
 
2925
        ulint   n,              /* in: maximum number of pending aio operations
 
2926
                                allowed; n must be divisible by n_segments */
 
2927
        ulint   n_segments,     /* in: combined number of segments in the four
 
2928
                                first aio arrays; must be >= 4 */
 
2929
        ulint   n_slots_sync)   /* in: number of slots in the sync aio array */
3343
2930
{
 
2931
        ulint   n_read_segs;
 
2932
        ulint   n_write_segs;
 
2933
        ulint   n_per_seg;
3344
2934
        ulint   i;
3345
 
        ulint   n_segments = 2 + n_read_segs + n_write_segs;
3346
2935
 
 
2936
        ut_ad(n % n_segments == 0);
3347
2937
        ut_ad(n_segments >= 4);
3348
2938
 
3349
2939
        os_io_init_simple();
3352
2942
                srv_set_io_thread_op_info(i, "not started yet");
3353
2943
        }
3354
2944
 
 
2945
        n_per_seg = n / n_segments;
 
2946
        n_write_segs = (n_segments - 2) / 2;
 
2947
        n_read_segs = n_segments - 2 - n_write_segs;
3355
2948
 
3356
2949
        /* fprintf(stderr, "Array n per seg %lu\n", n_per_seg); */
3357
2950
 
3358
2951
        os_aio_ibuf_array = os_aio_array_create(n_per_seg, 1);
3359
 
        if (os_aio_ibuf_array == NULL) {
3360
 
                goto err_exit;
3361
 
        }
3362
2952
 
3363
2953
        srv_io_thread_function[0] = "insert buffer thread";
3364
2954
 
3365
2955
        os_aio_log_array = os_aio_array_create(n_per_seg, 1);
3366
 
        if (os_aio_log_array == NULL) {
3367
 
                goto err_exit;
3368
 
        }
3369
2956
 
3370
2957
        srv_io_thread_function[1] = "log thread";
3371
2958
 
3372
2959
        os_aio_read_array = os_aio_array_create(n_read_segs * n_per_seg,
3373
2960
                                                n_read_segs);
3374
 
        if (os_aio_read_array == NULL) {
3375
 
                goto err_exit;
3376
 
        }
3377
 
 
3378
2961
        for (i = 2; i < 2 + n_read_segs; i++) {
3379
2962
                ut_a(i < SRV_MAX_N_IO_THREADS);
3380
2963
                srv_io_thread_function[i] = "read thread";
3382
2965
 
3383
2966
        os_aio_write_array = os_aio_array_create(n_write_segs * n_per_seg,
3384
2967
                                                 n_write_segs);
3385
 
        if (os_aio_write_array == NULL) {
3386
 
                goto err_exit;
3387
 
        }
3388
 
 
3389
2968
        for (i = 2 + n_read_segs; i < n_segments; i++) {
3390
2969
                ut_a(i < SRV_MAX_N_IO_THREADS);
3391
2970
                srv_io_thread_function[i] = "write thread";
3392
2971
        }
3393
2972
 
3394
2973
        os_aio_sync_array = os_aio_array_create(n_slots_sync, 1);
3395
 
        if (os_aio_sync_array == NULL) {
3396
 
                goto err_exit;
3397
 
        }
3398
 
 
3399
2974
 
3400
2975
        os_aio_n_segments = n_segments;
3401
2976
 
3409
2984
 
3410
2985
        os_last_printout = time(NULL);
3411
2986
 
3412
 
        return(TRUE);
3413
 
 
3414
 
err_exit:
3415
 
        return(FALSE);
3416
 
 
3417
 
}
3418
 
 
3419
 
/***********************************************************************
3420
 
Frees the asynchronous io system. */
3421
 
UNIV_INTERN
3422
 
void
3423
 
os_aio_free(void)
3424
 
/*=============*/
3425
 
{
3426
 
        ulint   i;
3427
 
 
3428
 
        os_aio_array_free(os_aio_ibuf_array);
3429
 
        os_aio_ibuf_array = NULL;
3430
 
        os_aio_array_free(os_aio_log_array);
3431
 
        os_aio_log_array = NULL;
3432
 
        os_aio_array_free(os_aio_read_array);
3433
 
        os_aio_read_array = NULL;
3434
 
        os_aio_array_free(os_aio_write_array);
3435
 
        os_aio_write_array = NULL;
3436
 
        os_aio_array_free(os_aio_sync_array);
3437
 
        os_aio_sync_array = NULL;
3438
 
 
3439
 
        for (i = 0; i < os_aio_n_segments; i++) {
3440
 
                os_event_free(os_aio_segment_wait_events[i]);
3441
 
        }
3442
 
 
3443
 
        ut_free(os_aio_segment_wait_events);
3444
 
        os_aio_segment_wait_events = 0;
3445
 
        os_aio_n_segments = 0;
3446
2987
}
3447
2988
 
3448
2989
#ifdef WIN_ASYNC_IO
3449
 
/************************************************************************//**
 
2990
/****************************************************************************
3450
2991
Wakes up all async i/o threads in the array in Windows async i/o at
3451
2992
shutdown. */
3452
2993
static
3453
2994
void
3454
2995
os_aio_array_wake_win_aio_at_shutdown(
3455
2996
/*==================================*/
3456
 
        os_aio_array_t* array)  /*!< in: aio array */
 
2997
        os_aio_array_t* array)  /* in: aio array */
3457
2998
{
3458
2999
        ulint   i;
3459
3000
 
3460
3001
        for (i = 0; i < array->n_slots; i++) {
3461
3002
 
3462
 
                SetEvent((array->slots + i)->handle);
 
3003
                os_event_set((array->slots + i)->event);
3463
3004
        }
3464
3005
}
3465
3006
#endif
3466
3007
 
3467
 
/************************************************************************//**
 
3008
/****************************************************************************
3468
3009
Wakes up all async i/o threads so that they know to exit themselves in
3469
3010
shutdown. */
3470
3011
UNIV_INTERN
3480
3021
        os_aio_array_wake_win_aio_at_shutdown(os_aio_write_array);
3481
3022
        os_aio_array_wake_win_aio_at_shutdown(os_aio_ibuf_array);
3482
3023
        os_aio_array_wake_win_aio_at_shutdown(os_aio_log_array);
3483
 
 
3484
 
#elif defined(LINUX_NATIVE_AIO)
3485
 
 
3486
 
        /* When using native AIO interface the io helper threads
3487
 
        wait on io_getevents with a timeout value of 500ms. At
3488
 
        each wake up these threads check the server status.
3489
 
        No need to do anything to wake them up. */
3490
 
 
3491
 
        if (srv_use_native_aio) {
3492
 
                return;
3493
 
        }
3494
 
        /* Fall through to simulated AIO handler wakeup if we are
3495
 
        not using native AIO. */
3496
3024
#endif
3497
3025
        /* This loop wakes up all simulated ai/o threads */
3498
3026
 
3502
3030
        }
3503
3031
}
3504
3032
 
3505
 
/************************************************************************//**
 
3033
/****************************************************************************
3506
3034
Waits until there are no pending writes in os_aio_write_array. There can
3507
3035
be other, synchronous, pending writes. */
3508
3036
UNIV_INTERN
3513
3041
        os_event_wait(os_aio_write_array->is_empty);
3514
3042
}
3515
3043
 
3516
 
/**********************************************************************//**
3517
 
Calculates segment number for a slot.
3518
 
@return segment number (which is the number used by, for example,
3519
 
i/o-handler threads) */
 
3044
/**************************************************************************
 
3045
Calculates segment number for a slot. */
3520
3046
static
3521
3047
ulint
3522
3048
os_aio_get_segment_no_from_slot(
3523
3049
/*============================*/
3524
 
        os_aio_array_t* array,  /*!< in: aio wait array */
3525
 
        os_aio_slot_t*  slot)   /*!< in: slot in this array */
 
3050
                                /* out: segment number (which is the number
 
3051
                                used by, for example, i/o-handler threads) */
 
3052
        os_aio_array_t* array,  /* in: aio wait array */
 
3053
        os_aio_slot_t*  slot)   /* in: slot in this array */
3526
3054
{
3527
3055
        ulint   segment;
3528
3056
        ulint   seg_len;
3550
3078
        return(segment);
3551
3079
}
3552
3080
 
3553
 
/**********************************************************************//**
3554
 
Calculates local segment number and aio array from global segment number.
3555
 
@return local segment number within the aio array */
 
3081
/**************************************************************************
 
3082
Calculates local segment number and aio array from global segment number. */
3556
3083
static
3557
3084
ulint
3558
3085
os_aio_get_array_and_local_segment(
3559
3086
/*===============================*/
3560
 
        os_aio_array_t** array,         /*!< out: aio wait array */
3561
 
        ulint            global_segment)/*!< in: global segment number */
 
3087
                                        /* out: local segment number within
 
3088
                                        the aio array */
 
3089
        os_aio_array_t** array,         /* out: aio wait array */
 
3090
        ulint            global_segment)/* in: global segment number */
3562
3091
{
3563
3092
        ulint   segment;
3564
3093
 
3585
3114
        return(segment);
3586
3115
}
3587
3116
 
3588
 
/*******************************************************************//**
 
3117
/***********************************************************************
3589
3118
Requests for a slot in the aio array. If no slot is available, waits until
3590
 
not_full-event becomes signaled.
3591
 
@return pointer to slot */
 
3119
not_full-event becomes signaled. */
3592
3120
static
3593
3121
os_aio_slot_t*
3594
3122
os_aio_array_reserve_slot(
3595
3123
/*======================*/
3596
 
        ulint           type,   /*!< in: OS_FILE_READ or OS_FILE_WRITE */
3597
 
        os_aio_array_t* array,  /*!< in: aio array */
3598
 
        fil_node_t*     message1,/*!< in: message to be passed along with
3599
 
                                the aio operation */
3600
 
        void*           message2,/*!< in: message to be passed along with
3601
 
                                the aio operation */
3602
 
        os_file_t       file,   /*!< in: file handle */
3603
 
        const char*     name,   /*!< in: name of the file or path as a
 
3124
                                /* out: pointer to slot */
 
3125
        ulint           type,   /* in: OS_FILE_READ or OS_FILE_WRITE */
 
3126
        os_aio_array_t* array,  /* in: aio array */
 
3127
        fil_node_t*     message1,/* in: message to be passed along with
 
3128
                                the aio operation */
 
3129
        void*           message2,/* in: message to be passed along with
 
3130
                                the aio operation */
 
3131
        os_file_t       file,   /* in: file handle */
 
3132
        const char*     name,   /* in: name of the file or path as a
3604
3133
                                null-terminated string */
3605
 
        void*           buf,    /*!< in: buffer where to read or from which
 
3134
        void*           buf,    /* in: buffer where to read or from which
3606
3135
                                to write */
3607
 
        ulint           offset, /*!< in: least significant 32 bits of file
3608
 
                                offset */
3609
 
        ulint           offset_high, /*!< in: most significant 32 bits of
3610
 
                                offset */
3611
 
        ulint           len)    /*!< in: length of the block to read or write */
 
3136
        ulint           offset, /* in: least significant 32 bits of file
 
3137
                                offset */
 
3138
        ulint           offset_high, /* in: most significant 32 bits of
 
3139
                                offset */
 
3140
        ulint           len)    /* in: length of the block to read or write */
3612
3141
{
3613
 
        os_aio_slot_t*  slot = NULL;
 
3142
        os_aio_slot_t*  slot;
3614
3143
#ifdef WIN_ASYNC_IO
3615
3144
        OVERLAPPED*     control;
3616
 
 
3617
 
#elif defined(LINUX_NATIVE_AIO)
3618
 
 
3619
 
        struct iocb*    iocb;
3620
 
        off_t           aio_offset;
3621
 
 
3622
3145
#endif
3623
3146
        ulint           i;
3624
 
        ulint           counter;
3625
 
        ulint           slots_per_seg;
3626
 
        ulint           local_seg;
3627
 
 
3628
 
        /* No need of a mutex. Only reading constant fields */
3629
 
        slots_per_seg = array->n_slots / array->n_segments;
3630
 
 
3631
 
        /* We attempt to keep adjacent blocks in the same local
3632
 
        segment. This can help in merging IO requests when we are
3633
 
        doing simulated AIO */
3634
 
        local_seg = (offset >> (UNIV_PAGE_SIZE_SHIFT + 6))
3635
 
                    % array->n_segments;
3636
 
 
3637
3147
loop:
3638
3148
        os_mutex_enter(array->mutex);
3639
3149
 
3640
3150
        if (array->n_reserved == array->n_slots) {
3641
3151
                os_mutex_exit(array->mutex);
3642
3152
 
3643
 
                if (!srv_use_native_aio) {
 
3153
                if (!os_aio_use_native_aio) {
3644
3154
                        /* If the handler threads are suspended, wake them
3645
3155
                        so that we get more slots */
3646
3156
 
3652
3162
                goto loop;
3653
3163
        }
3654
3164
 
3655
 
        /* We start our search for an available slot from our preferred
3656
 
        local segment and do a full scan of the array. We are
3657
 
        guaranteed to find a slot in full scan. */
3658
 
        for (i = local_seg * slots_per_seg, counter = 0;
3659
 
             counter < array->n_slots; i++, counter++) {
3660
 
 
3661
 
                i %= array->n_slots;
 
3165
        for (i = 0;; i++) {
3662
3166
                slot = os_aio_array_get_nth_slot(array, i);
3663
3167
 
3664
3168
                if (slot->reserved == FALSE) {
3665
 
                        goto found;
 
3169
                        break;
3666
3170
                }
3667
3171
        }
3668
3172
 
3669
 
        /* We MUST always be able to get hold of a reserved slot. */
3670
 
        ut_error;
3671
 
 
3672
 
found:
3673
 
        ut_a(slot->reserved == FALSE);
3674
3173
        array->n_reserved++;
3675
3174
 
3676
3175
        if (array->n_reserved == 1) {
3698
3197
        control = &(slot->control);
3699
3198
        control->Offset = (DWORD)offset;
3700
3199
        control->OffsetHigh = (DWORD)offset_high;
3701
 
        ResetEvent(slot->handle);
3702
 
 
3703
 
#elif defined(LINUX_NATIVE_AIO)
3704
 
 
3705
 
        /* If we are not using native AIO skip this part. */
3706
 
        if (!srv_use_native_aio) {
3707
 
                goto skip_native_aio;
3708
 
        }
3709
 
 
3710
 
        /* Check if we are dealing with 64 bit arch.
3711
 
        If not then make sure that offset fits in 32 bits. */
3712
 
        if (sizeof(aio_offset) == 8) {
3713
 
                aio_offset = offset_high;
3714
 
                aio_offset <<= 32;
3715
 
                aio_offset += offset;
3716
 
        } else {
3717
 
                ut_a(offset_high == 0);
3718
 
                aio_offset = offset;
3719
 
        }
3720
 
 
3721
 
        iocb = &slot->control;
3722
 
 
3723
 
        if (type == OS_FILE_READ) {
3724
 
                io_prep_pread(iocb, file, buf, len, aio_offset);
3725
 
        } else {
3726
 
                ut_a(type == OS_FILE_WRITE);
3727
 
                io_prep_pwrite(iocb, file, buf, len, aio_offset);
3728
 
        }
3729
 
 
3730
 
        iocb->data = (void*)slot;
3731
 
        slot->n_bytes = 0;
3732
 
        slot->ret = 0;
3733
 
        /*fprintf(stderr, "Filled up Linux native iocb.\n");*/
3734
 
        
3735
 
 
3736
 
skip_native_aio:
3737
 
#endif /* LINUX_NATIVE_AIO */
 
3200
        os_event_reset(slot->event);
 
3201
#endif
 
3202
 
3738
3203
        os_mutex_exit(array->mutex);
3739
3204
 
3740
3205
        return(slot);
3741
3206
}
3742
3207
 
3743
 
/*******************************************************************//**
 
3208
/***********************************************************************
3744
3209
Frees a slot in the aio array. */
3745
3210
static
3746
3211
void
3747
3212
os_aio_array_free_slot(
3748
3213
/*===================*/
3749
 
        os_aio_array_t* array,  /*!< in: aio array */
3750
 
        os_aio_slot_t*  slot)   /*!< in: pointer to slot */
 
3214
        os_aio_array_t* array,  /* in: aio array */
 
3215
        os_aio_slot_t*  slot)   /* in: pointer to slot */
3751
3216
{
3752
3217
        ut_ad(array);
3753
3218
        ut_ad(slot);
3769
3234
        }
3770
3235
 
3771
3236
#ifdef WIN_ASYNC_IO
3772
 
 
3773
 
        ResetEvent(slot->handle);
3774
 
 
3775
 
#elif defined(LINUX_NATIVE_AIO)
3776
 
 
3777
 
        if (srv_use_native_aio) {
3778
 
                memset(&slot->control, 0x0, sizeof(slot->control));
3779
 
                slot->n_bytes = 0;
3780
 
                slot->ret = 0;
3781
 
                /*fprintf(stderr, "Freed up Linux native slot.\n");*/
3782
 
        } else {
3783
 
                /* These fields should not be used if we are not
3784
 
                using native AIO. */
3785
 
                ut_ad(slot->n_bytes == 0);
3786
 
                ut_ad(slot->ret == 0);
3787
 
        }
3788
 
 
 
3237
        os_event_reset(slot->event);
3789
3238
#endif
3790
3239
        os_mutex_exit(array->mutex);
3791
3240
}
3792
3241
 
3793
 
/**********************************************************************//**
 
3242
/**************************************************************************
3794
3243
Wakes up a simulated aio i/o-handler thread if it has something to do. */
3795
3244
static
3796
3245
void
3797
3246
os_aio_simulated_wake_handler_thread(
3798
3247
/*=================================*/
3799
 
        ulint   global_segment) /*!< in: the number of the segment in the aio
 
3248
        ulint   global_segment) /* in: the number of the segment in the aio
3800
3249
                                arrays */
3801
3250
{
3802
3251
        os_aio_array_t* array;
3805
3254
        ulint           n;
3806
3255
        ulint           i;
3807
3256
 
3808
 
        ut_ad(!srv_use_native_aio);
 
3257
        ut_ad(!os_aio_use_native_aio);
3809
3258
 
3810
3259
        segment = os_aio_get_array_and_local_segment(&array, global_segment);
3811
3260
 
3832
3281
        }
3833
3282
}
3834
3283
 
3835
 
/**********************************************************************//**
 
3284
/**************************************************************************
3836
3285
Wakes up simulated aio i/o-handler threads if they have something to do. */
3837
3286
UNIV_INTERN
3838
3287
void
3841
3290
{
3842
3291
        ulint   i;
3843
3292
 
3844
 
        if (srv_use_native_aio) {
 
3293
        if (os_aio_use_native_aio) {
3845
3294
                /* We do not use simulated aio: do nothing */
3846
3295
 
3847
3296
                return;
3854
3303
        }
3855
3304
}
3856
3305
 
3857
 
/**********************************************************************//**
 
3306
/**************************************************************************
3858
3307
This function can be called if one wants to post a batch of reads and
3859
3308
prefers an i/o-handler thread to handle them all at once later. You must
3860
3309
call os_aio_simulated_wake_handler_threads later to ensure the threads
3864
3313
os_aio_simulated_put_read_threads_to_sleep(void)
3865
3314
/*============================================*/
3866
3315
{
3867
 
 
3868
 
/* The idea of putting background IO threads to sleep is only for
3869
 
Windows when using simulated AIO. Windows XP seems to schedule
3870
 
background threads too eagerly to allow for coalescing during
3871
 
readahead requests. */
3872
 
#ifdef __WIN__
3873
3316
        os_aio_array_t* array;
3874
3317
        ulint           g;
3875
3318
 
3876
 
        if (srv_use_native_aio) {
3877
 
                /* We do not use simulated aio: do nothing */
3878
 
 
3879
 
                return;
3880
 
        }
3881
 
 
3882
3319
        os_aio_recommend_sleep_for_read_threads = TRUE;
3883
3320
 
3884
3321
        for (g = 0; g < os_aio_n_segments; g++) {
3889
3326
                        os_event_reset(os_aio_segment_wait_events[g]);
3890
3327
                }
3891
3328
        }
3892
 
#endif /* __WIN__ */
3893
 
}
3894
 
 
3895
 
#if defined(LINUX_NATIVE_AIO)
3896
 
/*******************************************************************//**
3897
 
Dispatch an AIO request to the kernel.
3898
 
@return TRUE on success. */
3899
 
static
3900
 
ibool
3901
 
os_aio_linux_dispatch(
3902
 
/*==================*/
3903
 
        os_aio_array_t* array,  /*!< in: io request array. */
3904
 
        os_aio_slot_t*  slot)   /*!< in: an already reserved slot. */
3905
 
{
3906
 
        int             ret;
3907
 
        ulint           io_ctx_index;
3908
 
        struct iocb*    iocb;
3909
 
 
3910
 
        ut_ad(slot != NULL);
3911
 
        ut_ad(array);
3912
 
 
3913
 
        ut_a(slot->reserved);
3914
 
 
3915
 
        /* Find out what we are going to work with.
3916
 
        The iocb struct is directly in the slot.
3917
 
        The io_context is one per segment. */
3918
 
 
3919
 
        iocb = &slot->control;
3920
 
        io_ctx_index = (slot->pos * array->n_segments) / array->n_slots;
3921
 
 
3922
 
        ret = io_submit(array->aio_ctx[io_ctx_index], 1, &iocb);
3923
 
 
3924
 
#if defined(UNIV_AIO_DEBUG)
3925
 
        fprintf(stderr,
3926
 
                "io_submit[%c] ret[%d]: slot[%p] ctx[%p] seg[%lu]\n",
3927
 
                (slot->type == OS_FILE_WRITE) ? 'w' : 'r', ret, slot,
3928
 
                array->aio_ctx[io_ctx_index], (ulong)io_ctx_index);
3929
 
#endif
3930
 
 
3931
 
        /* io_submit returns number of successfully
3932
 
        queued requests or -errno. */
3933
 
        if (UNIV_UNLIKELY(ret != 1)) {
3934
 
                errno = -ret;
3935
 
                return(FALSE);
3936
 
        }
3937
 
 
3938
 
        return(TRUE);
3939
 
}
3940
 
#endif /* LINUX_NATIVE_AIO */
3941
 
 
3942
 
 
3943
 
/*******************************************************************//**
3944
 
NOTE! Use the corresponding macro os_aio(), not directly this function!
3945
 
Requests an asynchronous i/o operation.
3946
 
@return TRUE if request was queued successfully, FALSE if fail */
 
3329
}
 
3330
 
 
3331
/***********************************************************************
 
3332
Requests an asynchronous i/o operation. */
3947
3333
UNIV_INTERN
3948
3334
ibool
3949
 
os_aio_func(
3950
 
/*========*/
3951
 
        ulint           type,   /*!< in: OS_FILE_READ or OS_FILE_WRITE */
3952
 
        ulint           mode,   /*!< in: OS_AIO_NORMAL, ..., possibly ORed
 
3335
os_aio(
 
3336
/*===*/
 
3337
                                /* out: TRUE if request was queued
 
3338
                                successfully, FALSE if fail */
 
3339
        ulint           type,   /* in: OS_FILE_READ or OS_FILE_WRITE */
 
3340
        ulint           mode,   /* in: OS_AIO_NORMAL, ..., possibly ORed
3953
3341
                                to OS_AIO_SIMULATED_WAKE_LATER: the
3954
3342
                                last flag advises this function not to wake
3955
3343
                                i/o-handler threads, but the caller will
3962
3350
                                because i/os are not actually handled until
3963
3351
                                all have been posted: use with great
3964
3352
                                caution! */
3965
 
        const char*     name,   /*!< in: name of the file or path as a
 
3353
        const char*     name,   /* in: name of the file or path as a
3966
3354
                                null-terminated string */
3967
 
        os_file_t       file,   /*!< in: handle to a file */
3968
 
        void*           buf,    /*!< in: buffer where to read or from which
 
3355
        os_file_t       file,   /* in: handle to a file */
 
3356
        void*           buf,    /* in: buffer where to read or from which
3969
3357
                                to write */
3970
 
        ulint           offset, /*!< in: least significant 32 bits of file
 
3358
        ulint           offset, /* in: least significant 32 bits of file
3971
3359
                                offset where to read or write */
3972
 
        ulint           offset_high, /*!< in: most significant 32 bits of
 
3360
        ulint           offset_high, /* in: most significant 32 bits of
3973
3361
                                offset */
3974
 
        ulint           n,      /*!< in: number of bytes to read or write */
3975
 
        fil_node_t*     message1,/*!< in: message for the aio handler
3976
 
                                (can be used to identify a completed
3977
 
                                aio operation); ignored if mode is
3978
 
                                OS_AIO_SYNC */
3979
 
        void*           message2)/*!< in: message for the aio handler
3980
 
                                (can be used to identify a completed
3981
 
                                aio operation); ignored if mode is
3982
 
                                OS_AIO_SYNC */
 
3362
        ulint           n,      /* in: number of bytes to read or write */
 
3363
        fil_node_t*     message1,/* in: messages for the aio handler (these
 
3364
                                can be used to identify a completed aio
 
3365
                                operation); if mode is OS_AIO_SYNC, these
 
3366
                                are ignored */
 
3367
        void*           message2)
3983
3368
{
3984
3369
        os_aio_array_t* array;
3985
3370
        os_aio_slot_t*  slot;
3990
3375
        struct fil_node_struct * dummy_mess1;
3991
3376
        void*           dummy_mess2;
3992
3377
        ulint           dummy_type;
3993
 
#endif /* WIN_ASYNC_IO */
3994
 
#if defined LINUX_NATIVE_AIO || defined WIN_ASYNC_IO
 
3378
#endif
 
3379
        ulint           err             = 0;
3995
3380
        ibool           retry;
3996
 
#endif
3997
3381
        ulint           wake_later;
3998
3382
 
3999
3383
        ut_ad(file);
4008
3392
 
4009
3393
        if (mode == OS_AIO_SYNC
4010
3394
#ifdef WIN_ASYNC_IO
4011
 
            && !srv_use_native_aio
4012
 
#endif /* WIN_ASYNC_IO */
 
3395
            && !os_aio_use_native_aio
 
3396
#endif
4013
3397
            ) {
4014
3398
                /* This is actually an ordinary synchronous read or write:
4015
3399
                no need to use an i/o-handler thread. NOTE that if we use
4028
3412
                return(os_file_write(name, file, buf, offset, offset_high, n));
4029
3413
        }
4030
3414
 
4031
 
#if defined LINUX_NATIVE_AIO || defined WIN_ASYNC_IO
4032
3415
try_again:
4033
 
#endif
4034
3416
        if (mode == OS_AIO_NORMAL) {
4035
3417
                if (type == OS_FILE_READ) {
4036
3418
                        array = os_aio_read_array;
4050
3432
                array = os_aio_log_array;
4051
3433
        } else if (mode == OS_AIO_SYNC) {
4052
3434
                array = os_aio_sync_array;
4053
 
 
4054
 
#if defined(LINUX_NATIVE_AIO)
4055
 
                /* In Linux native AIO we don't use sync IO array. */
4056
 
                ut_a(!srv_use_native_aio);
4057
 
#endif /* LINUX_NATIVE_AIO */
4058
3435
        } else {
4059
3436
                array = NULL; /* Eliminate compiler warning */
4060
3437
                ut_error;
4063
3440
        slot = os_aio_array_reserve_slot(type, array, message1, message2, file,
4064
3441
                                         name, buf, offset, offset_high, n);
4065
3442
        if (type == OS_FILE_READ) {
4066
 
                if (srv_use_native_aio) {
 
3443
                if (os_aio_use_native_aio) {
 
3444
#ifdef WIN_ASYNC_IO
4067
3445
                        os_n_file_reads++;
4068
 
                        os_bytes_read_since_printout += n;
4069
 
#ifdef WIN_ASYNC_IO
 
3446
                        os_bytes_read_since_printout += len;
 
3447
 
4070
3448
                        ret = ReadFile(file, buf, (DWORD)n, &len,
4071
3449
                                       &(slot->control));
4072
 
 
4073
 
#elif defined(LINUX_NATIVE_AIO)
4074
 
                        if (!os_aio_linux_dispatch(array, slot)) {
4075
 
                                goto err_exit;
4076
 
                        }
4077
3450
#endif
4078
3451
                } else {
4079
3452
                        if (!wake_later) {
4083
3456
                        }
4084
3457
                }
4085
3458
        } else if (type == OS_FILE_WRITE) {
4086
 
                if (srv_use_native_aio) {
 
3459
                if (os_aio_use_native_aio) {
 
3460
#ifdef WIN_ASYNC_IO
4087
3461
                        os_n_file_writes++;
4088
 
#ifdef WIN_ASYNC_IO
4089
3462
                        ret = WriteFile(file, buf, (DWORD)n, &len,
4090
3463
                                        &(slot->control));
4091
 
 
4092
 
#elif defined(LINUX_NATIVE_AIO)
4093
 
                        if (!os_aio_linux_dispatch(array, slot)) {
4094
 
                                goto err_exit;
4095
 
                        }
4096
3464
#endif
4097
3465
                } else {
4098
3466
                        if (!wake_later) {
4106
3474
        }
4107
3475
 
4108
3476
#ifdef WIN_ASYNC_IO
4109
 
        if (srv_use_native_aio) {
 
3477
        if (os_aio_use_native_aio) {
4110
3478
                if ((ret && len == n)
4111
3479
                    || (!ret && GetLastError() == ERROR_IO_PENDING)) {
4112
3480
                        /* aio was queued successfully! */
4129
3497
                        return(TRUE);
4130
3498
                }
4131
3499
 
4132
 
                goto err_exit;
4133
 
        }
4134
 
#endif /* WIN_ASYNC_IO */
4135
 
        /* aio was queued successfully! */
4136
 
        return(TRUE);
4137
 
 
4138
 
#if defined LINUX_NATIVE_AIO || defined WIN_ASYNC_IO
4139
 
err_exit:
 
3500
                err = 1; /* Fall through the next if */
 
3501
        }
 
3502
#endif
 
3503
        if (err == 0) {
 
3504
                /* aio was queued successfully! */
 
3505
 
 
3506
                return(TRUE);
 
3507
        }
 
3508
 
4140
3509
        os_aio_array_free_slot(array, slot);
4141
3510
 
4142
3511
        retry = os_file_handle_error(name,
4148
3517
        }
4149
3518
 
4150
3519
        return(FALSE);
4151
 
#endif /* LINUX_NATIVE_AIO || WIN_ASYNC_IO */
4152
3520
}
4153
3521
 
4154
3522
#ifdef WIN_ASYNC_IO
4155
 
/**********************************************************************//**
 
3523
/**************************************************************************
4156
3524
This function is only used in Windows asynchronous i/o.
4157
3525
Waits for an aio operation to complete. This function is used to wait the
4158
3526
for completed requests. The aio array of pending requests is divided
4159
3527
into segments. The thread specifies which segment or slot it wants to wait
4160
3528
for. NOTE: this function will also take care of freeing the aio slot,
4161
 
therefore no other thread is allowed to do the freeing!
4162
 
@return TRUE if the aio operation succeeded */
 
3529
therefore no other thread is allowed to do the freeing! */
4163
3530
UNIV_INTERN
4164
3531
ibool
4165
3532
os_aio_windows_handle(
4166
3533
/*==================*/
4167
 
        ulint   segment,        /*!< in: the number of the segment in the aio
 
3534
                                /* out: TRUE if the aio operation succeeded */
 
3535
        ulint   segment,        /* in: the number of the segment in the aio
4168
3536
                                arrays to wait for; segment 0 is the ibuf
4169
3537
                                i/o thread, segment 1 the log i/o thread,
4170
3538
                                then follow the non-ibuf read threads, and as
4172
3540
                                this is ULINT_UNDEFINED, then it means that
4173
3541
                                sync aio is used, and this parameter is
4174
3542
                                ignored */
4175
 
        ulint   pos,            /*!< this parameter is used only in sync aio:
 
3543
        ulint   pos,            /* this parameter is used only in sync aio:
4176
3544
                                wait for the aio slot at this position */
4177
 
        fil_node_t**message1,   /*!< out: the messages passed with the aio
 
3545
        fil_node_t**message1,   /* out: the messages passed with the aio
4178
3546
                                request; note that also in the case where
4179
3547
                                the aio operation failed, these output
4180
3548
                                parameters are valid and can be used to
4181
3549
                                restart the operation, for example */
4182
3550
        void**  message2,
4183
 
        ulint*  type)           /*!< out: OS_FILE_WRITE or ..._READ */
 
3551
        ulint*  type)           /* out: OS_FILE_WRITE or ..._READ */
4184
3552
{
4185
3553
        ulint           orig_seg        = segment;
4186
3554
        os_aio_array_t* array;
4190
3558
        ibool           ret_val;
4191
3559
        BOOL            ret;
4192
3560
        DWORD           len;
4193
 
        BOOL            retry           = FALSE;
4194
3561
 
4195
3562
        if (segment == ULINT_UNDEFINED) {
4196
3563
                array = os_aio_sync_array;
4208
3575
        n = array->n_slots / array->n_segments;
4209
3576
 
4210
3577
        if (array == os_aio_sync_array) {
4211
 
                WaitForSingleObject(
4212
 
                        os_aio_array_get_nth_slot(array, pos)->handle,
4213
 
                        INFINITE);
 
3578
                os_event_wait(os_aio_array_get_nth_slot(array, pos)->event);
4214
3579
                i = pos;
4215
3580
        } else {
4216
3581
                srv_set_io_thread_op_info(orig_seg, "wait Windows aio");
4217
 
                i = WaitForMultipleObjects((DWORD) n,
4218
 
                                           array->handles + segment * n,
4219
 
                                           FALSE,
4220
 
                                           INFINITE);
4221
 
        }
4222
 
 
4223
 
        if (srv_shutdown_state == SRV_SHUTDOWN_EXIT_THREADS) {
4224
 
                os_thread_exit(NULL);
 
3582
                i = os_event_wait_multiple(n,
 
3583
                                           (array->native_events)
 
3584
                                           + segment * n);
4225
3585
        }
4226
3586
 
4227
3587
        os_mutex_enter(array->mutex);
4248
3608
#ifdef UNIV_DO_FLUSH
4249
3609
                if (slot->type == OS_FILE_WRITE
4250
3610
                    && !os_do_not_call_flush_at_each_write) {
4251
 
                        if (!os_file_flush(slot->file)) {
4252
 
                                ut_error;
4253
 
                        }
 
3611
                        ut_a(TRUE == os_file_flush(slot->file));
4254
3612
                }
4255
3613
#endif /* UNIV_DO_FLUSH */
4256
 
        } else if (os_file_handle_error(slot->name, "Windows aio")) {
4257
 
 
4258
 
                retry = TRUE;
4259
3614
        } else {
 
3615
                os_file_handle_error(slot->name, "Windows aio");
4260
3616
 
4261
3617
                ret_val = FALSE;
4262
3618
        }
4263
3619
 
4264
3620
        os_mutex_exit(array->mutex);
4265
3621
 
4266
 
        if (retry) {
4267
 
                /* retry failed read/write operation synchronously.
4268
 
                No need to hold array->mutex. */
4269
 
 
4270
 
#ifdef UNIV_PFS_IO
4271
 
                /* This read/write does not go through os_file_read
4272
 
                and os_file_write APIs, need to register with
4273
 
                performance schema explicitly here. */
4274
 
                struct PSI_file_locker* locker = NULL;
4275
 
                register_pfs_file_io_begin(locker, slot->file, slot->len,
4276
 
                                           (slot->type == OS_FILE_WRITE)
4277
 
                                                ? PSI_FILE_WRITE
4278
 
                                                : PSI_FILE_READ,
4279
 
                                            __FILE__, __LINE__);
4280
 
#endif
4281
 
 
4282
 
                switch (slot->type) {
4283
 
                case OS_FILE_WRITE:
4284
 
                        ret = WriteFile(slot->file, slot->buf,
4285
 
                                        slot->len, &len,
4286
 
                                        &(slot->control));
4287
 
 
4288
 
                        break;
4289
 
                case OS_FILE_READ:
4290
 
                        ret = ReadFile(slot->file, slot->buf,
4291
 
                                       slot->len, &len,
4292
 
                                       &(slot->control));
4293
 
 
4294
 
                        break;
4295
 
                default:
4296
 
                        ut_error;
4297
 
                }
4298
 
 
4299
 
#ifdef UNIV_PFS_IO
4300
 
                register_pfs_file_io_end(locker, len);
4301
 
#endif
4302
 
 
4303
 
                if (!ret && GetLastError() == ERROR_IO_PENDING) {
4304
 
                        /* aio was queued successfully!
4305
 
                        We want a synchronous i/o operation on a
4306
 
                        file where we also use async i/o: in Windows
4307
 
                        we must use the same wait mechanism as for
4308
 
                        async i/o */
4309
 
 
4310
 
                        ret = GetOverlappedResult(slot->file,
4311
 
                                                  &(slot->control),
4312
 
                                                  &len, TRUE);
4313
 
                }
4314
 
 
4315
 
                ret_val = ret && len == slot->len;
4316
 
        }
4317
 
 
4318
3622
        os_aio_array_free_slot(array, slot);
4319
3623
 
4320
3624
        return(ret_val);
4321
3625
}
4322
3626
#endif
4323
3627
 
4324
 
#if defined(LINUX_NATIVE_AIO)
4325
 
/******************************************************************//**
4326
 
This function is only used in Linux native asynchronous i/o. This is
4327
 
called from within the io-thread. If there are no completed IO requests
4328
 
in the slot array, the thread calls this function to collect more
4329
 
requests from the kernel.
4330
 
The io-thread waits on io_getevents(), which is a blocking call, with
4331
 
a timeout value. Unless the system is very heavy loaded, keeping the
4332
 
io-thread very busy, the io-thread will spend most of its time waiting
4333
 
in this function.
4334
 
The io-thread also exits in this function. It checks server status at
4335
 
each wakeup and that is why we use timed wait in io_getevents(). */
4336
 
static
4337
 
void
4338
 
os_aio_linux_collect(
4339
 
/*=================*/
4340
 
        os_aio_array_t* array,          /*!< in/out: slot array. */
4341
 
        ulint           segment,        /*!< in: local segment no. */
4342
 
        ulint           seg_size)       /*!< in: segment size. */
4343
 
{
4344
 
        int                     i;
4345
 
        int                     ret;
4346
 
        ulint                   start_pos;
4347
 
        ulint                   end_pos;
4348
 
        struct timespec         timeout;
4349
 
        struct io_event*        events;
4350
 
        struct io_context*      io_ctx;
4351
 
 
4352
 
        /* sanity checks. */
4353
 
        ut_ad(array != NULL);
4354
 
        ut_ad(seg_size > 0);
4355
 
        ut_ad(segment < array->n_segments);
4356
 
 
4357
 
        /* Which part of event array we are going to work on. */
4358
 
        events = &array->aio_events[segment * seg_size];
4359
 
 
4360
 
        /* Which io_context we are going to use. */
4361
 
        io_ctx = array->aio_ctx[segment];
4362
 
 
4363
 
        /* Starting point of the segment we will be working on. */
4364
 
        start_pos = segment * seg_size;
4365
 
 
4366
 
        /* End point. */
4367
 
        end_pos = start_pos + seg_size;
4368
 
 
4369
 
retry:
4370
 
 
4371
 
        /* Go down if we are in shutdown mode.
4372
 
        In case of srv_fast_shutdown == 2, there may be pending
4373
 
        IO requests but that should be OK as we essentially treat
4374
 
        that as a crash of InnoDB. */
4375
 
        if (srv_shutdown_state == SRV_SHUTDOWN_EXIT_THREADS) {
4376
 
                os_thread_exit(NULL);
4377
 
        }
4378
 
 
4379
 
        /* Initialize the events. The timeout value is arbitrary.
4380
 
        We probably need to experiment with it a little. */
4381
 
        memset(events, 0, sizeof(*events) * seg_size);
4382
 
        timeout.tv_sec = 0;
4383
 
        timeout.tv_nsec = OS_AIO_REAP_TIMEOUT;
4384
 
 
4385
 
        ret = io_getevents(io_ctx, 1, seg_size, events, &timeout);
4386
 
 
4387
 
        /* This error handling is for any error in collecting the
4388
 
        IO requests. The errors, if any, for any particular IO
4389
 
        request are simply passed on to the calling routine. */
4390
 
 
4391
 
        /* Not enough resources! Try again. */
4392
 
        if (ret == -EAGAIN) {
4393
 
                goto retry;
4394
 
        }
4395
 
 
4396
 
        /* Interrupted! I have tested the behaviour in case of an
4397
 
        interrupt. If we have some completed IOs available then
4398
 
        the return code will be the number of IOs. We get EINTR only
4399
 
        if there are no completed IOs and we have been interrupted. */
4400
 
        if (ret == -EINTR) {
4401
 
                goto retry;
4402
 
        }
4403
 
 
4404
 
        /* No pending request! Go back and check again. */
4405
 
        if (ret == 0) {
4406
 
                goto retry;
4407
 
        }
4408
 
 
4409
 
        /* All other errors! should cause a trap for now. */
4410
 
        if (UNIV_UNLIKELY(ret < 0)) {
4411
 
                ut_print_timestamp(stderr);
4412
 
                fprintf(stderr,
4413
 
                        "  InnoDB: unexpected ret_code[%d] from"
4414
 
                        " io_getevents()!\n", ret);
4415
 
                ut_error;
4416
 
        }
4417
 
 
4418
 
        ut_a(ret > 0);
4419
 
 
4420
 
        for (i = 0; i < ret; i++) {
4421
 
                os_aio_slot_t*  slot;
4422
 
                struct iocb*    control;
4423
 
 
4424
 
                control = (struct iocb *)events[i].obj;
4425
 
                ut_a(control != NULL);
4426
 
 
4427
 
                slot = (os_aio_slot_t *) control->data;
4428
 
 
4429
 
                /* Some sanity checks. */
4430
 
                ut_a(slot != NULL);
4431
 
                ut_a(slot->reserved);
4432
 
 
4433
 
#if defined(UNIV_AIO_DEBUG)
4434
 
                fprintf(stderr,
4435
 
                        "io_getevents[%c]: slot[%p] ctx[%p]"
4436
 
                        " seg[%lu]\n",
4437
 
                        (slot->type == OS_FILE_WRITE) ? 'w' : 'r',
4438
 
                        slot, io_ctx, segment);
4439
 
#endif
4440
 
 
4441
 
                /* We are not scribbling previous segment. */
4442
 
                ut_a(slot->pos >= start_pos);
4443
 
 
4444
 
                /* We have not overstepped to next segment. */
4445
 
                ut_a(slot->pos < end_pos);
4446
 
 
4447
 
                /* Mark this request as completed. The error handling
4448
 
                will be done in the calling function. */
4449
 
                os_mutex_enter(array->mutex);
4450
 
                slot->n_bytes = events[i].res;
4451
 
                slot->ret = events[i].res2;
4452
 
                slot->io_already_done = TRUE;
4453
 
                os_mutex_exit(array->mutex);
4454
 
        }
4455
 
 
4456
 
        return;
4457
 
}
4458
 
 
4459
 
/**********************************************************************//**
4460
 
This function is only used in Linux native asynchronous i/o.
4461
 
Waits for an aio operation to complete. This function is used to wait for
4462
 
the completed requests. The aio array of pending requests is divided
4463
 
into segments. The thread specifies which segment or slot it wants to wait
4464
 
for. NOTE: this function will also take care of freeing the aio slot,
4465
 
therefore no other thread is allowed to do the freeing!
4466
 
@return TRUE if the IO was successful */
4467
 
UNIV_INTERN
4468
 
ibool
4469
 
os_aio_linux_handle(
4470
 
/*================*/
4471
 
        ulint   global_seg,     /*!< in: segment number in the aio array
4472
 
                                to wait for; segment 0 is the ibuf
4473
 
                                i/o thread, segment 1 is log i/o thread,
4474
 
                                then follow the non-ibuf read threads,
4475
 
                                and the last are the non-ibuf write
4476
 
                                threads. */
4477
 
        fil_node_t**message1,   /*!< out: the messages passed with the */
4478
 
        void**  message2,       /*!< aio request; note that in case the
4479
 
                                aio operation failed, these output
4480
 
                                parameters are valid and can be used to
4481
 
                                restart the operation. */
4482
 
        ulint*  type)           /*!< out: OS_FILE_WRITE or ..._READ */
4483
 
{
4484
 
        ulint           segment;
4485
 
        os_aio_array_t* array;
4486
 
        os_aio_slot_t*  slot;
4487
 
        ulint           n;
4488
 
        ulint           i;
4489
 
        ibool           ret = FALSE;
4490
 
 
4491
 
        /* Should never be doing Sync IO here. */
4492
 
        ut_a(global_seg != ULINT_UNDEFINED);
4493
 
 
4494
 
        /* Find the array and the local segment. */
4495
 
        segment = os_aio_get_array_and_local_segment(&array, global_seg);
4496
 
        n = array->n_slots / array->n_segments;
4497
 
 
4498
 
        /* Loop until we have found a completed request. */
4499
 
        for (;;) {
4500
 
                os_mutex_enter(array->mutex);
4501
 
                for (i = 0; i < n; ++i) {
4502
 
                        slot = os_aio_array_get_nth_slot(
4503
 
                                        array, i + segment * n);
4504
 
                        if (slot->reserved && slot->io_already_done) {
4505
 
                                /* Something for us to work on. */
4506
 
                                goto found;
4507
 
                        }
4508
 
                }
4509
 
 
4510
 
                os_mutex_exit(array->mutex);
4511
 
 
4512
 
                /* We don't have any completed request.
4513
 
                Wait for some request. Note that we return
4514
 
                from wait iff we have found a request. */
4515
 
 
4516
 
                srv_set_io_thread_op_info(global_seg,
4517
 
                        "waiting for completed aio requests");
4518
 
                os_aio_linux_collect(array, segment, n);
4519
 
        }
4520
 
 
4521
 
found:
4522
 
        /* Note that it may be that there are more then one completed
4523
 
        IO requests. We process them one at a time. We may have a case
4524
 
        here to improve the performance slightly by dealing with all
4525
 
        requests in one sweep. */
4526
 
        srv_set_io_thread_op_info(global_seg,
4527
 
                                "processing completed aio requests");
4528
 
 
4529
 
        /* Ensure that we are scribbling only our segment. */
4530
 
        ut_a(i < n);
4531
 
 
4532
 
        ut_ad(slot != NULL);
4533
 
        ut_ad(slot->reserved);
4534
 
        ut_ad(slot->io_already_done);
4535
 
 
4536
 
        *message1 = slot->message1;
4537
 
        *message2 = slot->message2;
4538
 
 
4539
 
        *type = slot->type;
4540
 
 
4541
 
        if ((slot->ret == 0) && (slot->n_bytes == (long)slot->len)) {
4542
 
                ret = TRUE;
4543
 
 
4544
 
#ifdef UNIV_DO_FLUSH
4545
 
                if (slot->type == OS_FILE_WRITE
4546
 
                    && !os_do_not_call_flush_at_each_write)
4547
 
                    && !os_file_flush(slot->file) {
4548
 
                        ut_error;
4549
 
                }
4550
 
#endif /* UNIV_DO_FLUSH */
4551
 
        } else {
4552
 
                errno = -slot->ret;
4553
 
 
4554
 
                /* os_file_handle_error does tell us if we should retry
4555
 
                this IO. As it stands now, we don't do this retry when
4556
 
                reaping requests from a different context than
4557
 
                the dispatcher. This non-retry logic is the same for
4558
 
                windows and linux native AIO.
4559
 
                We should probably look into this to transparently
4560
 
                re-submit the IO. */
4561
 
                os_file_handle_error(slot->name, "Linux aio");
4562
 
 
4563
 
                ret = FALSE;
4564
 
        }
4565
 
 
4566
 
        os_mutex_exit(array->mutex);
4567
 
 
4568
 
        os_aio_array_free_slot(array, slot);
4569
 
 
4570
 
        return(ret);
4571
 
}
4572
 
#endif /* LINUX_NATIVE_AIO */
4573
 
 
4574
 
/**********************************************************************//**
 
3628
/**************************************************************************
4575
3629
Does simulated aio. This function should be called by an i/o-handler
4576
 
thread.
4577
 
@return TRUE if the aio operation succeeded */
 
3630
thread. */
4578
3631
UNIV_INTERN
4579
3632
ibool
4580
3633
os_aio_simulated_handle(
4581
3634
/*====================*/
4582
 
        ulint   global_segment, /*!< in: the number of the segment in the aio
 
3635
                                /* out: TRUE if the aio operation succeeded */
 
3636
        ulint   global_segment, /* in: the number of the segment in the aio
4583
3637
                                arrays to wait for; segment 0 is the ibuf
4584
3638
                                i/o thread, segment 1 the log i/o thread,
4585
3639
                                then follow the non-ibuf read threads, and as
4586
3640
                                the last are the non-ibuf write threads */
4587
 
        fil_node_t**message1,   /*!< out: the messages passed with the aio
 
3641
        fil_node_t**message1,   /* out: the messages passed with the aio
4588
3642
                                request; note that also in the case where
4589
3643
                                the aio operation failed, these output
4590
3644
                                parameters are valid and can be used to
4591
3645
                                restart the operation, for example */
4592
3646
        void**  message2,
4593
 
        ulint*  type)           /*!< out: OS_FILE_WRITE or ..._READ */
 
3647
        ulint*  type)           /* out: OS_FILE_WRITE or ..._READ */
4594
3648
{
4595
3649
        os_aio_array_t* array;
4596
3650
        ulint           segment;
4609
3663
        ulint           n;
4610
3664
        ulint           i;
4611
3665
 
4612
 
        /* Fix compiler warning */
4613
 
        *consecutive_ios = NULL;
4614
 
 
4615
 
        memset(consecutive_ios, 0, sizeof(os_aio_slot_t*) * OS_AIO_MERGE_N_CONSECUTIVE);
4616
3666
        segment = os_aio_get_array_and_local_segment(&array, global_segment);
4617
3667
 
4618
3668
restart:
4724
3774
                goto wait_for_io;
4725
3775
        }
4726
3776
 
4727
 
        /* if n_consecutive != 0, then we have assigned
4728
 
        something valid to consecutive_ios[0] */
4729
 
        ut_ad(n_consecutive != 0);
4730
 
        ut_ad(consecutive_ios[0] != NULL);
4731
 
 
4732
3777
        slot = consecutive_ios[0];
4733
3778
 
4734
3779
        /* Check if there are several consecutive blocks to read or write */
4901
3946
        goto restart;
4902
3947
}
4903
3948
 
4904
 
/**********************************************************************//**
4905
 
Validates the consistency of an aio array.
4906
 
@return TRUE if ok */
 
3949
/**************************************************************************
 
3950
Validates the consistency of an aio array. */
4907
3951
static
4908
3952
ibool
4909
3953
os_aio_array_validate(
4910
3954
/*==================*/
4911
 
        os_aio_array_t* array)  /*!< in: aio wait array */
 
3955
                                /* out: TRUE if ok */
 
3956
        os_aio_array_t* array)  /* in: aio wait array */
4912
3957
{
4913
3958
        os_aio_slot_t*  slot;
4914
3959
        ulint           n_reserved      = 0;
4937
3982
        return(TRUE);
4938
3983
}
4939
3984
 
4940
 
/**********************************************************************//**
4941
 
Validates the consistency the aio system.
4942
 
@return TRUE if ok */
 
3985
/**************************************************************************
 
3986
Validates the consistency the aio system. */
4943
3987
UNIV_INTERN
4944
3988
ibool
4945
3989
os_aio_validate(void)
4946
3990
/*=================*/
 
3991
                                /* out: TRUE if ok */
4947
3992
{
4948
3993
        os_aio_array_validate(os_aio_read_array);
4949
3994
        os_aio_array_validate(os_aio_write_array);
4954
3999
        return(TRUE);
4955
4000
}
4956
4001
 
4957
 
/**********************************************************************//**
4958
 
Prints pending IO requests per segment of an aio array.
4959
 
We probably don't need per segment statistics but they can help us
4960
 
during development phase to see if the IO requests are being
4961
 
distributed as expected. */
4962
 
static
4963
 
void
4964
 
os_aio_print_segment_info(
4965
 
/*======================*/
4966
 
        FILE*           file,   /*!< in: file where to print */
4967
 
        ulint*          n_seg,  /*!< in: pending IO array */
4968
 
        os_aio_array_t* array)  /*!< in: array to process */
4969
 
{
4970
 
        ulint   i;
4971
 
 
4972
 
        ut_ad(array);
4973
 
        ut_ad(n_seg);
4974
 
        ut_ad(array->n_segments > 0);
4975
 
 
4976
 
        if (array->n_segments == 1) {
4977
 
                return;
4978
 
        }
4979
 
 
4980
 
        fprintf(file, " [");
4981
 
        for (i = 0; i < array->n_segments; i++) {
4982
 
                if (i != 0) {
4983
 
                        fprintf(file, ", ");
4984
 
                }
4985
 
 
4986
 
                fprintf(file, "%lu", n_seg[i]);
4987
 
        }
4988
 
        fprintf(file, "] ");
4989
 
}
4990
 
 
4991
 
/**********************************************************************//**
 
4002
/**************************************************************************
4992
4003
Prints info of the aio arrays. */
4993
4004
UNIV_INTERN
4994
4005
void
4995
4006
os_aio_print(
4996
4007
/*=========*/
4997
 
        FILE*   file)   /*!< in: file where to print */
 
4008
        FILE*   file)   /* in: file where to print */
4998
4009
{
4999
4010
        os_aio_array_t* array;
5000
4011
        os_aio_slot_t*  slot;
5001
4012
        ulint           n_reserved;
5002
 
        ulint           n_res_seg[SRV_MAX_N_IO_THREADS];
5003
4013
        time_t          current_time;
5004
4014
        double          time_elapsed;
5005
4015
        double          avg_bytes_read;
5032
4042
 
5033
4043
        n_reserved = 0;
5034
4044
 
5035
 
        memset(n_res_seg, 0x0, sizeof(n_res_seg));
5036
 
 
5037
4045
        for (i = 0; i < array->n_slots; i++) {
5038
 
                ulint   seg_no;
5039
 
 
5040
4046
                slot = os_aio_array_get_nth_slot(array, i);
5041
4047
 
5042
 
                seg_no = (i * array->n_segments) / array->n_slots;
5043
4048
                if (slot->reserved) {
5044
4049
                        n_reserved++;
5045
 
                        n_res_seg[seg_no]++;
5046
4050
#if 0
5047
4051
                        fprintf(stderr, "Reserved slot, messages %p %p\n",
5048
4052
                                (void*) slot->message1,
5056
4060
 
5057
4061
        fprintf(file, " %lu", (ulong) n_reserved);
5058
4062
 
5059
 
        os_aio_print_segment_info(file, n_res_seg, array);
5060
 
 
5061
4063
        os_mutex_exit(array->mutex);
5062
4064
 
5063
4065
        if (array == os_aio_read_array) {
5134
4136
        os_last_printout = current_time;
5135
4137
}
5136
4138
 
5137
 
/**********************************************************************//**
 
4139
/**************************************************************************
5138
4140
Refreshes the statistics used to print per-second averages. */
5139
4141
UNIV_INTERN
5140
4142
void
5150
4152
}
5151
4153
 
5152
4154
#ifdef UNIV_DEBUG
5153
 
/**********************************************************************//**
 
4155
/**************************************************************************
5154
4156
Checks that all slots in the system have been freed, that is, there are
5155
 
no pending io operations.
5156
 
@return TRUE if all free */
 
4157
no pending io operations. */
5157
4158
UNIV_INTERN
5158
4159
ibool
5159
4160
os_aio_all_slots_free(void)
5160
4161
/*=======================*/
 
4162
                                /* out: TRUE if all free */
5161
4163
{
5162
4164
        os_aio_array_t* array;
5163
4165
        ulint           n_res   = 0;
5210
4212
        return(FALSE);
5211
4213
}
5212
4214
#endif /* UNIV_DEBUG */
5213
 
 
5214
 
#endif /* !UNIV_HOTBACKUP */