mirror of
https://github.com/rustfs/rustfs.git
synced 2026-08-13 16:46:55 +00:00
2e5874f839
fix(get): give UringBackend the only fd cache for its disk (#1801) #1801 made `StdBackend::new` always build a descriptor cache. `UringBackend` wraps a `StdBackend` (`inner`), so under io_uring a disk ended up with TWO `FdCache`s: the wrapper's and the inner's. `UringBackend::pread_bytes` delegates to `inner.pread_bytes` on four fallback paths (latch-off, O_DIRECT unsupported / error, buffered-read error), which populated `inner.fd_cache` — but `UringBackend`'s invalidation only touches its own cache, so the inner cache was never invalidated. For up to `FD_CACHE_TTL` (5s) after a heal/rename/ delete, a fallback read could serve the pre-mutation inode: exactly the stale-descriptor hazard `FdCache`'s generation guard exists to close (rustfs/backlog#1176). It also double-counted `FD_CACHE_CAPACITY` (512 fds) against `RLIMIT_NOFILE` per disk (backlog#1178). Fix: `UringBackend` now constructs its inner `StdBackend` with the new `StdBackend::new_without_fd_cache`, so the wrapper owns the only cache for the disk. The inner backend opens per read on fallback, leaving nothing unguarded. `StdBackend::new` (standalone default) is unchanged; a private `build(root, build_fd_cache)` holds the shared construction. - Default (non-io_uring) path: byte-for-byte unchanged. - io_uring path: one cache per disk, fully covered by the wrapper's invalidation; halves the per-disk fd budget under `RLIMIT_NOFILE`. - `RUSTFS_IO_URING_FD_CACHE` / `RUSTFS_LOCAL_FD_CACHE` semantics preserved. - Regression test pins `new_without_fd_cache` -> no cache. Found by a post-merge re-review of the Wave 1 GET PRs. cargo check/clippy clean; Linux compile + the io_uring fd-cache suite deferred to CI. Co-authored-by: heihutu <heihutu@gmail.com>