Fix windows inode to use u128 (#6377)

This commit is contained in:
Jeong, YunWon
2025-12-09 23:40:54 +09:00
committed by GitHub
parent 6003c87582
commit 8bc46cf83d
2 changed files with 37 additions and 8 deletions

View File

@@ -510,7 +510,9 @@ pub(super) mod _os {
lstat: OnceCell<PyObjectRef>,
#[cfg(unix)]
ino: AtomicCell<u64>,
#[cfg(not(unix))]
#[cfg(windows)]
ino: AtomicCell<Option<u128>>,
#[cfg(not(any(unix, windows)))]
ino: AtomicCell<Option<u64>>,
}
@@ -608,9 +610,9 @@ pub(super) mod _os {
Ok(stat.clone())
}
#[cfg(not(unix))]
#[cfg(windows)]
#[pymethod]
fn inode(&self, vm: &VirtualMachine) -> PyResult<u64> {
fn inode(&self, vm: &VirtualMachine) -> PyResult<u128> {
match self.ino.load() {
Some(ino) => Ok(ino),
None => {
@@ -625,9 +627,14 @@ pub(super) mod _os {
)
.map_err(|e| e.into_pyexception(vm))?
.ok_or_else(|| crate::exceptions::cstring_error(vm))?;
// On Windows, combine st_ino and st_ino_high into 128-bit value
#[cfg(windows)]
let ino: u128 = stat.st_ino as u128 | ((stat.st_ino_high as u128) << 64);
#[cfg(not(windows))]
let ino: u128 = stat.st_ino as u128;
// Err(T) means other thread set `ino` at the mean time which is safe to ignore
let _ = self.ino.compare_exchange(None, Some(stat.st_ino));
Ok(stat.st_ino)
let _ = self.ino.compare_exchange(None, Some(ino));
Ok(ino)
}
}
}
@@ -638,6 +645,12 @@ pub(super) mod _os {
Ok(self.ino.load())
}
#[cfg(not(any(unix, windows)))]
#[pymethod]
fn inode(&self, _vm: &VirtualMachine) -> PyResult<Option<u64>> {
Ok(self.ino.load())
}
#[cfg(not(windows))]
#[pymethod]
const fn is_junction(&self, _vm: &VirtualMachine) -> PyResult<bool> {
@@ -737,6 +750,12 @@ pub(super) mod _os {
use std::os::unix::fs::DirEntryExt;
entry.ino()
};
// TODO: wasi is nightly
// #[cfg(target_os = "wasi")]
// let ino = {
// use std::os::wasi::fs::DirEntryExt;
// entry.ino()
// };
#[cfg(not(unix))]
let ino = None;
@@ -882,9 +901,16 @@ pub(super) mod _os {
#[cfg(not(windows))]
let st_file_attributes = 0;
// On Windows, combine st_ino and st_ino_high into a 128-bit value
// like _pystat_l128_from_l64_l64
#[cfg(windows)]
let st_ino: u128 = stat.st_ino as u128 | ((stat.st_ino_high as u128) << 64);
#[cfg(not(windows))]
let st_ino = stat.st_ino;
Self {
st_mode: vm.ctx.new_pyref(stat.st_mode),
st_ino: vm.ctx.new_pyref(stat.st_ino),
st_ino: vm.ctx.new_pyref(st_ino),
st_dev: vm.ctx.new_pyref(stat.st_dev),
st_nlink: vm.ctx.new_pyref(stat.st_nlink),
st_uid: vm.ctx.new_pyref(stat.st_uid),

View File

@@ -515,8 +515,11 @@ fn win32_xstat_impl(path: &OsStr, traverse: bool) -> std::io::Result<StatStruct>
{
let mut result =
crate::common::fileutils::windows::stat_basic_info_to_stat(&stat_info);
result.update_st_mode_from_path(path, stat_info.FileAttributes);
return Ok(result);
// If st_ino is 0, fall through to slow path to get proper file ID
if result.st_ino != 0 || result.st_ino_high != 0 {
result.update_st_mode_from_path(path, stat_info.FileAttributes);
return Ok(result);
}
}
}
Err(e) => {