~drizzle-trunk/drizzle/development

« back to all changes in this revision

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

  • Committer: Brian Aker
  • Date: 2008-11-04 15:39:09 UTC
  • mfrom: (575.1.2 devel)
  • Revision ID: brian@tangent.org-20081104153909-c72hn65udxs1ccal
Merge of Monty's work

Show diffs side-by-side

added added

removed removed

Lines of Context:
33
33
my_umask */
34
34
 
35
35
#ifndef __WIN__
36
 
ulint   os_innodb_umask         = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP;
 
36
UNIV_INTERN ulint       os_innodb_umask
 
37
                        = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP;
37
38
#else
38
 
ulint   os_innodb_umask         = 0;
 
39
UNIV_INTERN ulint       os_innodb_umask         = 0;
39
40
#endif
40
41
 
41
42
#ifdef UNIV_DO_FLUSH
42
43
/* If the following is set to TRUE, we do not call os_file_flush in every
43
44
os_file_write. We can set this TRUE when the doublewrite buffer is used. */
44
 
ibool   os_do_not_call_flush_at_each_write      = FALSE;
 
45
UNIV_INTERN ibool       os_do_not_call_flush_at_each_write      = FALSE;
45
46
#else
46
47
/* We do not call os_file_flush in every os_file_write. */
47
48
#endif /* UNIV_DO_FLUSH */
49
50
/* We use these mutexes to protect lseek + file i/o operation, if the
50
51
OS does not provide an atomic pread or pwrite, or similar */
51
52
#define OS_FILE_N_SEEK_MUTEXES  16
52
 
os_mutex_t      os_file_seek_mutexes[OS_FILE_N_SEEK_MUTEXES];
 
53
UNIV_INTERN os_mutex_t  os_file_seek_mutexes[OS_FILE_N_SEEK_MUTEXES];
53
54
 
54
55
/* In simulated aio, merge at most this many consecutive i/os */
55
56
#define OS_AIO_MERGE_N_CONSECUTIVE      64
58
59
OS (provided we compiled Innobase with it in), otherwise we will
59
60
use simulated aio we build below with threads */
60
61
 
61
 
ibool   os_aio_use_native_aio   = FALSE;
 
62
UNIV_INTERN ibool       os_aio_use_native_aio   = FALSE;
62
63
 
63
 
ibool   os_aio_print_debug      = FALSE;
 
64
UNIV_INTERN ibool       os_aio_print_debug      = FALSE;
64
65
 
65
66
/* The aio array slot structure */
66
67
typedef struct os_aio_slot_struct       os_aio_slot_t;
131
132
};
132
133
 
133
134
/* Array of events used in simulated aio */
134
 
os_event_t*     os_aio_segment_wait_events      = NULL;
 
135
static os_event_t*      os_aio_segment_wait_events      = NULL;
135
136
 
136
137
/* The aio arrays for non-ibuf i/o and ibuf i/o, as well as sync aio. These
137
138
are NULL when the module has not yet been initialized. */
147
148
wait until a batch of new read requests have been posted */
148
149
static ibool    os_aio_recommend_sleep_for_read_threads = FALSE;
149
150
 
150
 
ulint   os_n_file_reads         = 0;
151
 
ulint   os_bytes_read_since_printout = 0;
152
 
ulint   os_n_file_writes        = 0;
153
 
ulint   os_n_fsyncs             = 0;
154
 
ulint   os_n_file_reads_old     = 0;
155
 
ulint   os_n_file_writes_old    = 0;
156
 
ulint   os_n_fsyncs_old         = 0;
157
 
time_t  os_last_printout;
 
151
UNIV_INTERN ulint       os_n_file_reads         = 0;
 
152
UNIV_INTERN ulint       os_bytes_read_since_printout = 0;
 
153
UNIV_INTERN ulint       os_n_file_writes        = 0;
 
154
UNIV_INTERN ulint       os_n_fsyncs             = 0;
 
155
UNIV_INTERN ulint       os_n_file_reads_old     = 0;
 
156
UNIV_INTERN ulint       os_n_file_writes_old    = 0;
 
157
UNIV_INTERN ulint       os_n_fsyncs_old         = 0;
 
158
UNIV_INTERN time_t      os_last_printout;
158
159
 
159
 
ibool   os_has_said_disk_full   = FALSE;
 
