
Security News
November CVEs Fell 25% YoY, Driven by Slowdowns at Major CNAs
November CVE publications fell 25% YoY even as 2025 totals rose, showing how a few major CNAs can swing βglobalβ counts and skew perceived risk.
Async file I/O for Linux using io_uring.
io_uring is Linux's modern async I/O interface. It's fast and efficient, but the raw API requires managing submission queues, completion queues, memory lifetimes, and substantial unsafe code. This crate builds on io-uring to provide simple async/await file operations at three levels of abstraction.
1. High-level functions β Similar to std::fs, but async. Suitable for scripts, tools, and straightforward file operations.
let contents = uring_file::fs::read_to_string("config.toml").await?;
2. The default ring β The UringFile trait works on any file handle. Useful when you have files opened elsewhere and want io_uring performance without managing a ring.
use uring_file::UringFile;
let file = std::fs::File::open("data.bin")?;
let result = file.ur_read_at(0, 4096).await?;
3. Custom rings β Full control over ring configuration. Configure queue size, enable kernel polling, register files for faster repeated access.
use uring_file::uring::{Uring, UringCfg};
let ring = Uring::new(UringCfg {
entries: 256,
kernel_poll: true,
..Default::default()
})?;
All three use the same underlying io_uring implementation. Uring is Clone + Send + Sync, and path arguments accept any type implementing AsRef<Path>.
[dependencies]
uring-file = "0.4"
tokio = { version = "1", features = ["rt", "macros"] }
use uring_file::fs;
#[tokio::main]
async fn main() -> std::io::Result<()> {
fs::write("/tmp/hello.txt", "Hello!").await?;
let text = fs::read_to_string("/tmp/hello.txt").await?;
fs::create_dir_all("/tmp/a/b/c").await?;
fs::remove_dir_all("/tmp/a").await?;
Ok(())
}
See docs.rs for full documentation.
uring_file::fs β high-level convenience// Reading
fs::read(path).await?; // -> Vec<u8>
fs::read_to_string(path).await?; // -> String
// Writing
fs::write(path, data).await?; // create or truncate
fs::append(path, data).await?; // create or append
fs::copy(src, dst).await?; // -> bytes copied
// Opening files (returns tokio::fs::File)
let file = fs::open(path).await?; // read-only
let file = fs::create(path).await?; // write, create/truncate
// OpenOptions for more control
let file = fs::OpenOptions::new()
.read(true)
.write(true)
.create(true)
.open(path).await?;
// Directories
fs::create_dir(path).await?;
fs::create_dir_all(path).await?;
fs::remove_dir(path).await?;
fs::remove_dir_all(path).await?;
// Files and links
fs::remove_file(path).await?;
fs::rename(from, to).await?;
fs::symlink(target, link).await?;
fs::hard_link(original, link).await?;
fs::truncate(path, len).await?;
// Metadata
fs::metadata(path).await?; // -> Metadata
fs::exists(path).await; // -> bool
UringFile trait β for existing file handlesWorks with std::fs::File and tokio::fs::File:
use uring_file::UringFile;
let file = std::fs::File::open("data.bin")?;
// Positioned I/O
let result = file.ur_read_at(offset, len).await?;
let result = file.ur_write_at(offset, data).await?;
// Durability
file.ur_sync().await?; // fsync
file.ur_datasync().await?; // fdatasync
// Metadata and space management
file.ur_statx().await?;
file.ur_fallocate(offset, len, mode).await?;
file.ur_fadvise(offset, len, advice).await?;
file.ur_ftruncate(len).await?;
Uring β full controluse uring_file::uring::{Uring, UringCfg};
let ring = Uring::new(UringCfg {
entries: 256, // submission queue size
kernel_poll: true, // SQPOLL for lower latency
..Default::default()
})?;
// File operations
let fd = ring.open("/tmp/file", libc::O_RDWR | libc::O_CREAT, 0o644).await?;
ring.write_at(&fd, 0, b"hello".to_vec()).await?;
ring.read_at(&fd, 0, 5).await?;
ring.close(fd).await?;
// Path operations
ring.mkdir("/tmp/dir", 0o755).await?;
ring.rename("/tmp/a", "/tmp/b").await?;
ring.unlink("/tmp/file").await?;
// Registered files for faster repeated access
let registered = ring.register(&file)?;
ring.read_at(®istered, 0, 1024).await?;
| Feature | Minimum kernel |
|---|---|
| Basic read/write/sync | 5.1 |
| open, statx, fallocate, fadvise | 5.6 |
| close, rename, unlink, mkdir, symlink, link | 5.11 |
| ftruncate | 6.9 |
No readdir in io_uring β remove_dir_all uses tokio for directory listing, then io_uring for deletions. This is a kernel limitation.
~2GB per operation β Single read/write operations are limited to approximately 2GB (uring::URING_LEN_MAX). Chunk larger transfers.
βββββββββββββββ βββββββββββββββββββββ βββββββββββββββ
β Async tasks ββββββΆβ Submission thread ββββββΆβ io_uring β
βββββββββββββββ βββββββββββββββββββββ ββββββββ¬βββββββ
β² β
β βββββββββββββββββββββ β
ββββββββββββββ Completion thread ββββββββββββββ
βββββββββββββββββββββ
Async tasks send requests to a submission thread that batches them into the io_uring submission queue. A completion thread polls for results and wakes the appropriate futures.
MIT OR Apache-2.0
FAQs
Unknown package
We found that uring-file demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago.Β It has 1 open source maintainer collaborating on the project.
Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Security News
November CVE publications fell 25% YoY even as 2025 totals rose, showing how a few major CNAs can swing βglobalβ counts and skew perceived risk.

Security News
React disclosed a CVSS 10.0 RCE in React Server Components and is advising users to upgrade affected packages and frameworks to patched versions now.

Research
/Security News
We spotted a wave of auto-generated βelf-*β npm packages published every two minutes from new accounts, with simple malware variants and early takedowns underway.