Skip to content

Commit 1380ac2

Browse files
authored
perf: optimize FileSystem metadata operations with rustix (#800)
## Summary Optimizes FileSystem::metadata and FileSystem::symlink_metadata operations using rustix for significant performance improvements on Unix platforms.
1 parent 961929c commit 1380ac2

File tree

3 files changed

+66
-20
lines changed

3 files changed

+66
-20
lines changed

Cargo.lock

Lines changed: 33 additions & 3 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,9 @@ url = "2"
9999
[target.'cfg(any(target_os = "macos", target_os = "linux"))'.dependencies]
100100
libc = "0.2"
101101

102+
[target.'cfg(target_os = "linux")'.dependencies]
103+
rustix = { version = "1.1.2", features = ["fs"] }
104+
102105
[target.'cfg(target_os = "windows")'.dependencies]
103106
windows = { version = "0.62.2", features = ["Win32_Storage_FileSystem"] }
104107

src/file_system.rs

Lines changed: 30 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -167,17 +167,21 @@ impl FileSystemOs {
167167
/// See [std::fs::metadata]
168168
#[inline]
169169
pub fn metadata(path: &Path) -> io::Result<FileMetadata> {
170-
#[cfg(target_os = "windows")]
171-
{
172-
let result = crate::windows::symlink_metadata(path)?;
173-
if result.is_symlink {
174-
return fs::metadata(path).map(FileMetadata::from);
170+
cfg_if! {
171+
if #[cfg(target_os = "windows")] {
172+
let result = crate::windows::symlink_metadata(path)?;
173+
if result.is_symlink {
174+
return fs::metadata(path).map(FileMetadata::from);
175+
}
176+
Ok(result.into())
177+
} else if #[cfg(target_os = "linux")] {
178+
use rustix::fs::{AtFlags, CWD, FileType, StatxFlags};
179+
let statx = rustix::fs::statx(CWD, path, AtFlags::STATX_DONT_SYNC, StatxFlags::TYPE)?;
180+
let file_type = FileType::from_raw_mode(statx.stx_mode.into());
181+
Ok(FileMetadata::new(file_type.is_file(), file_type.is_dir(), file_type.is_symlink()))
182+
} else {
183+
fs::metadata(path).map(FileMetadata::from)
175184
}
176-
Ok(result.into())
177-
}
178-
#[cfg(not(target_os = "windows"))]
179-
{
180-
fs::metadata(path).map(FileMetadata::from)
181185
}
182186
}
183187

@@ -186,13 +190,22 @@ impl FileSystemOs {
186190
/// See [std::fs::symlink_metadata]
187191
#[inline]
188192
pub fn symlink_metadata(path: &Path) -> io::Result<FileMetadata> {
189-
#[cfg(target_os = "windows")]
190-
{
191-
Ok(crate::windows::symlink_metadata(path)?.into())
192-
}
193-
#[cfg(not(target_os = "windows"))]
194-
{
195-
fs::symlink_metadata(path).map(FileMetadata::from)
193+
cfg_if! {
194+
if #[cfg(target_os = "windows")] {
195+
Ok(crate::windows::symlink_metadata(path)?.into())
196+
} else if #[cfg(target_os = "linux")] {
197+
use rustix::fs::{AtFlags, CWD, FileType, StatxFlags};
198+
let statx = rustix::fs::statx(
199+
CWD,
200+
path,
201+
AtFlags::STATX_DONT_SYNC | AtFlags::SYMLINK_NOFOLLOW,
202+
StatxFlags::TYPE,
203+
)?;
204+
let file_type = FileType::from_raw_mode(statx.stx_mode.into());
205+
Ok(FileMetadata::new(file_type.is_file(), file_type.is_dir(), file_type.is_symlink()))
206+
} else {
207+
fs::symlink_metadata(path).map(FileMetadata::from)
208+
}
196209
}
197210
}
198211

0 commit comments

Comments
 (0)