浏览代码

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>
Tobias Klauser 7 年之前
父节点
当前提交
d9c697bf0b
共有 4 个文件被更改,包括 52 次插入21 次删除
  1. 8 1
      unix/syscall_linux_ppc64x.go
  2. 24 0
      unix/syscall_linux_test.go
  3. 10 10
      unix/zsyscall_linux_ppc64.go
  4. 10 10
      unix/zsyscall_linux_ppc64le.go

+ 8 - 1
unix/syscall_linux_ppc64x.go

@@ -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)
+}

+ 24 - 0
unix/syscall_linux_test.go

@@ -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)
+	}
+}

+ 10 - 10
unix/zsyscall_linux_ppc64.go

@@ -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
+}

+ 10 - 10
unix/zsyscall_linux_ppc64le.go

@@ -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
+}