unix: fix fsync for read-only files on aix

On aix, the fsync syscall doesn't work on read-only files. Use
fsync_range instead to allow Fsync to work on any file.

Follow CL 254657 which did the same in package syscall.

For golang/go#41372

Change-Id: Ibc55ecf5c43e27a04281af1a204f847eeafeea63
Reviewed-on: https://go-review.googlesource.com/c/sys/+/362274
Trust: Tobias Klauser <tobias.klauser@gmail.com>
Run-TryBot: Tobias Klauser <tobias.klauser@gmail.com>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Ian Lance Taylor <iant@golang.org>
diff --git a/unix/syscall_aix.go b/unix/syscall_aix.go
index 680c954..6192750 100644
--- a/unix/syscall_aix.go
+++ b/unix/syscall_aix.go
@@ -377,6 +377,11 @@
 
 //sys	fcntl(fd int, cmd int, arg int) (val int, err error)
 
+//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)
+}
+
 /*
  * Direct access
  */
@@ -393,7 +398,6 @@
 //sys	Fchmodat(dirfd int, path string, mode uint32, flags int) (err error)
 //sys	Fchownat(dirfd int, path string, uid int, gid int, flags int) (err error)
 //sys	Fdatasync(fd int) (err error)
-//sys	Fsync(fd int) (err error)
 // readdir_r
 //sysnb	Getpgid(pid int) (pgid int, err error)
 
diff --git a/unix/zsyscall_aix_ppc.go b/unix/zsyscall_aix_ppc.go
index 91a23cc..85e0cc3 100644
--- a/unix/zsyscall_aix_ppc.go
+++ b/unix/zsyscall_aix_ppc.go
@@ -17,6 +17,7 @@
 int wait4(int, uintptr_t, int, uintptr_t);
 int ioctl(int, int, uintptr_t);
 int fcntl(uintptr_t, int, uintptr_t);
+int fsync_range(int, int, long long, long long);
 int acct(uintptr_t);
 int chdir(uintptr_t);
 int chroot(uintptr_t);
@@ -29,7 +30,6 @@
 int fchmodat(int, uintptr_t, unsigned int, int);
 int fchownat(int, uintptr_t, int, int, int);
 int fdatasync(int);
-int fsync(int);
 int getpgid(int);
 int getpgrp();
 int getpid();
@@ -255,6 +255,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) {
+	r0, er := C.fsync_range(C.int(fd), C.int(how), C.longlong(start), C.longlong(length))
+	if r0 == -1 && er != nil {
+		err = er
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
 func Acct(path string) (err error) {
 	_p0 := uintptr(unsafe.Pointer(C.CString(path)))
 	r0, er := C.acct(C.uintptr_t(_p0))
@@ -379,16 +389,6 @@
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
-func Fsync(fd int) (err error) {
-	r0, er := C.fsync(C.int(fd))
-	if r0 == -1 && er != nil {
-		err = er
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
 func Getpgid(pid int) (pgid int, err error) {
 	r0, er := C.getpgid(C.int(pid))
 	pgid = int(r0)
diff --git a/unix/zsyscall_aix_ppc64.go b/unix/zsyscall_aix_ppc64.go
index 33c2609..f1d4a73 100644
--- a/unix/zsyscall_aix_ppc64.go
+++ b/unix/zsyscall_aix_ppc64.go
@@ -135,6 +135,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 := callfsync_range(fd, how, start, length)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
 func Acct(path string) (err error) {
 	var _p0 *byte
 	_p0, err = BytePtrFromString(path)
@@ -283,16 +293,6 @@
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
-func Fsync(fd int) (err error) {
-	_, e1 := callfsync(fd)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
 func Getpgid(pid int) (pgid int, err error) {
 	r0, e1 := callgetpgid(pid)
 	pgid = int(r0)
diff --git a/unix/zsyscall_aix_ppc64_gc.go b/unix/zsyscall_aix_ppc64_gc.go
index 8b737fa..2caa5ad 100644
--- a/unix/zsyscall_aix_ppc64_gc.go
+++ b/unix/zsyscall_aix_ppc64_gc.go
@@ -18,6 +18,7 @@
 //go:cgo_import_dynamic libc_wait4 wait4 "libc.a/shr_64.o"
 //go:cgo_import_dynamic libc_ioctl ioctl "libc.a/shr_64.o"
 //go:cgo_import_dynamic libc_fcntl fcntl "libc.a/shr_64.o"
+//go:cgo_import_dynamic libc_fsync_range fsync_range "libc.a/shr_64.o"
 //go:cgo_import_dynamic libc_acct acct "libc.a/shr_64.o"
 //go:cgo_import_dynamic libc_chdir chdir "libc.a/shr_64.o"
 //go:cgo_import_dynamic libc_chroot chroot "libc.a/shr_64.o"
@@ -30,7 +31,6 @@
 //go:cgo_import_dynamic libc_fchmodat fchmodat "libc.a/shr_64.o"
 //go:cgo_import_dynamic libc_fchownat fchownat "libc.a/shr_64.o"
 //go:cgo_import_dynamic libc_fdatasync fdatasync "libc.a/shr_64.o"
-//go:cgo_import_dynamic libc_fsync fsync "libc.a/shr_64.o"
 //go:cgo_import_dynamic libc_getpgid getpgid "libc.a/shr_64.o"
 //go:cgo_import_dynamic libc_getpgrp getpgrp "libc.a/shr_64.o"
 //go:cgo_import_dynamic libc_getpid getpid "libc.a/shr_64.o"
@@ -136,6 +136,7 @@
 //go:linkname libc_wait4 libc_wait4
 //go:linkname libc_ioctl libc_ioctl
 //go:linkname libc_fcntl libc_fcntl
+//go:linkname libc_fsync_range libc_fsync_range
 //go:linkname libc_acct libc_acct
 //go:linkname libc_chdir libc_chdir
 //go:linkname libc_chroot libc_chroot
@@ -148,7 +149,6 @@
 //go:linkname libc_fchmodat libc_fchmodat
 //go:linkname libc_fchownat libc_fchownat
 //go:linkname libc_fdatasync libc_fdatasync
-//go:linkname libc_fsync libc_fsync
 //go:linkname libc_getpgid libc_getpgid
 //go:linkname libc_getpgrp libc_getpgrp
 //go:linkname libc_getpid libc_getpid
@@ -257,6 +257,7 @@
 	libc_wait4,
 	libc_ioctl,
 	libc_fcntl,
+	libc_fsync_range,
 	libc_acct,
 	libc_chdir,
 	libc_chroot,
@@ -269,7 +270,6 @@
 	libc_fchmodat,
 	libc_fchownat,
 	libc_fdatasync,
-	libc_fsync,
 	libc_getpgid,
 	libc_getpgrp,
 	libc_getpid,
@@ -430,6 +430,13 @@
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
+func callfsync_range(fd int, how int, start int64, length int64) (r1 uintptr, e1 Errno) {
+	r1, _, e1 = syscall6(uintptr(unsafe.Pointer(&libc_fsync_range)), 4, uintptr(fd), uintptr(how), uintptr(start), uintptr(length), 0, 0)
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
 func callacct(_p0 uintptr) (r1 uintptr, e1 Errno) {
 	r1, _, e1 = syscall6(uintptr(unsafe.Pointer(&libc_acct)), 1, _p0, 0, 0, 0, 0, 0)
 	return
@@ -514,13 +521,6 @@
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
-func callfsync(fd int) (r1 uintptr, e1 Errno) {
-	r1, _, e1 = syscall6(uintptr(unsafe.Pointer(&libc_fsync)), 1, uintptr(fd), 0, 0, 0, 0, 0)
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
 func callgetpgid(pid int) (r1 uintptr, e1 Errno) {
 	r1, _, e1 = rawSyscall6(uintptr(unsafe.Pointer(&libc_getpgid)), 1, uintptr(pid), 0, 0, 0, 0, 0)
 	return
diff --git a/unix/zsyscall_aix_ppc64_gccgo.go b/unix/zsyscall_aix_ppc64_gccgo.go
index 3c26091..944a714 100644
--- a/unix/zsyscall_aix_ppc64_gccgo.go
+++ b/unix/zsyscall_aix_ppc64_gccgo.go
@@ -16,6 +16,7 @@
 int wait4(int, uintptr_t, int, uintptr_t);
 int ioctl(int, int, uintptr_t);
 int fcntl(uintptr_t, int, uintptr_t);
+int fsync_range(int, int, long long, long long);
 int acct(uintptr_t);
 int chdir(uintptr_t);
 int chroot(uintptr_t);
@@ -28,7 +29,6 @@
 int fchmodat(int, uintptr_t, unsigned int, int);
 int fchownat(int, uintptr_t, int, int, int);
 int fdatasync(int);
-int fsync(int);
 int getpgid(int);
 int getpgrp();
 int getpid();
@@ -199,6 +199,14 @@
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
+func callfsync_range(fd int, how int, start int64, length int64) (r1 uintptr, e1 Errno) {
+	r1 = uintptr(C.fsync_range(C.int(fd), C.int(how), C.longlong(start), C.longlong(length)))
+	e1 = syscall.GetErrno()
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
 func callacct(_p0 uintptr) (r1 uintptr, e1 Errno) {
 	r1 = uintptr(C.acct(C.uintptr_t(_p0)))
 	e1 = syscall.GetErrno()
@@ -295,14 +303,6 @@
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
-func callfsync(fd int) (r1 uintptr, e1 Errno) {
-	r1 = uintptr(C.fsync(C.int(fd)))
-	e1 = syscall.GetErrno()
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
 func callgetpgid(pid int) (r1 uintptr, e1 Errno) {
 	r1 = uintptr(C.getpgid(C.int(pid)))
 	e1 = syscall.GetErrno()