unix: correct argument order for SyncFileRange syscall on linux/ppc64{,le}
On linux/ppc64{,le} the SYS_SYNC_FILE_RANGE2 syscall is used to
implement SyncFileRange. This syscall has a different argument order
than SYS_SYNC_FILE_RANGE. Apart from that the implementations of both
syscalls are the same, so use a simple wrapper to invoke the syscall
with the correct argument order.
For context see:
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=edd5cd4a9424f22b0fa08bef5e299d41befd5622
Fixes golang/go#27485
Change-Id: Idc154eab7b7c521a34de821e1d1a97095e96fed0
Reviewed-on: https://go-review.googlesource.com/133215
Run-TryBot: Tobias Klauser <tobias.klauser@gmail.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
diff --git a/unix/syscall_linux_ppc64x.go b/unix/syscall_linux_ppc64x.go
index 8c6720f..6a38dfd 100644
--- a/unix/syscall_linux_ppc64x.go
+++ b/unix/syscall_linux_ppc64x.go
@@ -44,7 +44,6 @@
//sys Splice(rfd int, roff *int64, wfd int, woff *int64, len int, flags int) (n int64, err error)
//sys Stat(path string, stat *Stat_t) (err error)
//sys Statfs(path string, buf *Statfs_t) (err error)
-//sys SyncFileRange(fd int, off int64, n int64, flags int) (err error) = SYS_SYNC_FILE_RANGE2
//sys Truncate(path string, length int64) (err error)
//sys Ustat(dev int, ubuf *Ustat_t) (err error)
//sys accept(s int, rsa *RawSockaddrAny, addrlen *_Socklen) (fd int, err error)
@@ -129,3 +128,11 @@
}
return poll(&fds[0], len(fds), timeout)
}
+
+//sys syncFileRange2(fd int, flags int, off int64, n int64) (err error) = SYS_SYNC_FILE_RANGE2
+
+func SyncFileRange(fd int, off int64, n int64, flags int) error {
+ // The sync_file_range and sync_file_range2 syscalls differ only in the
+ // order of their arguments.
+ return syncFileRange2(fd, flags, off, n)
+}
diff --git a/unix/syscall_linux_test.go b/unix/syscall_linux_test.go
index 7fb5804..0f68077 100644
--- a/unix/syscall_linux_test.go
+++ b/unix/syscall_linux_test.go
@@ -7,6 +7,7 @@
package unix_test
import (
+ "io/ioutil"
"os"
"runtime"
"runtime/debug"
@@ -441,3 +442,26 @@
}
}
}
+
+func TestSyncFileRange(t *testing.T) {
+ file, err := ioutil.TempFile("", "TestSyncFileRange")
+ if err != nil {
+ t.Fatal(err)
+ }
+ defer os.Remove(file.Name())
+ defer file.Close()
+
+ err = unix.SyncFileRange(int(file.Fd()), 0, 0, 0)
+ if err == unix.ENOSYS || err == unix.EPERM {
+ t.Skip("sync_file_range syscall is not available, skipping test")
+ } else if err != nil {
+ t.Fatalf("SyncFileRange: %v", err)
+ }
+
+ // invalid flags
+ flags := 0xf00
+ err = unix.SyncFileRange(int(file.Fd()), 0, 0, flags)
+ if err != unix.EINVAL {
+ t.Fatalf("SyncFileRange: unexpected error: %v, want EINVAL", err)
+ }
+}
diff --git a/unix/zsyscall_linux_ppc64.go b/unix/zsyscall_linux_ppc64.go
index 2f7110d..f3fae1d 100644
--- a/unix/zsyscall_linux_ppc64.go
+++ b/unix/zsyscall_linux_ppc64.go
@@ -1998,16 +1998,6 @@
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-func SyncFileRange(fd int, off int64, n int64, flags int) (err error) {
- _, _, e1 := Syscall6(SYS_SYNC_FILE_RANGE2, uintptr(fd), uintptr(off), uintptr(n), uintptr(flags), 0, 0)
- if e1 != 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
func Truncate(path string, length int64) (err error) {
var _p0 *byte
_p0, err = BytePtrFromString(path)
@@ -2317,3 +2307,13 @@
}
return
}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func syncFileRange2(fd int, flags int, off int64, n int64) (err error) {
+ _, _, e1 := Syscall6(SYS_SYNC_FILE_RANGE2, uintptr(fd), uintptr(flags), uintptr(off), uintptr(n), 0, 0)
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
diff --git a/unix/zsyscall_linux_ppc64le.go b/unix/zsyscall_linux_ppc64le.go
index bb3bd59..011b0a5 100644
--- a/unix/zsyscall_linux_ppc64le.go
+++ b/unix/zsyscall_linux_ppc64le.go
@@ -1998,16 +1998,6 @@
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-func SyncFileRange(fd int, off int64, n int64, flags int) (err error) {
- _, _, e1 := Syscall6(SYS_SYNC_FILE_RANGE2, uintptr(fd), uintptr(off), uintptr(n), uintptr(flags), 0, 0)
- if e1 != 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
func Truncate(path string, length int64) (err error) {
var _p0 *byte
_p0, err = BytePtrFromString(path)
@@ -2317,3 +2307,13 @@
}
return
}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func syncFileRange2(fd int, flags int, off int64, n int64) (err error) {
+ _, _, e1 := Syscall6(SYS_SYNC_FILE_RANGE2, uintptr(fd), uintptr(flags), uintptr(off), uintptr(n), 0, 0)
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}