diff --git a/weed/storage/blockvol/batchio/batchio.go b/weed/storage/blockvol/batchio/batchio.go index cb93c2338..2ad03a35a 100644 --- a/weed/storage/blockvol/batchio/batchio.go +++ b/weed/storage/blockvol/batchio/batchio.go @@ -23,6 +23,11 @@ import ( // Callers decide whether to fall back to standard or fail. var ErrIOUringUnavailable = errors.New("batchio: io_uring unavailable") +// IOUringImpl reports the compiled io_uring implementation name. +// Set by each iouring_*_linux.go file. Empty string means no io_uring +// backend was compiled in (standard only). +var IOUringImpl string + // Op represents a single I/O operation: read or write buf at offset. type Op struct { Buf []byte diff --git a/weed/storage/blockvol/batchio/iouring_giouring_linux.go b/weed/storage/blockvol/batchio/iouring_giouring_linux.go index 0b6149876..dd5701966 100644 --- a/weed/storage/blockvol/batchio/iouring_giouring_linux.go +++ b/weed/storage/blockvol/batchio/iouring_giouring_linux.go @@ -10,6 +10,8 @@ import ( "github.com/pawelgaczynski/giouring" ) +func init() { IOUringImpl = "giouring" } + // giouringBatchIO implements BatchIO using giouring (direct liburing port). // No goroutines or channels — direct SQE/CQE ring manipulation. // Requires kernel 6.0+. diff --git a/weed/storage/blockvol/batchio/iouring_iceber_linux.go b/weed/storage/blockvol/batchio/iouring_iceber_linux.go index 6b821f5b5..250b7f8f8 100644 --- a/weed/storage/blockvol/batchio/iouring_iceber_linux.go +++ b/weed/storage/blockvol/batchio/iouring_iceber_linux.go @@ -9,6 +9,8 @@ import ( "github.com/iceber/iouring-go" ) +func init() { IOUringImpl = "iceber" } + // ioUringBatchIO implements BatchIO using Linux io_uring. // Requires kernel 5.6+ (linked fsync: 5.10+). type ioUringBatchIO struct { diff --git a/weed/storage/blockvol/batchio/iouring_other.go b/weed/storage/blockvol/batchio/iouring_other.go index 784e566bf..2bfcd8922 100644 --- a/weed/storage/blockvol/batchio/iouring_other.go +++ b/weed/storage/blockvol/batchio/iouring_other.go @@ -1,9 +1,12 @@ -//go:build !linux || no_iouring +//go:build !linux || (!iouring_iceber && !iouring_giouring && !iouring_raw) package batchio -// NewIOUring returns ErrIOUringUnavailable on non-Linux platforms -// or when io_uring is disabled via the no_iouring build tag. +// NewIOUring returns ErrIOUringUnavailable when no io_uring backend is +// compiled in. On Linux, use one of these build tags to enable a backend: +// - iouring_iceber (iceber/iouring-go library) +// - iouring_giouring (pawelgaczynski/giouring library) +// - iouring_raw (raw syscall wrappers, zero deps) func NewIOUring(ringSize uint) (BatchIO, error) { return nil, ErrIOUringUnavailable } diff --git a/weed/storage/blockvol/batchio/iouring_raw_linux.go b/weed/storage/blockvol/batchio/iouring_raw_linux.go index d877f762f..b016d659d 100644 --- a/weed/storage/blockvol/batchio/iouring_raw_linux.go +++ b/weed/storage/blockvol/batchio/iouring_raw_linux.go @@ -1,4 +1,4 @@ -//go:build linux && !no_iouring && !iouring_iceber && !iouring_giouring +//go:build linux && iouring_raw package batchio @@ -10,6 +10,8 @@ import ( "unsafe" ) +func init() { IOUringImpl = "raw" } + // Raw io_uring syscall numbers. const ( sysIOUringSetup = 425 diff --git a/weed/storage/blockvol/blockvol.go b/weed/storage/blockvol/blockvol.go index 721cdf788..b2532142a 100644 --- a/weed/storage/blockvol/blockvol.go +++ b/weed/storage/blockvol/blockvol.go @@ -1165,25 +1165,31 @@ func (v *BlockVol) Close() error { // - "auto": tries io_uring, falls back to standard with warning // - "io_uring": requires io_uring, returns error if unavailable func newBatchIO(mode IOBackendMode, logger *log.Logger) (batchio.BatchIO, string, error) { + impl := batchio.IOUringImpl // compiled-in implementation ("iceber", "giouring", "raw", or "") + if impl == "" { + impl = "none" + } + switch mode { case IOBackendIOUring: bio, err := batchio.NewIOUring(256) if err != nil { - return nil, "", fmt.Errorf("io_uring requested but unavailable: %w", err) + return nil, "", fmt.Errorf("io_uring requested but unavailable (compiled=%s): %w", impl, err) } - logger.Printf("io backend: requested=io_uring selected=io_uring") + logger.Printf("io backend: requested=io_uring implementation=%s selected=io_uring", impl) return bio, "io_uring", nil case IOBackendAuto: bio, err := batchio.NewIOUring(256) if err != nil { - logger.Printf("io backend: requested=auto selected=standard reason=%v", err) + logger.Printf("io backend: requested=auto implementation=%s selected=standard reason=%v", impl, err) return batchio.NewStandard(), "standard", nil } - logger.Printf("io backend: requested=auto selected=io_uring") + logger.Printf("io backend: requested=auto implementation=%s selected=io_uring", impl) return bio, "io_uring", nil default: // IOBackendStandard or empty + logger.Printf("io backend: requested=standard implementation=%s selected=standard", impl) return batchio.NewStandard(), "standard", nil } }