[PR #279] fix(overlaybd): derive direct I/O alignment from each file #314

Open
opened 2026-10-29 14:22:06 +00:00 by bsakaguchi · 0 comments
Owner

📋 Pull Request Information

Original PR: https://github.com/kvcache-ai/AgentENV/pull/279
Author: @ranxi2001
Created: 9/11/2026
Status: 🔄 Open

Base: main ← Head: fix/direct-io-alignment


📝 Commits (3)

  • 2762e88 fix(overlaybd): derive direct I/O alignment from each file
  • f43c506 fix(overlaybd): validate direct I/O alignment metadata
  • e357a2d fix(overlaybd): preserve direct I/O alignment on short completions

📊 Changes

4 files changed (+334 additions, -49 deletions)

View changed files

📝 storage/overlaybd/src/backend/local.rs (+190 -48)
📝 storage/overlaybd/src/sys/mod.rs (+3 -1)
📝 storage/overlaybd/src/sys/open_flags.rs (+75 -0)
📝 storage/util/src/io_ring/mod.rs (+66 -0)

📄 Description

What

Query each direct-I/O file’s memory and offset alignment with Linux STATX_DIOALIGN and use those limits for LocalFile reads and writes, including io_uring. This allows sub-sector reads from local lower layers on filesystems requiring 4096-byte direct I/O.

Why

The fixed 512-byte alignment causes EINVAL when the backing file requires 4096-byte requests. The libaio image path opens local lower layers with direct I/O, so even reading their headers can fail.

Related to #274. This addresses lower-layer reads and aligned LocalFile I/O; writable LSMT operations that issue 512-byte requests on a 4K-required file remain unsupported.

Scope and non-goals

The change is limited to LocalFile and its existing platform syscall boundary. The LSMT data/index layout remains unchanged; it does not add read-modify-write or buffered fallback.

Design and behavior changes

Alignment is queried once using the opened descriptor. Read ranges use the reported offset alignment, while bounce buffers use the memory alignment. Writes still require aligned offsets and lengths, and invalid requests report the required alignment. If the kernel/filesystem cannot report the limits, or on macOS, the existing 512-byte behavior is retained. Other query errors are propagated.

Compatibility and operations

  • Public API or generated protocol: unchanged.
  • Configuration or defaults: unchanged; buffered files do not query alignment.
  • Snapshot manifest, artifact layout, or storage format: unchanged.
  • Upgrade and rollback: no migration; rollback restores the old alignment assumption.
  • Host requirements, permissions, ports, or dependencies: no new dependency or privilege; STATX_DIOALIGN is used when available (Linux 6.1+ with filesystem support).

Validation

  • make fmt
  • make clippy
  • make test-unit
  • Relevant Rust integration tests
  • make -C services test (required when services/ changes)
  • Generated clients/server regenerated with the documented make target
  • Documentation updated
  • Benchmarks or performance comparison completed

Commands and results:

cargo test --locked -p overlaybd --lib --all-features
  359 passed, 4 ignored
cargo clippy --locked -p overlaybd --all-targets --all-features -- -D warnings
  passed
make fmt
  passed
make clippy
  passed with locally extracted libclang and explicit resource directory
git diff --check
  passed

Full workspace clippy passed after supplying libclang/LLVM and Clang builtin headers from locally extracted distribution packages; no host packages were installed.

The no-default-features library suite also passed (299 tests, 2 ignored). A process-local syscall probe reporting and enforcing 4K constraints makes the same new lower-read regression fail on base with EINVAL and pass with this patch. The libaio image-open test passes under that probe. This models alignment constraints; it is not native 4K hardware validation, and it does not intercept io_uring submissions.

Skipped checks and reasons:

  • Native 4K validation and macOS execution were unavailable.
  • The new explicit context/io_uring test was attempted but failed before I/O during ring setup on local WSL 5.15 (EINVAL); the existing ring builder requires newer kernel setup flags.
  • Privileged ublk, VM and full E2E tiers were not run on this host. Go, generated-code, documentation and benchmark checks are unrelated to this change.

Risks and reviewer notes

This is a partial fix for #274. LSMT uses 512-byte data and seal-index/padding writes, which cannot be submitted as direct I/O to a file requiring 4096-byte requests. Such writes now fail with the required alignment in the error. Supporting them needs a separate storage design. Filesystems that cannot report STATX_DIOALIGN retain the existing 512-byte assumption.

Checklist

  • The PR contains one coherent change and no unrelated formatting or refactoring.
  • New behavior is covered by tests, or I explained why testing is impractical.
  • Logs and examples contain no credentials, tokens, or private registry information.
  • I did not manually edit generated code without updating its source and regenerating it.

🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.

## 📋 Pull Request Information **Original PR:** https://github.com/kvcache-ai/AgentENV/pull/279 **Author:** [@ranxi2001](https://github.com/ranxi2001) **Created:** 9/11/2026 **Status:** 🔄 Open **Base:** `main` ← **Head:** `fix/direct-io-alignment` --- ### 📝 Commits (3) - [`2762e88`](https://github.com/kvcache-ai/AgentENV/commit/2762e88ba395b6463997b037fb02785a42769f09) fix(overlaybd): derive direct I/O alignment from each file - [`f43c506`](https://github.com/kvcache-ai/AgentENV/commit/f43c506d8f8a92e1ff609e83db2ab62f8d77f6e9) fix(overlaybd): validate direct I/O alignment metadata - [`e357a2d`](https://github.com/kvcache-ai/AgentENV/commit/e357a2d224d380bdcc83d1c46fe05d0489954354) fix(overlaybd): preserve direct I/O alignment on short completions ### 📊 Changes **4 files changed** (+334 additions, -49 deletions) <details> <summary>View changed files</summary> 📝 `storage/overlaybd/src/backend/local.rs` (+190 -48) 📝 `storage/overlaybd/src/sys/mod.rs` (+3 -1) 📝 `storage/overlaybd/src/sys/open_flags.rs` (+75 -0) 📝 `storage/util/src/io_ring/mod.rs` (+66 -0) </details> ### 📄 Description ## What <!-- Summarize the change. Keep the PR focused on one problem. --> Query each direct-I/O file’s memory and offset alignment with Linux STATX_DIOALIGN and use those limits for LocalFile reads and writes, including io_uring. This allows sub-sector reads from local lower layers on filesystems requiring 4096-byte direct I/O. ## Why <!-- Explain the user or maintainer problem this solves. --> The fixed 512-byte alignment causes EINVAL when the backing file requires 4096-byte requests. The libaio image path opens local lower layers with direct I/O, so even reading their headers can fail. ## Related issue <!-- Use "Closes #123" for an issue resolved by this PR. Non-trivial changes should normally have an issue or prior design discussion. --> Related to #274. This addresses lower-layer reads and aligned LocalFile I/O; writable LSMT operations that issue 512-byte requests on a 4K-required file remain unsupported. ## Scope and non-goals <!-- State what is intentionally included and excluded. Call out unrelated refactors. --> The change is limited to LocalFile and its existing platform syscall boundary. The LSMT data/index layout remains unchanged; it does not add read-modify-write or buffered fallback. ## Design and behavior changes <!-- Describe important data flow, lifecycle, failure handling, concurrency, or operational changes. Include diagrams for substantial changes. --> Alignment is queried once using the opened descriptor. Read ranges use the reported offset alignment, while bounce buffers use the memory alignment. Writes still require aligned offsets and lengths, and invalid requests report the required alignment. If the kernel/filesystem cannot report the limits, or on macOS, the existing 512-byte behavior is retained. Other query errors are propagated. ## Compatibility and operations <!-- Explain applicable compatibility and deployment impact. Write "N/A" with a reason where appropriate. --> - Public API or generated protocol: unchanged. - Configuration or defaults: unchanged; buffered files do not query alignment. - Snapshot manifest, artifact layout, or storage format: unchanged. - Upgrade and rollback: no migration; rollback restores the old alignment assumption. - Host requirements, permissions, ports, or dependencies: no new dependency or privilege; STATX_DIOALIGN is used when available (Linux 6.1+ with filesystem support). ## Validation <!-- Check only commands you actually ran. Add focused tests and exact commands below. --> - [x] `make fmt` - [x] `make clippy` - [ ] `make test-unit` - [ ] Relevant Rust integration tests - [ ] `make -C services test` (required when `services/` changes) - [ ] Generated clients/server regenerated with the documented `make` target - [ ] Documentation updated - [ ] Benchmarks or performance comparison completed Commands and results: ```text cargo test --locked -p overlaybd --lib --all-features 359 passed, 4 ignored cargo clippy --locked -p overlaybd --all-targets --all-features -- -D warnings passed make fmt passed make clippy passed with locally extracted libclang and explicit resource directory git diff --check passed ``` Full workspace clippy passed after supplying libclang/LLVM and Clang builtin headers from locally extracted distribution packages; no host packages were installed. The no-default-features library suite also passed (299 tests, 2 ignored). A process-local syscall probe reporting and enforcing 4K constraints makes the same new lower-read regression fail on base with EINVAL and pass with this patch. The libaio image-open test passes under that probe. This models alignment constraints; it is not native 4K hardware validation, and it does not intercept io_uring submissions. Skipped checks and reasons: - Native 4K validation and macOS execution were unavailable. - The new explicit context/io_uring test was attempted but failed before I/O during ring setup on local WSL 5.15 (EINVAL); the existing ring builder requires newer kernel setup flags. - Privileged ublk, VM and full E2E tiers were not run on this host. Go, generated-code, documentation and benchmark checks are unrelated to this change. ## Risks and reviewer notes <!-- Identify correctness, security, compatibility, resource, and operational risks. Point reviewers to the most important files or commits. --> This is a partial fix for #274. LSMT uses 512-byte data and seal-index/padding writes, which cannot be submitted as direct I/O to a file requiring 4096-byte requests. Such writes now fail with the required alignment in the error. Supporting them needs a separate storage design. Filesystems that cannot report STATX_DIOALIGN retain the existing 512-byte assumption. ## Checklist - [x] The PR contains one coherent change and no unrelated formatting or refactoring. - [x] New behavior is covered by tests, or I explained why testing is impractical. - [x] Logs and examples contain no credentials, tokens, or private registry information. - [x] I did not manually edit generated code without updating its source and regenerating it. --- <sub>🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.</sub>
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
kvcache-ai/AgentENV#314
No description provided.