diff options
author | Vladislav Vaintroub <wlad@mariadb.com> | 2019-05-03 12:58:11 +0000 |
---|---|---|
committer | Vladislav Vaintroub <wlad@mariadb.com> | 2019-05-06 10:15:46 +0000 |
commit | c477623f047e971f1833076d62bff1647d6e9b0b (patch) | |
tree | 3f5d46c073d3ea1a5db48785add0208f30bdcbbb | |
parent | f81007f8d80aca1c7afc709bd2c6d20eeebc0248 (diff) | |
download | mariadb-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.cc | 132 |
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, |