mirror of
https://github.com/denoland/deno.git
synced 2025-01-09 15:48:16 -05:00
perf(fs/windows): stat - only open file once (#27487)
This commit is contained in:
parent
4638caa740
commit
88bd5f09f7
1 changed files with 22 additions and 42 deletions
|
@ -61,7 +61,7 @@ impl FileSystem for RealFs {
|
||||||
umask(Mode::from_bits_truncate(mask as mode_t))
|
umask(Mode::from_bits_truncate(mask as mode_t))
|
||||||
} else {
|
} else {
|
||||||
// If no mask provided, we query the current. Requires two syscalls.
|
// If no mask provided, we query the current. Requires two syscalls.
|
||||||
let prev = umask(Mode::from_bits_truncate(0o777));
|
let prev = umask(Mode::from_bits_truncate(0));
|
||||||
let _ = umask(prev);
|
let _ = umask(prev);
|
||||||
prev
|
prev
|
||||||
};
|
};
|
||||||
|
@ -761,11 +761,16 @@ fn stat(path: &Path) -> FsResult<FsStat> {
|
||||||
|
|
||||||
#[cfg(windows)]
|
#[cfg(windows)]
|
||||||
fn stat(path: &Path) -> FsResult<FsStat> {
|
fn stat(path: &Path) -> FsResult<FsStat> {
|
||||||
let metadata = fs::metadata(path)?;
|
use std::os::windows::fs::OpenOptionsExt;
|
||||||
let mut fsstat = FsStat::from_std(metadata);
|
|
||||||
use winapi::um::winbase::FILE_FLAG_BACKUP_SEMANTICS;
|
use winapi::um::winbase::FILE_FLAG_BACKUP_SEMANTICS;
|
||||||
let path = path.canonicalize()?;
|
|
||||||
stat_extra(&mut fsstat, &path, FILE_FLAG_BACKUP_SEMANTICS)?;
|
let mut opts = fs::OpenOptions::new();
|
||||||
|
opts.access_mode(0); // no read or write
|
||||||
|
opts.custom_flags(FILE_FLAG_BACKUP_SEMANTICS);
|
||||||
|
let file = opts.open(path)?;
|
||||||
|
let metadata = file.metadata()?;
|
||||||
|
let mut fsstat = FsStat::from_std(metadata);
|
||||||
|
stat_extra(&file, &mut fsstat)?;
|
||||||
Ok(fsstat)
|
Ok(fsstat)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -777,34 +782,24 @@ fn lstat(path: &Path) -> FsResult<FsStat> {
|
||||||
|
|
||||||
#[cfg(windows)]
|
#[cfg(windows)]
|
||||||
fn lstat(path: &Path) -> FsResult<FsStat> {
|
fn lstat(path: &Path) -> FsResult<FsStat> {
|
||||||
|
use std::os::windows::fs::OpenOptionsExt;
|
||||||
|
|
||||||
use winapi::um::winbase::FILE_FLAG_BACKUP_SEMANTICS;
|
use winapi::um::winbase::FILE_FLAG_BACKUP_SEMANTICS;
|
||||||
use winapi::um::winbase::FILE_FLAG_OPEN_REPARSE_POINT;
|
use winapi::um::winbase::FILE_FLAG_OPEN_REPARSE_POINT;
|
||||||
|
|
||||||
let metadata = fs::symlink_metadata(path)?;
|
let mut opts = fs::OpenOptions::new();
|
||||||
|
opts.access_mode(0); // no read or write
|
||||||
|
opts.custom_flags(FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OPEN_REPARSE_POINT);
|
||||||
|
let file = opts.open(path)?;
|
||||||
|
let metadata = file.metadata()?;
|
||||||
let mut fsstat = FsStat::from_std(metadata);
|
let mut fsstat = FsStat::from_std(metadata);
|
||||||
stat_extra(
|
stat_extra(&file, &mut fsstat)?;
|
||||||
&mut fsstat,
|
|
||||||
path,
|
|
||||||
FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OPEN_REPARSE_POINT,
|
|
||||||
)?;
|
|
||||||
Ok(fsstat)
|
Ok(fsstat)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(windows)]
|
#[cfg(windows)]
|
||||||
fn stat_extra(
|
fn stat_extra(file: &std::fs::File, fsstat: &mut FsStat) -> FsResult<()> {
|
||||||
fsstat: &mut FsStat,
|
use std::os::windows::io::AsRawHandle;
|
||||||
path: &Path,
|
|
||||||
file_flags: winapi::shared::minwindef::DWORD,
|
|
||||||
) -> FsResult<()> {
|
|
||||||
use std::os::windows::prelude::OsStrExt;
|
|
||||||
|
|
||||||
use winapi::um::fileapi::CreateFileW;
|
|
||||||
use winapi::um::fileapi::OPEN_EXISTING;
|
|
||||||
use winapi::um::handleapi::CloseHandle;
|
|
||||||
use winapi::um::handleapi::INVALID_HANDLE_VALUE;
|
|
||||||
use winapi::um::winnt::FILE_SHARE_DELETE;
|
|
||||||
use winapi::um::winnt::FILE_SHARE_READ;
|
|
||||||
use winapi::um::winnt::FILE_SHARE_WRITE;
|
|
||||||
|
|
||||||
unsafe fn get_dev(
|
unsafe fn get_dev(
|
||||||
handle: winapi::shared::ntdef::HANDLE,
|
handle: winapi::shared::ntdef::HANDLE,
|
||||||
|
@ -873,23 +868,9 @@ fn stat_extra(
|
||||||
|
|
||||||
// SAFETY: winapi calls
|
// SAFETY: winapi calls
|
||||||
unsafe {
|
unsafe {
|
||||||
let mut path: Vec<_> = path.as_os_str().encode_wide().collect();
|
let file_handle = file.as_raw_handle();
|
||||||
path.push(0);
|
|
||||||
let file_handle = CreateFileW(
|
|
||||||
path.as_ptr(),
|
|
||||||
0,
|
|
||||||
FILE_SHARE_READ | FILE_SHARE_DELETE | FILE_SHARE_WRITE,
|
|
||||||
std::ptr::null_mut(),
|
|
||||||
OPEN_EXISTING,
|
|
||||||
file_flags,
|
|
||||||
std::ptr::null_mut(),
|
|
||||||
);
|
|
||||||
if file_handle == INVALID_HANDLE_VALUE {
|
|
||||||
return Err(std::io::Error::last_os_error().into());
|
|
||||||
}
|
|
||||||
|
|
||||||
let result = get_dev(file_handle);
|
fsstat.dev = get_dev(file_handle)?;
|
||||||
fsstat.dev = result?;
|
|
||||||
|
|
||||||
if let Ok(file_info) = query_file_information(file_handle) {
|
if let Ok(file_info) = query_file_information(file_handle) {
|
||||||
fsstat.ctime = Some(windows_time_to_unix_time_msec(
|
fsstat.ctime = Some(windows_time_to_unix_time_msec(
|
||||||
|
@ -928,7 +909,6 @@ fn stat_extra(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
CloseHandle(file_handle);
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue