Files
seaweedfs/seaweed-volume/src/storage/volume_open.rs
T
Chris Lu 1996c6aec6 volume: open volume files with O_NOATIME (#11055)
* volume server: open volume files with O_NOATIME

Nothing reads the atime of .dat, .idx, .sdx, or EC files, but every
needle read still dirtied the inode: even relatime writes atime on the
first read after each write, so an actively written volume paid a
metadata write per read/write cycle, and strictatime mounts paid one
per read. Open the serving handles with O_NOATIME, falling back to a
plain open when the file belongs to another owner (EPERM).

Claude-Session: https://claude.ai/code/session_015uVY4diBgEn3VYQoc2eMuD

* seaweed-volume: mirror the O_NOATIME volume file opens

Same change as the Go volume server: serving handles for .dat, .idx,
.sdx, .ecx, .ecj, and shard files open with O_NOATIME on Linux, with a
plain-open fallback on EPERM.

Claude-Session: https://claude.ai/code/session_015uVY4diBgEn3VYQoc2eMuD

* route the tier-down and recreate .dat opens through the no-atime helper

Review caught the Rust tier-down swap opening the local .dat directly.
The Go swapToLocalDatBackend and the zero-length read-only .dat
recreate in maybeWriteSuperBlock had the same gap: all three install
long-lived serving handles.

Claude-Session: https://claude.ai/code/session_015uVY4diBgEn3VYQoc2eMuD
2026-08-31 21:41:50 -07:00

28 lines
1.0 KiB
Rust

//! Opening volume data and index files without access-time updates.
use std::fs::{File, OpenOptions};
use std::io;
use std::path::Path;
/// Open a volume data or index file with `O_NOATIME`. Nothing reads these
/// files' atime, but without the flag every needle read dirties the inode —
/// even relatime writes atime on the first read after each write, so an
/// actively written volume pays a metadata write per read/write cycle.
/// Matches Go's `backend.OpenVolumeFile`.
pub fn open_volume_file(opts: &OpenOptions, path: impl AsRef<Path>) -> io::Result<File> {
let path = path.as_ref();
#[cfg(target_os = "linux")]
{
use std::os::unix::fs::OpenOptionsExt;
let mut noatime = opts.clone();
noatime.custom_flags(libc::O_NOATIME);
match noatime.open(path) {
// O_NOATIME is refused unless we own the file or hold CAP_FOWNER.
Err(e) if e.raw_os_error() == Some(libc::EPERM) => opts.open(path),
result => result,
}
}
#[cfg(not(target_os = "linux"))]
opts.open(path)
}