{"record":{"id":"a89c2cc6c3db4514","repo":"ClementTsang/bottom","slug":"device-i-o-error-err","errorCode":null,"errorMessage":"Device I/O error: {err:?}","messagePattern":"Device I/O error: (.+?)","errorType":"error_code","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"src/collection/disks/windows/bindings.rs","lineNumber":87,"sourceCode":"            h_device,\n            IOCTL_DISK_PERFORMANCE,\n            None,\n            0,\n            Some(&mut disk_performance as *mut _ as _),\n            mem::size_of::<DISK_PERFORMANCE>() as u32,\n            Some(&mut bytes_returned),\n            None,\n        )\n    };\n\n    // SAFETY: This should be safe, we will check the result as well.\n    let handle_result = unsafe { CloseHandle(h_device) };\n    if let Err(err) = handle_result {\n        bail!(\"Handle error: {err:?}\");\n    }\n\n    if let Err(err) = ret {\n        bail!(\"Device I/O error: {err:?}\");\n    } else {\n        Ok(disk_performance)\n    }\n}\n\nfn current_volume(buffer: &[u16]) -> PathBuf {\n    let first_null = buffer.iter().position(|byte| *byte == 0x00).unwrap_or(0);\n    let path_string = OsString::from_wide(&buffer[..first_null]);\n\n    PathBuf::from(path_string)\n}\n\nfn close_find_handle(handle: HANDLE) -> anyhow::Result<()> {\n    // Clean up the handle.\n    // SAFETY: This should be safe, we will check the result as well.\n    let res = unsafe { FindVolumeClose(handle) };\n    Ok(res?)\n}","sourceCodeStart":69,"sourceCodeEnd":105,"githubUrl":"https://github.com/ClementTsang/bottom/blob/b77d3175028849824e987c35177e8f61450d72e7/src/collection/disks/windows/bindings.rs#L69-L105","documentation":"The DeviceIoControl call with IOCTL_DISK_PERFORMANCE failed inside volume_io, so the DISK_PERFORMANCE counters could not be read from the volume. The handle was successfully opened and closed; only the control-code query failed. This means the OS refused or could not service the disk-performance request for that volume.","triggerScenarios":"DeviceIoControl returns Err — most commonly ERROR_INVALID_FUNCTION because disk performance counters are disabled on the system, or the output buffer/size was rejected, or the volume does not support the IOCTL.","commonSituations":"Windows systems where 'diskperf -n' was never enabled (counters off by default on some configs/skylines); virtualized or network volumes that do not implement IOCTL_DISK_PERFORMANCE; collecting stats on dynamic/foreign disks.","solutions":["Enable disk performance counters by running 'diskperf -n' (as Administrator) and retry","Check the wrapped err for the Win32 code — ERROR_INVALID_FUNCTION (1) means the IOCTL/volume combination is unsupported","Skip volumes that do not support the IOCTL and aggregate only the ones that do","Verify the volume is a physical/local disk, not a mapped network or virtual volume"],"exampleFix":"// before\nif let Err(err) = ret {\n    bail!(\"Device I/O error: {err:?}\");\n}\n// after\nif let Err(err) = ret {\n    if err.code() == HRESULT::from_win32(ERROR_INVALID_FUNCTION) {\n        return Ok(DISK_PERFORMANCE::default()); // counters unsupported/disabled\n    }\n    bail!(\"Device I/O error: {err:?}\");\n}","handlingStrategy":"fallback","validationCode":"// enable counters beforehand (requires admin):\n// run `diskperf -n` once on the target machine\n","typeGuard":null,"tryCatchPattern":"match volume_io(&volume) {\n    Ok(stats) => Some(stats),\n    Err(e) if e.to_string().contains(\"Device I/O error\") => None, // unsupported\n    Err(e) => return Err(e),\n}","preventionTips":["Enable disk performance counters with `diskperf -n` on machines you monitor","Expect IOCTL_DISK_PERFORMANCE to be unsupported on network/virtual volumes","Model disk stats as Option rather than assuming every volume reports them"],"tags":["windows","win32","deviceiocontrol","disk-io"],"backgroundTag":"api-error-response","analyzedSha":"b77d3175028849824e987c35177e8f61450d72e7","analyzedAt":"2026-09-07T14:53:21.246Z","contentChangedAt":"2026-09-07T14:53:21.246Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}