From 26ba8103bf2422493a01b57b8ee53aa9b1e867f7 Mon Sep 17 00:00:00 2001
From: Jakob Unterwurzacher
Date: Wed, 31 Jan 2018 18:59:10 +0100
Subject: syscallcompat: switch from syscall.Getdents to unix.Getdents

On mips64le, syscall.Getdents() and struct syscall.Dirent do
not fit together, causing our Getdents implementation to
return garbage ( https://github.com/rfjakob/gocryptfs/issues/200
and https://github.com/golang/go/issues/23624 ).

Switch to unix.Getdents which does not have this problem -
the next Go release with the syscall package fixes is too
far away, and will take time to trickle into distros.
---
 internal/syscallcompat/getdents_linux.go | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/internal/syscallcompat/getdents_linux.go b/internal/syscallcompat/getdents_linux.go
index 146517c..1387023 100644
--- a/internal/syscallcompat/getdents_linux.go
+++ b/internal/syscallcompat/getdents_linux.go
@@ -19,14 +19,14 @@ import (
 	"github.com/rfjakob/gocryptfs/internal/tlog"
 )
 
-const sizeofDirent = int(unsafe.Sizeof(syscall.Dirent{}))
+const sizeofDirent = int(unsafe.Sizeof(unix.Dirent{}))
 
 // maxReclen sanity check: Reclen should never be larger than this.
 // Due to padding between entries, it is 280 even on 32-bit architectures.
 // See https://github.com/rfjakob/gocryptfs/issues/197 for details.
 const maxReclen = 280
 
-// getdents wraps syscall.Getdents and converts the result to []fuse.DirEntry.
+// getdents wraps unix.Getdents and converts the result to []fuse.DirEntry.
 func getdents(fd int) ([]fuse.DirEntry, error) {
 	// Collect syscall result in smartBuf.
 	// "bytes.Buffer" is smart about expanding the capacity and avoids the
@@ -34,7 +34,7 @@ func getdents(fd int) ([]fuse.DirEntry, error) {
 	var smartBuf bytes.Buffer
 	tmp := make([]byte, 10000)
 	for {
-		n, err := syscall.Getdents(fd, tmp)
+		n, err := unix.Getdents(fd, tmp)
 		if err != nil {
 			return nil, err
 		}
@@ -51,7 +51,7 @@ func getdents(fd int) ([]fuse.DirEntry, error) {
 	// a fuse.DirEntry slice of the correct size at once.
 	var numEntries, offset int
 	for offset < len(buf) {
-		s := *(*syscall.Dirent)(unsafe.Pointer(&buf[offset]))
+		s := *(*unix.Dirent)(unsafe.Pointer(&buf[offset]))
 		if s.Reclen == 0 {
 			tlog.Warn.Printf("Getdents: corrupt entry #%d: Reclen=0 at offset=%d. Returning EBADR",
 				numEntries, offset)
@@ -73,7 +73,7 @@ func getdents(fd int) ([]fuse.DirEntry, error) {
 	entries := make([]fuse.DirEntry, 0, numEntries)
 	offset = 0
 	for offset < len(buf) {
-		s := *(*syscall.Dirent)(unsafe.Pointer(&buf[offset]))
+		s := *(*unix.Dirent)(unsafe.Pointer(&buf[offset]))
 		name, err := getdentsName(s)
 		if err != nil {
 			return nil, err
@@ -100,7 +100,7 @@ func getdents(fd int) ([]fuse.DirEntry, error) {
 
 // getdentsName extracts the filename from a Dirent struct and returns it as
 // a Go string.
-func getdentsName(s syscall.Dirent) (string, error) {
+func getdentsName(s unix.Dirent) (string, error) {
 	// After the loop, l contains the index of the first '\0'.
 	l := 0
 	for l = range s.Name {
-- 
cgit v1.2.3