160
UNIV_INTERN ibool       os_has_said_disk_full   = FALSE;
160
161
 
161
162
/* The mutex protecting the following counts of pending I/O operations */
162
 
static os_mutex_t os_file_count_mutex;
163
 
ulint   os_file_n_pending_preads  = 0;
164
 
ulint   os_file_n_pending_pwrites = 0;
165
 
ulint   os_n_pending_writes = 0;
166
 
ulint   os_n_pending_reads = 0;
 
163
static os_mutex_t       os_file_count_mutex;
 
164
UNIV_INTERN ulint       os_file_n_pending_preads  = 0;
 
165
UNIV_INTERN ulint       os_file_n_pending_pwrites = 0;
 
166
UNIV_INTERN ulint       os_n_pending_writes = 0;
 
167
UNIV_INTERN ulint       os_n_pending_reads = 0;
167
168
 
168
169
/***************************************************************************
169
170
Gets the operating system version. Currently works only on Windows. */
170
 
 
 
171
UNIV_INTERN
171
172
ulint
172
173
os_get_os_version(void)
173
174
/*===================*/
206
207
The number should be retrieved before any other OS calls (because they may
207
208
overwrite the error number). If the number is not known to this program,
208
209
the OS error number + 100 is returned. */
209
 
 
 
210
UNIV_INTERN
210
211
ulint
211
212
os_file_get_last_error(
212
213
/*===================*/
350
351
Does error handling when a file operation fails.
351
352
Conditionally exits (calling exit(3)) based on should_exit value and the
352
353
error type */
353
 
 
354
354
static
355
355
ibool
356
356
os_file_handle_error_cond_exit(
454
454
 
455
455
#undef USE_FILE_LOCK
456
456
#define USE_FILE_LOCK
457
 
#if defined(UNIV_HOTBACKUP) || defined(__WIN__) 
 
457
#if defined(UNIV_HOTBACKUP) || defined(__WIN__) || defined(__NETWARE__)
458
458
/* InnoDB Hot Backup does not lock the data files.
459
459
 * On Windows, mandatory locking is used.
460
460
 */
496
496
 
497
497
/********************************************************************
498
498
Creates the seek mutexes used in positioned reads and writes. */
499
 
 
 
499
UNIV_INTERN
500
500
void
501
501
os_io_init_simple(void)
502
502
/*===================*/
510
510
        }
511
511
}
512
512
 
513
 
#if !defined(UNIV_HOTBACKUP) 
514
 
/*************************************************************************
515
 
Creates a temporary file that will be deleted on close.
516
 
This function is defined in ha_innodb.cc. */
517
 
 
518
 
int
519
 
innobase_mysql_tmpfile(void);
520
 
/*========================*/
521
 
                        /* out: temporary file descriptor, or < 0 on error */
522
 
#endif /* !UNIV_HOTBACKUP */
523
 
 
524
513
/***************************************************************************
525
514
Creates a temporary file.  This function is like tmpfile(3), but
526
515
the temporary file is created in the MySQL temporary directory.
527
516
On Netware, this function is like tmpfile(3), because the C run-time
528
517
library of Netware does not expose the delete-on-close flag. */
529
 
 
 
518
UNIV_INTERN
530
519
FILE*
531
520
os_file_create_tmpfile(void)
532
521
/*========================*/
537
526
 
538
527
        return(NULL);
539
528
#else
 
529
# ifdef __NETWARE__
 
530
        FILE*   file    = tmpfile();
 
531
# else /* __NETWARE__ */
540
532
        FILE*   file    = NULL;
541
533
        int     fd      = innobase_mysql_tmpfile();
542
534
 
543
535
        if (fd >= 0) {
544
536
                file = fdopen(fd, "w+b");
545
537
        }
 
538
# endif /* __NETWARE__ */
546
539
 
547
540
        if (!file) {
548
541
                ut_print_timestamp(stderr);
549
542
                fprintf(stderr,
550
543
                        "  InnoDB: Error: unable to create temporary file;"
551
544
                        " errno: %d\n", errno);
 
545
# ifndef __NETWARE__
552
546
                if (fd >= 0) {
553
547
                        close(fd);
554
548
                }
 
549
# endif /* !__NETWARE__ */
555
550
        }
556
551
 
557
552
        return(file);
