diff options
author | Vladislav Vaintroub <wlad@mariadb.com> | 2016-10-25 12:21:53 +0000 |
---|---|---|
committer | Vladislav Vaintroub <wlad@mariadb.com> | 2016-10-25 12:23:34 +0000 |
commit | ba11dd69fee7b82edf4e6afbb13e3fa94cd885ca (patch) | |
tree | 9f8e14797ece671f27bca1efa592ff60588fffef /extra | |
parent | 3321f1adc74b54e7534000c06eeca166730ccc4a (diff) | |
download | mariadb-git-ba11dd69fee7b82edf4e6afbb13e3fa94cd885ca.tar.gz |
MDEV-11127 : Fix innochecksum to work with large files on Windows.
- don't use stat() for file size, it doesn not handle large size
use GetFileSizeEx() instead
- don't use lseek(), it can't handle large files, use _lseeki64() instead.
- Also, switch off OS file buffering for innochecksum on Windows,
to avoid thrashing file cache.
Diffstat (limited to 'extra')
-rw-r--r-- | extra/innochecksum.cc | 55 |
1 files changed, 50 insertions, 5 deletions
diff --git a/extra/innochecksum.cc b/extra/innochecksum.cc index 6018a4884ea..97d47b4563a 100644 --- a/extra/innochecksum.cc +++ b/extra/innochecksum.cc @@ -243,10 +243,9 @@ int main(int argc, char **argv) time_t lastt; /* last time */ ulint oldcsum, oldcsumfield, csum, csumfield, crc32, logseq, logseqfield; /* ulints for checksum storage */ - struct stat st; /* for stat, if you couldn't guess */ unsigned long long int size; /* size of file (has to be 64 bits) */ ulint pages; /* number of pages in file */ - off_t offset= 0; + unsigned long long offset= 0; int fd; printf("InnoDB offline file checksum utility.\n"); @@ -269,6 +268,47 @@ int main(int argc, char **argv) goto error; } +#ifdef _WIN32 + /* Switch off OS file buffering for the file. */ + + HANDLE h = CreateFile(filename, GENERIC_READ, + FILE_SHARE_READ|FILE_SHARE_WRITE, 0, + OPEN_EXISTING, FILE_FLAG_NO_BUFFERING, 0); + + if (!h) + { + fprintf(stderr, "Error; cant open file\n"); + goto error; + } + + if (!GetFileSizeEx(h, (LARGE_INTEGER *)&size)) + { + fprintf(stderr, "Error; GetFileSize() failed\n"); + goto error; + } + + fd = _open_osfhandle ((intptr_t) h, _O_RDONLY); + if (fd < 0) + { + fprintf(stderr, "Error; _open_osfhandle() failed\n"); + goto error; + } + + f = _fdopen(fd, "rb"); + if (!f) + { + fprintf(stderr, "Error; fdopen() failed\n"); + goto error; + } + + /* + Disable stdio buffering (FILE_FLAG_NO_BUFFERING requires properly IO buffers + which stdio does not guarantee. + */ + setvbuf(f, NULL, _IONBF, 0); + +#else + struct stat st; /* stat the file to get size and page count */ if (stat(filename, &st)) { @@ -279,6 +319,8 @@ int main(int argc, char **argv) /* Open the file for reading */ f= fopen(filename, "rb"); +#endif + if (f == NULL) { fprintf(stderr, "Error; %s cannot be opened", filename); @@ -323,7 +365,7 @@ int main(int argc, char **argv) } else if (verbose) { - printf("file %s = %llu bytes (%lu pages)...\n", filename, size, pages); + printf("file %s = %llu bytes (%lu pages)...\n", filename, size, (ulong)pages); if (do_one_page) printf("InnoChecksum; checking page %lu\n", do_page); else @@ -348,9 +390,12 @@ int main(int argc, char **argv) goto error; } - offset= (off_t)start_page * (off_t)physical_page_size; - + offset= (ulonglong)start_page * (ulonglong)physical_page_size; +#ifdef _WIN32 + if (_lseeki64(fd, offset, SEEK_SET) != offset) +#else if (lseek(fd, offset, SEEK_SET) != offset) +#endif { perror("Error; Unable to seek to necessary offset"); goto error; |