summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVladislav Vaintroub <wlad@mariadb.com>2019-05-03 12:58:11 +0000
committerVladislav Vaintroub <wlad@mariadb.com>2019-05-06 10:15:46 +0000
commitc477623f047e971f1833076d62bff1647d6e9b0b (patch)
tree3f5d46c073d3ea1a5db48785add0208f30bdcbbb
parentf81007f8d80aca1c7afc709bd2c6d20eeebc0248 (diff)
downloadmariadb-git-c477623f047e971f1833076d62bff1647d6e9b0b.tar.gz
MDEV-19388 Improve SSD detection on Windows
Fallback to detecting if TRIM is enabled, if we cannot determine seek penalty.
-rw-r--r--storage/innobase/os/os0file.cc132
1 files changed, 72 insertions, 60 deletions
diff --git a/storage/innobase/os/os0file.cc b/storage/innobase/os/os0file.cc
index 77f5ba7c113..6a86d902c96 100644
--- a/storage/innobase/os/os0file.cc
+++ b/storage/innobase/os/os0file.cc
@@ -7502,6 +7502,75 @@ os_file_set_umask(ulint umask)
os_innodb_umask = umask;
}
+#ifdef _WIN32
+static int win32_get_block_size(HANDLE volume_handle, const char *volume_name)
+{
+ STORAGE_ACCESS_ALIGNMENT_DESCRIPTOR disk_alignment;
+ STORAGE_PROPERTY_QUERY storage_query;
+ DWORD tmp;
+
+ memset(&storage_query, 0, sizeof(storage_query));
+ storage_query.PropertyId = StorageAccessAlignmentProperty;
+ storage_query.QueryType = PropertyStandardQuery;
+
+ if (os_win32_device_io_control(volume_handle,
+ IOCTL_STORAGE_QUERY_PROPERTY,
+ &storage_query,
+ sizeof storage_query,
+ &disk_alignment,
+ sizeof disk_alignment,
+ &tmp) && tmp == sizeof disk_alignment) {
+ return disk_alignment.BytesPerPhysicalSector;
+ }
+
+ switch (GetLastError()) {
+ case ERROR_INVALID_FUNCTION:
+ case ERROR_NOT_SUPPORTED:
+ break;
+ default:
+ os_file_handle_error_no_exit(
+ volume_name,
+ "DeviceIoControl(IOCTL_STORAGE_QUERY_PROPERTY / StorageAccessAlignmentProperty)",
+ FALSE);
+ }
+ return 512;
+}
+
+static bool win32_is_ssd(HANDLE volume_handle)
+{
+ DWORD tmp;
+ DEVICE_SEEK_PENALTY_DESCRIPTOR seek_penalty;
+ STORAGE_PROPERTY_QUERY storage_query;
+ memset(&storage_query, 0, sizeof(storage_query));
+
+ storage_query.PropertyId = StorageDeviceSeekPenaltyProperty;
+ storage_query.QueryType = PropertyStandardQuery;
+
+ if (os_win32_device_io_control(volume_handle,
+ IOCTL_STORAGE_QUERY_PROPERTY,
+ &storage_query,
+ sizeof storage_query,
+ &seek_penalty,
+ sizeof seek_penalty,
+ &tmp) && tmp == sizeof(seek_penalty)){
+ return !seek_penalty.IncursSeekPenalty;
+ }
+
+ DEVICE_TRIM_DESCRIPTOR trim;
+ storage_query.PropertyId = StorageDeviceTrimProperty;
+ if (os_win32_device_io_control(volume_handle,
+ IOCTL_STORAGE_QUERY_PROPERTY,
+ &storage_query,
+ sizeof storage_query,
+ &trim,
+ sizeof trim,
+ &tmp) && tmp == sizeof trim) {
+ return trim.TrimEnabled;
+ }
+ return false;
+}
+#endif
+
/** Determine some file metadata when creating or reading the file.
@param file the file that is being created, or OS_FILE_CLOSED */
void fil_node_t::find_metadata(os_file_t file
@@ -7559,66 +7628,9 @@ void fil_node_t::find_metadata(os_file_t file
0, OPEN_EXISTING, 0, 0);
if (volume_handle != INVALID_HANDLE_VALUE) {
- DWORD tmp;
- union {
- STORAGE_ACCESS_ALIGNMENT_DESCRIPTOR disk_alignment;
- DEVICE_SEEK_PENALTY_DESCRIPTOR seek_penalty;
- } result;
- STORAGE_PROPERTY_QUERY storage_query;
- memset(&storage_query, 0, sizeof(storage_query));
- storage_query.PropertyId = StorageAccessAlignmentProperty;
- storage_query.QueryType = PropertyStandardQuery;
-
- if (!os_win32_device_io_control(volume_handle,
- IOCTL_STORAGE_QUERY_PROPERTY,
- &storage_query,
- sizeof storage_query,
- &result.disk_alignment,
- sizeof result.disk_alignment,
- &tmp)
- || tmp < sizeof result.disk_alignment) {
- switch (GetLastError()) {
- case ERROR_INVALID_FUNCTION:
- case ERROR_NOT_SUPPORTED:
- break;
- default:
- ioctl_fail:
- os_file_handle_error_no_exit(
- volume,
- "DeviceIoControl(IOCTL_STORAGE_QUERY_PROPERTY)",
- FALSE);
- }
- goto end;
- }
-
- block_size = result.disk_alignment.BytesPerPhysicalSector;
-
- storage_query.PropertyId = StorageDeviceSeekPenaltyProperty;
- storage_query.QueryType = PropertyStandardQuery;
-
- if (!os_win32_device_io_control(volume_handle,
- IOCTL_STORAGE_QUERY_PROPERTY,
- &storage_query,
- sizeof storage_query,
- &result.seek_penalty,
- sizeof result.seek_penalty,
- &tmp)
- || tmp < sizeof result.seek_penalty) {
- switch (GetLastError()) {
- case ERROR_INVALID_FUNCTION:
- case ERROR_NOT_SUPPORTED:
- case ERROR_GEN_FAILURE:
- goto end;
- default:
- goto ioctl_fail;
- }
- }
-
- on_ssd = !result.seek_penalty.IncursSeekPenalty;
-end:
- if (volume_handle != INVALID_HANDLE_VALUE) {
- CloseHandle(volume_handle);
- }
+ block_size = win32_get_block_size(volume_handle, volume);
+ on_ssd = win32_is_ssd(volume_handle);
+ CloseHandle(volume_handle);
} else {
if (GetLastError() != ERROR_ACCESS_DENIED) {
os_file_handle_error_no_exit(volume,