scsi(windows): only sleep on successful device reset
SptiTransport::reset() unconditionally slept 2 seconds after sending IOCTL_STORAGE_RESET_DEVICE, even when the IOCTL failed (e.g. ERROR_INVALID_FUNCTION on a driver that does not support the reset). On failure no reset occurred, so there is nothing to settle and the 2-second penalty was pure waste. Gate the settle sleep on the IOCTL return so it only fires when the drive was actually reset.
This commit is contained in:
+11
-5
@@ -279,23 +279,29 @@ impl SptiTransport {
|
||||
std::ptr::null_mut(),
|
||||
)
|
||||
};
|
||||
if ok == 0 {
|
||||
let reset_ok = ok != 0;
|
||||
if reset_ok {
|
||||
tracing::debug!("IOCTL_STORAGE_RESET_DEVICE succeeded");
|
||||
} else {
|
||||
let err = unsafe { GetLastError() };
|
||||
// Not fatal — the caller treats reset as best-effort — but a
|
||||
// failing reset (especially ERROR_INVALID_FUNCTION = 1) means the
|
||||
// device was NOT reset despite the settle sleep that follows.
|
||||
// device was NOT reset, so there is nothing to settle and we must
|
||||
// not pay the settle-sleep penalty below.
|
||||
tracing::warn!(
|
||||
last_error = err,
|
||||
ioctl = format_args!("{IOCTL_STORAGE_RESET_DEVICE:#010x}"),
|
||||
"IOCTL_STORAGE_RESET_DEVICE failed; drive not reset"
|
||||
);
|
||||
} else {
|
||||
tracing::debug!("IOCTL_STORAGE_RESET_DEVICE succeeded");
|
||||
}
|
||||
|
||||
// Close and wait for drive to settle
|
||||
// Close the handle, then — only if the reset actually happened — wait
|
||||
// for the drive to settle. A failed IOCTL reset performed no reset, so
|
||||
// sleeping would burn 2 s for nothing.
|
||||
unsafe { CloseHandle(handle) };
|
||||
if reset_ok {
|
||||
std::thread::sleep(std::time::Duration::from_secs(2));
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user