{"id":51601289,"url":"https://github.com/rustfs/uring","last_synced_at":"2026-07-11T22:30:39.454Z","repository":{"id":370654415,"uuid":"1295450728","full_name":"rustfs/uring","owner":"rustfs","description":"Cancel-safe async io_uring read backend for RustFS storage (P2, rustfs/backlog#894/#1048). Standalone crate: rustfs-uring.","archived":false,"fork":false,"pushed_at":"2026-07-10T04:58:41.000Z","size":49,"stargazers_count":1,"open_issues_count":1,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-07-10T05:09:07.138Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Rust","has_issues":false,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/rustfs.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-07-09T15:16:09.000Z","updated_at":"2026-07-10T03:49:59.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/rustfs/uring","commit_stats":null,"previous_names":["rustfs/uring"],"tags_count":null,"template":false,"template_full_name":null,"purl":"pkg:github/rustfs/uring","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rustfs%2Furing","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rustfs%2Furing/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rustfs%2Furing/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rustfs%2Furing/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/rustfs","download_url":"https://codeload.github.com/rustfs/uring/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rustfs%2Furing/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":35377012,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-07-11T02:00:05.354Z","response_time":104,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2026-07-11T22:30:38.645Z","updated_at":"2026-07-11T22:30:39.438Z","avatar_url":"https://github.com/rustfs.png","language":"Rust","funding_links":[],"categories":[],"sub_categories":[],"readme":"# rustfs-uring\n\n[![CI](https://github.com/rustfs/uring/actions/workflows/ci.yml/badge.svg)](https://github.com/rustfs/uring/actions/workflows/ci.yml)\n[![license](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://github.com/rustfs/uring/blob/main/LICENSE)\n[![crates](https://img.shields.io/crates/v/rustfs-uring.svg)](https://crates.io/crates/rustfs-uring)\n[![docs.rs](https://docs.rs/rustfs-uring/badge.svg)](https://docs.rs/rustfs-uring/)\n\nCancel-safe async `io_uring` read backend for [RustFS](https://github.com/rustfs/rustfs) storage.\n\nWhen a caller drops the future of an in-flight read (an erasure-code quorum was reached, a timeout, a disconnect), the kernel may still write into the read buffer until the CQE — so freeing it at future-drop is a use-after-free. This crate owns each buffer and file handle in the driver's pending table from submission until the CQE, reclaims only at the CQE, drains in-flight ops to zero on shutdown (with a bounded leak-over-UAF escape hatch for a hung disk), and aborts rather than free in-flight buffers on a driver-thread panic. The per-invariant rationale lives inline in [`src/driver.rs`](src/driver.rs) and on [docs.rs](https://docs.rs/rustfs-uring/).\n\n\u003e **Status:** read path only, Linux only (an empty stub on other targets). Wired into `rustfs/rustfs` behind a runtime probe, **off by default** (`RUSTFS_IO_URING_READ_ENABLE`). See [`CHANGELOG.md`](CHANGELOG.md).\n\n```toml\n[target.'cfg(target_os = \"linux\")'.dependencies]\nrustfs-uring = \"0.2.1\"\n```\n\n## Usage\n\n```rust\nuse std::fs::File;\nuse std::sync::Arc;\nuse rustfs_uring::UringDriver;\n\n# async fn demo() -\u003e std::io::Result\u003c()\u003e {\n// Probe a real IORING_OP_READ before accepting work. On a restricted host the\n// ProbeFailure's `is_expected_restriction()` says to degrade to the std backend.\nlet driver = UringDriver::probe_and_start(64).expect(\"io_uring available\");\nlet file = Arc::new(File::open(\"/data/object\")?);\n\n// Positioned read (whole-range: short reads are resubmitted). Dropping the\n// returned future before it completes is safe — the driver owns the buffer.\nlet bytes = driver.read_at(Arc::clone(\u0026file), 0, 65536).await?;\n\nlet snapshot = driver.shutdown();\nassert_eq!(snapshot.delivered + snapshot.orphan_reclaimed, snapshot.submitted);\n# Ok(())\n# }\n```\n\n- `read_at(file, offset, len)` — positioned (pread) read, whole-range.\n- `read_at_direct(file, offset, len, align)` — the same for an `O_DIRECT` fd; `offset`/`len` need not be aligned (the driver reads a block-aligned superset and returns exactly the requested range).\n- `read_current(file, len)` — `read(2)` semantics from the current position, for pipes and other non-seekable fds (a short read is a valid final result).\n- `probe_and_start_sharded(entries, shards)` — several independent rings per disk (each ring caps at one core's memory bandwidth for cache-hit reads); `probe_and_start(entries)` equals `..._sharded(entries, 1)`.\n\n## Testing\n\nLinux only; on other hosts `cargo check` builds the empty stub.\n\n```bash\n# On a Linux host with io_uring available:\ncargo test -- --nocapture --test-threads=1\n\n# Two legs in Docker (also on macOS via Docker Desktop / OrbStack):\n#   leg 1 — io_uring blocked by an explicit seccomp profile → every test MUST\n#           degrade to a graceful skip;\n#   leg 2 — seccomp=unconfined → real io_uring, and NO test may skip.\n./run-docker.sh\n```\n\nThe harness fails on a non-degrading leg 1 or a vacuous-pass leg 2, so a skipped suite can never masquerade as coverage. The cancel-safety contract is pinned by the acceptance tests in `tests/cancel.rs`; the `fault-injection` feature (test-only) drives the panic-abort, bounded-drain-leak, and probe-failure escape hatches in `tests/fault_injection.rs`.\n\n## License\n\nApache-2.0. See [LICENSE](LICENSE).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frustfs%2Furing","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Frustfs%2Furing","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frustfs%2Furing/lists"}