Interesting. My understanding of how things get implemented is that all code runs essentially "async" by default, but the runtime scheduler can switch to running code synchronously when requested (runtime.LockOSThread) or necessary (e.g. "slow" calls to C via cgo).
I was not aware that file I/O isn't async on Linux. Even so, I'm pretty sure network I/O and channel operations (send/receive/select) are async via epoll. I'm not as sure about these, but I think time.Sleep and sync.Mutex.Lock suspend the goroutine as well.
For those curious I looked at Windows and Linux, but not much else.
Linux: no io_uring support. There's debate on even whether to use it as people are discussing security implications[2]. It looks like (from perusing this issue, but could be wrong) AIO wasn't used.
Windows: it looks like they're using IOCP everywhere. Seems sensible enough.
General case: there seems to be an open issue regarding this[3].
[1]: For example, Windows has IOCPs, Linux has io_uring, FreeBSD has kqueue, POSIX has... POSIX AIO, etc.
[2]: https://github.com/golang/go/issues/31908
[3]: https://github.com/golang/go/issues/6817