summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVladislav Vaintroub <wlad@mariadb.com>2017-10-27 23:42:02 +0000
committerVladislav Vaintroub <wlad@mariadb.com>2017-10-27 23:42:02 +0000
commit97df230aed24dc9ba1990c955c083c2d53d1f723 (patch)
treebee593403fc6c189f132288e745e1f082073ac80
parent067f83969caca50d95492a01f4af22176abf7ff2 (diff)
downloadmariadb-git-97df230aed24dc9ba1990c955c083c2d53d1f723.tar.gz
MDEV-14115 : Do not use lpNumberOfBytesRead/Written params in
ReadFile/WriteFile operations. Innodb opens files with FILE_FLAG_OVERLAPPED. lpNumberOfBytesRead/Written are documented to be potentially inaccurate in this case, (possibly even if async operations complete synchronously?) The fix is to always pass NULL for the correspondng parameters, as recommended by MSDN. Read the actual counts with GetQueuedCompletionStatus() or GetOverlappedResult().
-rw-r--r--storage/innobase/os/os0file.cc23
1 files changed, 11 insertions, 12 deletions
diff --git a/storage/innobase/os/os0file.cc b/storage/innobase/os/os0file.cc
index 65affe7638d..44b78dabf87 100644
--- a/storage/innobase/os/os0file.cc
+++ b/storage/innobase/os/os0file.cc
@@ -775,9 +775,9 @@ os_win32_device_io_control(
OVERLAPPED overlapped = { 0 };
overlapped.hEvent = win_get_syncio_event();
BOOL result = DeviceIoControl(handle, code, inbuf, inbuf_size, outbuf,
- outbuf_size, bytes_returned, &overlapped);
+ outbuf_size, NULL, &overlapped);
- if (!result && (GetLastError() == ERROR_IO_PENDING)) {
+ if (result || (GetLastError() == ERROR_IO_PENDING)) {
/* Wait for async io to complete */
result = GetOverlappedResult(handle, &overlapped, bytes_returned, TRUE);
}
@@ -3451,14 +3451,14 @@ SyncFileIO::execute(const IORequest& request)
if (request.is_read()) {
ret = ReadFile(m_fh, m_buf,
- static_cast<DWORD>(m_n), &n_bytes, &seek);
+ static_cast<DWORD>(m_n), NULL, &seek);
} else {
ut_ad(request.is_write());
ret = WriteFile(m_fh, m_buf,
- static_cast<DWORD>(m_n), &n_bytes, &seek);
+ static_cast<DWORD>(m_n), NULL, &seek);
}
- if (!ret && (GetLastError() == ERROR_IO_PENDING)) {
+ if (ret || (GetLastError() == ERROR_IO_PENDING)) {
/* Wait for async io to complete */
ret = GetOverlappedResult(m_fh, &seek, &n_bytes, TRUE);
}
@@ -3478,17 +3478,17 @@ SyncFileIO::execute(Slot* slot)
ret = ReadFile(
slot->file, slot->ptr, slot->len,
- &slot->n_bytes, &slot->control);
+ NULL, &slot->control);
} else {
ut_ad(slot->type.is_write());
ret = WriteFile(
slot->file, slot->ptr, slot->len,
- &slot->n_bytes, &slot->control);
+ NULL, &slot->control);
}
- if (!ret && (GetLastError() == ERROR_IO_PENDING)) {
+ if (ret || (GetLastError() == ERROR_IO_PENDING)) {
/* Wait for async io to complete */
ret = GetOverlappedResult(slot->file, &slot->control, &slot->n_bytes, TRUE);
}
@@ -6725,7 +6725,7 @@ try_again:
#ifdef WIN_ASYNC_IO
ret = ReadFile(
file, slot->ptr, slot->len,
- &slot->n_bytes, &slot->control);
+ NULL, &slot->control);
#elif defined(LINUX_NATIVE_AIO)
if (!array->linux_dispatch(slot)) {
goto err_exit;
@@ -6743,7 +6743,7 @@ try_again:
#ifdef WIN_ASYNC_IO
ret = WriteFile(
file, slot->ptr, slot->len,
- &slot->n_bytes, &slot->control);
+ NULL, &slot->control);
#elif defined(LINUX_NATIVE_AIO)
if (!array->linux_dispatch(slot)) {
goto err_exit;
@@ -6759,8 +6759,7 @@ try_again:
}
#ifdef WIN_ASYNC_IO
- if ((ret && slot->len == slot->n_bytes)
- || (!ret && GetLastError() == ERROR_IO_PENDING)) {
+ if (ret || (GetLastError() == ERROR_IO_PENDING)) {
/* aio completed or was queued successfully! */
return(DB_SUCCESS);
}