563
558
directory named by the dirname argument. The directory stream is positioned
564
559
at the first entry. In both Unix and Windows we automatically skip the '.'
565
560
and '..' items at the start of the directory listing. */
566
 
 
 
561
UNIV_INTERN
567
562
os_file_dir_t
568
563
os_file_opendir(
569
564
/*============*/
620
615
 
621
616
/***************************************************************************
622
617
Closes a directory stream. */
623
 
 
 
618
UNIV_INTERN
624
619
int
625
620
os_file_closedir(
626
621
/*=============*/
655
650
/***************************************************************************
656
651
This function returns information of the next file in the directory. We jump
657
652
over the '.' and '..' entries in the directory. */
658
 
 
 
653
UNIV_INTERN
659
654
int
660
655
os_file_readdir_next_file(
661
656
/*======================*/
685
680
 
686
681
                strcpy(info->name, (char *) lpFindFileData->cFileName);
687
682
 
688
 
                info->size = (ib_longlong)(lpFindFileData->nFileSizeLow)
689
 
                        + (((ib_longlong)(lpFindFileData->nFileSizeHigh))
 
683
                info->size = (ib_int64_t)(lpFindFileData->nFileSizeLow)
 
684
                        + (((ib_int64_t)(lpFindFileData->nFileSizeHigh))
690
685
                           << 32);
691
686
 
692
687
                if (lpFindFileData->dwFileAttributes
786
781
                return(-1);
787
782
        }
788
783
 
789
 
        info->size = (ib_longlong)statinfo.st_size;
 
784
        info->size = (ib_int64_t)statinfo.st_size;
790
785
 
791
786
        if (S_ISDIR(statinfo.st_mode)) {
792
787
                info->type = OS_FILE_TYPE_DIR;
809
804
gets default permissions. On Unix the permissions are (0770 & ~umask). If the
810
805
directory exists already, nothing is done and the call succeeds, unless the
811
806
fail_if_exists arguments is true. */
812
 
 
 
807
UNIV_INTERN
813
808
ibool
814
809
os_file_create_directory(
815
810
/*=====================*/
852
847
 
853
848
/********************************************************************
854
849
A simple function to open or create a file. */
855
 
 
 
850
UNIV_INTERN
856
851
os_file_t
857
852
os_file_create_simple(
858
853
/*==================*/
994
989
 
995
990
/********************************************************************
996
991
A simple function to open or create a file. */
997
 
 
 
992
UNIV_INTERN
998
993
os_file_t
999
994
os_file_create_simple_no_error_handling(
1000
995
/*====================================*/
1107
1102
 
1108
1103
/********************************************************************
1109
1104
Tries to disable OS caching on an opened file descriptor. */
1110
 
 
1111
 
static void
 
1105
UNIV_INTERN
 
1106
void
1112
1107
os_file_set_nocache(
1113
1108
/*================*/
1114
 
        int             fd,/* in: file descriptor to alter */
1115
 
        const char*     file_name,/* in: used in the diagnostic
1116
 
                                        message */
1117
 
        const char*     operation_name)/* in: used in the
1118
 
                                        diagnostic message,
1119
 
                                        we call os_file_set_nocache()
1120
 
                                        immediately after opening or creating
1121
 
                                        a file, so this is either "open" or
1122
 
                                        "create" */
 
1109
        int             fd,             /* in: file descriptor to alter */
 
1110
        const char*     file_name,      /* in: file name, used in the
 
1111
                                        diagnostic message */
 
1112
        const char*     operation_name) /* in: "open" or "create"; used in the
 
1113
                                        diagnostic message */
1123
1114
{
1124
1115
        /* some versions of Solaris may not have DIRECTIO_ON */
1125
1116
#if defined(UNIV_SOLARIS) && defined(DIRECTIO_ON)
1149
1140
                                "see MySQL Bug#26662\n");
1150
1141
                }
1151
1142
        }
1152
 
#else
1153
 
  (void)fd;
1154
 
  (void)file_name;
1155
 
  (void)operation_name;
 
1143
#else /* Required for OSX */
 
1144
        (void)fd;
 
1145
        (void)file_name;
 
1146
        (void)operation_name;
1156
1147
#endif
1157
1148
}
1158
1149
 
1159
1150
/********************************************************************
1160
1151
Opens an existing file or creates a new. */
1161
 
 
 
1152
UNIV_INTERN
1162
1153
os_file_t
1163
1154
os_file_create(
1164
1155
/*===========*/
1397
1388
 
1398
1389
/***************************************************************************
1399
1390
Deletes a file if it exists. The file has to be closed before calling this. */
1400
 
 
 
1391
UNIV_INTERN
1401
1392
ibool
1402
1393
os_file_delete_if_exists(
1403
1394
/*=====================*/
1445
1436
#else
1446
1437
        int     ret;
1447
1438
 
1448
 
        ret = unlink((const char*)name);
 
1439
        ret = unlink(name);
1449
1440
 
1450
1441
        if (ret != 0 && errno != ENOENT) {
1451
1442
                os_file_handle_error_no_exit(name, "delete");
1459
1450
 
1460
1451
/***************************************************************************
1461
1452
Deletes a file. The file has to be closed before calling this. */
1462
 
 
 
1453
UNIV_INTERN
1463
1454
ibool
1464
1455
os_file_delete(
1465
1456
/*===========*/
1508
1499
#else
1509
1500
        int     ret;
1510
1501
 
1511
 
        ret = unlink((const char*)name);
 
1502
        ret = unlink(name);
1512
1503
 
1513
1504
        if (ret != 0) {
1514
1505
                os_file_handle_error_no_exit(name, "delete");
1523
1514
/***************************************************************************
1524
1515
Renames a file (can also move it to another directory). It is safest that the
1525
1516
file is closed before calling this function. */
1526
 
 
 
1517
UNIV_INTERN
1527
1518
ibool
1528
1519
os_file_rename(
1529
1520
/*===========*/
1547
1538
#else
1548
1539
        int     ret;
1549
1540
 
1550
 
        ret = rename((const char*)oldpath, (const char*)newpath);
 
1541
        ret = rename(oldpath, newpath);
1551
1542
 
1552
1543
        if (ret != 0) {
1553
1544
                os_file_handle_error_no_exit(oldpath, "rename");
1562
1553
/***************************************************************************
1563
1554
Closes a file handle. In case of error, error number can be retrieved with
1564
1555
os_file_get_last_error. */
1565
 
 
 
1556
UNIV_INTERN
1566
1557
ibool
1567
1558
os_file_close(
1568
1559
/*==========*/
1600
1591
 
1601
1592
/***************************************************************************
1602
1593
Closes a file handle. */
1603
 
 
 
1594
UNIV_INTERN
1604
1595
ibool
1605
1596
os_file_close_no_error_handling(
1606
1597
/*============================*/
1635
1626
 
1636
1627
/***************************************************************************
1637
1628
Gets a file size. */
1638
 
 
 
1629
UNIV_INTERN
1639
1630
ibool
1640
1631
os_file_get_size(
1641
1632
/*=============*/
1682
1673
}
1683
1674
 
1684
1675
/***************************************************************************
1685
 
Gets file size as a 64-bit integer ib_longlong. */
1686
 
 
1687
 
ib_longlong
 
1676
Gets file size as a 64-bit integer ib_int64_t. */
 
1677
UNIV_INTERN
 
1678
ib_int64_t
1688
1679
os_file_get_size_as_iblonglong(
1689
1680
/*===========================*/
1690
1681
                                /* out: size in bytes, -1 if error */
1701
1692
                return(-1);
1702
1693
        }
1703
1694
 
1704
 
        return((((ib_longlong)size_high) << 32) + (ib_longlong)size);
 
1695
        return((((ib_int64_t)size_high) << 32) + (ib_int64_t)size);
1705
1696
}
1706
1697
 
1707
1698
/***************************************************************************
1708
1699
Write the specified number of zeros to a newly created file. */
1709
 
 
 
1700
UNIV_INTERN
1710
1701
ibool
1711
1702
os_file_set_size(
1712
1703
/*=============*/
1718
1709
                                size */
1719
1710
        ulint           size_high)/* in: most significant 32 bits of size */
1720
1711
{
1721
 
        ib_longlong     current_size;
1722
 
        ib_longlong     desired_size;
 
1712
        ib_int64_t      current_size;
 
1713
        ib_int64_t      desired_size;
1723
1714
        ibool           ret;
1724
1715
        byte*           buf;
1725
1716
        byte*           buf2;
1728
1719
        ut_a(size == (size & 0xFFFFFFFF));
1729
1720
 
1730
1721
        current_size = 0;
1731
 
        desired_size = (ib_longlong)size + (((ib_longlong)size_high) << 32);
 
1722
        desired_size = (ib_int64_t)size + (((ib_int64_t)size_high) << 32);
1732
1723
 
1733
1724
        /* Write up to 1 megabyte at a time. */
1734
1725
        buf_size = ut_min(64, (ulint) (desired_size / UNIV_PAGE_SIZE))
1741
1732
        /* Write buffer full of zeros */
1742
1733
        memset(buf, 0, buf_size);
1743
1734
 
1744
 
        if (desired_size >= (ib_longlong)(100 * 1024 * 1024)) {
 
1735
        if (desired_size >= (ib_int64_t)(100 * 1024 * 1024)) {
1745
1736
 
1746
1737
                fprintf(stderr, "InnoDB: Progress in MB:");
1747
1738
        }
1749
1740
        while (current_size < desired_size) {
1750
1741
                ulint   n_bytes;
1751
1742
 
1752
 
                if (desired_size - current_size < (ib_longlong) buf_size) {
 
1743
                if (desired_size - current_size < (ib_int64_t) buf_size) {
1753
1744
                        n_bytes = (ulint) (desired_size - current_size);
1754
1745
                } else {
1755
1746
                        n_bytes = buf_size;
1765
1756
                }
1766
1757
 
1767
1758
                /* Print about progress for each 100 MB written */
1768
 
                if ((ib_longlong) (current_size + n_bytes) / (ib_longlong)(100 * 1024 * 1024)
1769
 
                    != current_size / (ib_longlong)(100 * 1024 * 1024)) {
 
1759
                if ((ib_int64_t) (current_size + n_bytes) / (ib_int64_t)(100 * 1024 * 1024)
 
1760
                    != current_size / (ib_int64_t)(100 * 1024 * 1024)) {
1770
1761
 
1771
1762
                        fprintf(stderr, " %lu00",
1772
1763
                                (ulong) ((current_size + n_bytes)
1773
 
                                         / (ib_longlong)(100 * 1024 * 1024)));
 
1764
                                         / (ib_int64_t)(100 * 1024 * 1024)));
1774
1765
                }
1775
1766
 
1776
1767
                current_size += n_bytes;
1777
1768
        }
1778
1769
 
1779
 
        if (desired_size >= (ib_longlong)(100 * 1024 * 1024)) {
 
1770
        if (desired_size >= (ib_int64_t)(100 * 1024 * 1024)) {
1780
1771
 
1781
1772
                fprintf(stderr, "\n");
1782
1773
        }
1795
1786
 
1796
1787
/***************************************************************************
1797
1788
Truncates a file at its current position. */
1798
 
 
 
1789
UNIV_INTERN
1799
1790
ibool
1800
1791
os_file_set_eof(
1801
1792
/*============*/
1861
1852
 
1862
1853
/***************************************************************************
1863
1854
Flushes the write buffers of a given file to the disk. */
1864
 
 
 
1855
UNIV_INTERN
1865
1856
ibool
1866
1857
os_file_flush(
1867
1858
/*==========*/
2159
2150
 
2160
2151
/***********************************************************************
2161
2152
Requests a synchronous positioned read operation. */
2162
 
 
 
2153
UNIV_INTERN
2163
2154
ibool
2164
2155
os_file_read(
2165
2156
/*=========*/
2276
2267
/***********************************************************************
2277
2268
Requests a synchronous positioned read operation. This function does not do
2278
2269
any error handling. In case of error it returns FALSE. */
2279
 
 
 
2270
UNIV_INTERN
2280
2271
ibool
2281
2272
os_file_read_no_error_handling(
2282
2273
/*===========================*/
2375
2366
Rewind file to its start, read at most size - 1 bytes from it to str, and
2376
2367
NUL-terminate str. All errors are silently ignored. This function is
2377
2368
mostly meant to be used with temporary files. */
2378
 
 
 
2369
UNIV_INTERN
2379
2370
void
2380
2371
os_file_read_string(
2381
2372
/*================*/
2396
2387
 
2397
2388
/***********************************************************************
2398
2389
Requests a synchronous write operation. */
2399
 
 
 
2390
UNIV_INTERN
2400
2391
ibool
2401
2392
os_file_write(
2402
2393
/*==========*/
2589
2580
 
2590
2581
/***********************************************************************
2591
2582
Check the existence and type of the given file. */
2592
 
 
 
2583
UNIV_INTERN
2593
2584
ibool
2594
2585
os_file_status(
2595
2586
/*===========*/
2661
2652
 
2662
2653
/***********************************************************************
2663
2654
This function returns information about the specified file */
2664
 
 
 
2655
UNIV_INTERN
2665
2656
ibool
2666
2657
os_file_get_status(
2667
2658
/*===============*/
2772
2763
       "."            "."            "."
2773
2764
       ".."           "."            ".."
2774
2765
*/
2775
 
 
 
2766
UNIV_INTERN
2776
2767
char*
2777
2768
os_file_dirname(
2778
2769
/*============*/
2803
2794
 
2804
2795
/********************************************************************
2805
2796
Creates all missing subdirectories along the given path. */
2806
 
 
 
2797
UNIV_INTERN
2807
2798
ibool
2808
2799
os_file_create_subdirs_if_needed(
2809
2800
/*=============================*/
2920
2911
in the three first aio arrays is the parameter n_segments given to the
2921
2912
function. The caller must create an i/o handler thread for each segment in
2922
2913
the four first arrays, but not for the sync aio array. */
2923
 
 
 
2914
UNIV_INTERN
2924
2915
void
2925
2916
os_aio_init(
2926
2917
/*========*/
3028
3019
/****************************************************************************
3029
3020
Wakes up all async i/o threads so that they know to exit themselves in
3030
3021
shutdown. */
3031
 
 
 
3022
UNIV_INTERN
3032
3023
void
3033
3024
os_aio_wake_all_threads_at_shutdown(void)
3034
3025
/*=====================================*/
3053
3044
/****************************************************************************
3054
3045
Waits until there are no pending writes in os_aio_write_array. There can
3055
3046
be other, synchronous, pending writes. */
3056
 
 
 
3047
UNIV_INTERN
3057
3048
void
3058
3049
os_aio_wait_until_no_pending_writes(void)
3059
3050
/*=====================================*/
3389
3380
 
3390
3381
/**************************************************************************
3391
3382
Wakes up simulated aio i/o-handler threads if they have something to do. */
3392
 
 
 
3383
UNIV_INTERN
3393
3384
void
3394
3385
os_aio_simulated_wake_handler_threads(void)
3395
3386
/*=======================================*/
3414
3405
prefers an i/o-handler thread to handle them all at once later. You must
3415
3406
call os_aio_simulated_wake_handler_threads later to ensure the threads
3416
3407
are not left sleeping! */
3417
 
 
 
3408
UNIV_INTERN
3418
3409
void
3419
3410
os_aio_simulated_put_read_threads_to_sleep(void)
3420
3411
/*============================================*/
3436
3427
 
3437
3428
/***********************************************************************
3438
3429
Requests an asynchronous i/o operation. */
3439
 
 
 
3430
UNIV_INTERN
3440
3431
ibool
3441
3432
os_aio(
3442
3433
/*===*/
3641
3632
into segments. The thread specifies which segment or slot it wants to wait
3642
3633
for. NOTE: this function will also take care of freeing the aio slot,
3643
3634
therefore no other thread is allowed to do the freeing! */
3644
 
 
 
3635
UNIV_INTERN
3645
3636
ibool
3646
3637
os_aio_windows_handle(
3647
3638
/*==================*/
3744
3735
/**************************************************************************
3745
3736
This function is only used in Posix asynchronous i/o. Waits for an aio
3746
3737
operation to complete. */
3747
 
 
 
3738
UNIV_INTERN
3748
3739
ibool
3749
3740
os_aio_posix_handle(
3750
3741
/*================*/
3821
3812
#endif
3822
3813
 
3823
3814
/**************************************************************************
3824
 
Do a 'last millisecond' check that the page end is sensible;
3825
 
reported page checksum errors from Linux seem to wipe over the page end. */
3826
 
static
3827
 
void
3828
 
os_file_check_page_trailers(
3829
 
/*========================*/
3830
 
        byte*   combined_buf,   /* in: combined write buffer */
3831
 
        ulint   total_len)      /* in: size of combined_buf, in bytes
3832
 
                                (a multiple of UNIV_PAGE_SIZE) */
3833
 
{
3834
 
        ulint   len;
3835
 
 
3836
 
        for (len = 0; len + UNIV_PAGE_SIZE <= total_len;
3837
 
             len += UNIV_PAGE_SIZE) {
3838
 
                byte*   buf = combined_buf + len;
3839
 
 
3840
 
                if (UNIV_UNLIKELY
3841
 
                    (memcmp(buf + (FIL_PAGE_LSN + 4),
3842
 
                            buf + (UNIV_PAGE_SIZE
3843
 
                                   - FIL_PAGE_END_LSN_OLD_CHKSUM + 4), 4))) {
3844
 
                        ut_print_timestamp(stderr);
3845
 
                        fprintf(stderr,
3846
 
                                "  InnoDB: ERROR: The page to be written"
3847
 
                                " seems corrupt!\n"
3848
 
                                "InnoDB: Writing a block of %lu bytes,"
3849
 
                                " currently at offset %lu\n",
3850
 
                                (ulong)total_len, (ulong)len);
3851
 
                        buf_page_print(buf);
3852
 
                        fprintf(stderr,
3853
 
                                "InnoDB: ERROR: The page to be written"
3854
 
                                " seems corrupt!\n");
3855
 
                }
3856
 
        }
3857
 
}
3858
 
 
3859
 
/**************************************************************************
3860
3815
Does simulated aio. This function should be called by an i/o-handler
3861
3816
thread. */
3862
 
 
 
3817
UNIV_INTERN
3863
3818
ibool
3864
3819
os_aio_simulated_handle(
3865
3820
/*====================*/
4092
4047
 
4093
4048
        /* Do the i/o with ordinary, synchronous i/o functions: */
4094
4049
        if (slot->type == OS_FILE_WRITE) {
4095
 
                if (array == os_aio_write_array) {
4096
 
                        if ((total_len % UNIV_PAGE_SIZE != 0)
4097
 
                            || (slot->offset % UNIV_PAGE_SIZE != 0)) {
4098
 
                                fprintf(stderr,
4099
 
                                        "InnoDB: Error: trying a displaced"
4100
 
                                        " write to %s %lu %lu, len %lu\n",
4101
 
                                        slot->name, (ulong) slot->offset_high,
4102
 
                                        (ulong) slot->offset,
4103
 
                                        (ulong) total_len);
4104
 
                                ut_error;
4105
 
                        }
4106
 
 
4107
 
                        os_file_check_page_trailers(combined_buf, total_len);
4108
 
                }
4109
 
 
4110
4050
                ret = os_file_write(slot->name, slot->file, combined_buf,
4111
4051
                                    slot->offset, slot->offset_high,
4112
4052
                                    total_len);
4113
 
 
4114
 
                if (array == os_aio_write_array) {
4115
 
                        os_file_check_page_trailers(combined_buf, total_len);
4116
 
                }
4117
4053
        } else {
4118
4054
                ret = os_file_read(slot->file, combined_buf,
4119
4055
                                   slot->offset, slot->offset_high, total_len);
4234
4170
 
4235
4171
/**************************************************************************
4236
4172
Validates the consistency the aio system. */
4237
 
 
 
4173
UNIV_INTERN
4238
4174
ibool
4239
4175
os_aio_validate(void)
4240
4176
/*=================*/
4251
4187
 
4252
4188
/**************************************************************************
4253
4189
Prints info of the aio arrays. */
4254
 
 
 
4190
UNIV_INTERN
4255
4191
void
4256
4192
os_aio_print(
4257
4193
/*=========*/
4388
4324
 
4389
4325
/**************************************************************************
4390
4326
Refreshes the statistics used to print per-second averages. */
4391
 
 
 
4327
UNIV_INTERN
4392
4328
void
4393
4329
os_aio_refresh_stats(void)
4394
4330
/*======================*/
4405
4341
/**************************************************************************
4406
4342
Checks that all slots in the system have been freed, that is, there are
4407
4343
no pending io operations. */
4408
 
 
 
4344
UNIV_INTERN
4409
4345
ibool
4410
4346
os_aio_all_slots_free(void)
4411
4347
/*=======================*/