Commit d9c697bf authored by Tobias Klauser's avatar Tobias Klauser Committed by Tobias Klauser

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: 's avatarBrad Fitzpatrick <bradfitz@golang.org>
parent 2b024373
......@@ -44,7 +44,6 @@ package unix
//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 @@ func Poll(fds []PollFd, timeout int) (n int, err error) {
}
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)
}
......@@ -7,6 +7,7 @@
package unix_test
import (
"io/ioutil"
"os"
"runtime"
"runtime/debug"
......@@ -441,3 +442,26 @@ func TestFaccessat(t *testing.T) {
}
}
}
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)
}
}
......@@ -1998,16 +1998,6 @@ func Statfs(path string, buf *Statfs_t) (err error) {
// 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 @@ func poll(fds *PollFd, nfds int, timeout int) (n int, err error) {
}
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
}
......@@ -1998,16 +1998,6 @@ func Statfs(path string, buf *Statfs_t) (err error) {
// 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 @@ func poll(fds *PollFd, nfds int, timeout int) (n int, err error) {
}
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
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment