package wal import ( "fmt" "os" ) // dirFsyncFn is the package-level indirection over dirFsync so tests can // inject failures without interface plumbing in production code. // // NOT PARALLEL-SAFE: tests that override this must not use t.Parallel(). // All existing wal tests run serially within the package. var dirFsyncFn = dirFsync // dirFsync opens the directory and fsyncs it. Required for durable-ready // state per design ยง3.2 line 258. This is a hard requirement, not // best-effort: rename is atomic in memory but not guaranteed to survive // power loss without a directory fsync. // // Order: os.Open โ†’ f.Stat โ†’ IsDir โ†’ f.Sync. The open-then-stat sequence // avoids the TOCTOU window between a separate os.Stat and os.Open, and // ensures IsDir is checked against the actually-opened file. func dirFsync(dir string) error { f, err := os.Open(dir) if err != nil { return fmt.Errorf("open dir %q: %w", dir, err) } defer f.Close() info, err := f.Stat() if err != nil { return fmt.Errorf("stat dir %q: %w", dir, err) } if !info.IsDir() { return fmt.Errorf("path %q is not a directory", dir) } if err := f.Sync(); err != nil { return fmt.Errorf("fsync dir %q: %w", dir, err) } return nil }