syscall: fix fsync for read-only files on aix

AIX fsync syscall doesn't work on read-only files. Using fsync_range
instead allows syscall.Fsync to work on any files.

Fixes #41372

Change-Id: I66d33e847875496af53da60828c1bddf6c2b76b7
Reviewed-on: https://go-review.googlesource.com/c/go/+/254657
Run-TryBot: Tobias Klauser <tobias.klauser@gmail.com>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Tobias Klauser <tobias.klauser@gmail.com>
Reviewed-by: Ian Lance Taylor <iant@golang.org>
diff --git a/src/syscall/syscall_aix.go b/src/syscall/syscall_aix.go
index 8bb5fa9..8837dd5 100644
--- a/src/syscall/syscall_aix.go
+++ b/src/syscall/syscall_aix.go
@@ -214,6 +214,11 @@
 	return
 }
 
+//sys	fsyncRange(fd int, how int, start int64, length int64) (err error) = fsync_range
+func Fsync(fd int) error {
+	return fsyncRange(fd, O_SYNC, 0, 0)
+}
+
 /*
  * Socket
  */
@@ -600,7 +605,6 @@
 //sys	Fstat(fd int, stat *Stat_t) (err error)
 //sys	Fstatfs(fd int, buf *Statfs_t) (err error)
 //sys	Ftruncate(fd int, length int64) (err error)
-//sys	Fsync(fd int) (err error)
 //sysnb	Getgid() (gid int)
 //sysnb	Getpid() (pid int)
 //sys	Geteuid() (euid int)
diff --git a/src/syscall/zsyscall_aix_ppc64.go b/src/syscall/zsyscall_aix_ppc64.go
index 384fead..20625c1 100644
--- a/src/syscall/zsyscall_aix_ppc64.go
+++ b/src/syscall/zsyscall_aix_ppc64.go
@@ -19,6 +19,7 @@
 //go:cgo_import_dynamic libc_setgroups setgroups "libc.a/shr_64.o"
 //go:cgo_import_dynamic libc_getdirent getdirent "libc.a/shr_64.o"
 //go:cgo_import_dynamic libc_wait4 wait4 "libc.a/shr_64.o"
+//go:cgo_import_dynamic libc_fsync_range fsync_range "libc.a/shr_64.o"
 //go:cgo_import_dynamic libc_bind bind "libc.a/shr_64.o"
 //go:cgo_import_dynamic libc_connect connect "libc.a/shr_64.o"
 //go:cgo_import_dynamic libc_Getkerninfo getkerninfo "libc.a/shr_64.o"
@@ -54,7 +55,6 @@
 //go:cgo_import_dynamic libc_Fstat fstat "libc.a/shr_64.o"
 //go:cgo_import_dynamic libc_Fstatfs fstatfs "libc.a/shr_64.o"
 //go:cgo_import_dynamic libc_Ftruncate ftruncate "libc.a/shr_64.o"
-//go:cgo_import_dynamic libc_Fsync fsync "libc.a/shr_64.o"
 //go:cgo_import_dynamic libc_Getgid getgid "libc.a/shr_64.o"
 //go:cgo_import_dynamic libc_Getpid getpid "libc.a/shr_64.o"
 //go:cgo_import_dynamic libc_Geteuid geteuid "libc.a/shr_64.o"
@@ -111,6 +111,7 @@
 //go:linkname libc_setgroups libc_setgroups
 //go:linkname libc_getdirent libc_getdirent
 //go:linkname libc_wait4 libc_wait4
+//go:linkname libc_fsync_range libc_fsync_range
 //go:linkname libc_bind libc_bind
 //go:linkname libc_connect libc_connect
 //go:linkname libc_Getkerninfo libc_Getkerninfo
@@ -146,7 +147,6 @@
 //go:linkname libc_Fstat libc_Fstat
 //go:linkname libc_Fstatfs libc_Fstatfs
 //go:linkname libc_Ftruncate libc_Ftruncate
-//go:linkname libc_Fsync libc_Fsync
 //go:linkname libc_Getgid libc_Getgid
 //go:linkname libc_Getpid libc_Getpid
 //go:linkname libc_Geteuid libc_Geteuid
@@ -206,6 +206,7 @@
 	libc_setgroups,
 	libc_getdirent,
 	libc_wait4,
+	libc_fsync_range,
 	libc_bind,
 	libc_connect,
 	libc_Getkerninfo,
@@ -241,7 +242,6 @@
 	libc_Fstat,
 	libc_Fstatfs,
 	libc_Ftruncate,
-	libc_Fsync,
 	libc_Getgid,
 	libc_Getpid,
 	libc_Geteuid,
@@ -442,6 +442,16 @@
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
+func fsyncRange(fd int, how int, start int64, length int64) (err error) {
+	_, _, e1 := syscall6(uintptr(unsafe.Pointer(&libc_fsync_range)), 4, uintptr(fd), uintptr(how), uintptr(start), uintptr(length), 0, 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
 func bind(s int, addr unsafe.Pointer, addrlen _Socklen) (err error) {
 	_, _, e1 := syscall6(uintptr(unsafe.Pointer(&libc_bind)), 3, uintptr(s), uintptr(addr), uintptr(addrlen), 0, 0, 0)
 	if e1 != 0 {
@@ -854,16 +864,6 @@
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
-func Fsync(fd int) (err error) {
-	_, _, e1 := syscall6(uintptr(unsafe.Pointer(&libc_Fsync)), 1, uintptr(fd), 0, 0, 0, 0, 0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
 func Getgid() (gid int) {
 	r0, _, _ := rawSyscall6(uintptr(unsafe.Pointer(&libc_Getgid)), 0, 0, 0, 0, 0, 0, 0)
 	gid = int(r0)