summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJakob Unterwurzacher2017-09-03 15:05:54 +0200
committerJakob Unterwurzacher2017-09-03 15:05:54 +0200
commit538cae610cc4f7512cfb7a3b64a47e2fba9ea3c7 (patch)
tree30971b89484437aefe2f68f125af4d1a7b7b8a30
parenta710451d9218aea35709343e5de94a004e431c35 (diff)
syscallcompat: Getdents: warn once if we get DT_UNKNOWN
...and if Getdents is not available at all. Due to this warning I now know that SSHFS always returns DT_UNKNOWN: gocryptfs[8129]: Getdents: convertDType: received DT_UNKNOWN, falling back to Lstat This behavoir is confirmed at http://ahefner.livejournal.com/16875.html: "With sshfs, I finally found that obscure case. The dtype is always set to DT_UNKNOWN [...]"
-rw-r--r--internal/fusefrontend/fs_dir.go6
-rw-r--r--internal/syscallcompat/getdents_linux.go6
2 files changed, 12 insertions, 0 deletions
diff --git a/internal/fusefrontend/fs_dir.go b/internal/fusefrontend/fs_dir.go
index 211eeea..c87cc02 100644
--- a/internal/fusefrontend/fs_dir.go
+++ b/internal/fusefrontend/fs_dir.go
@@ -7,6 +7,7 @@ import (
"io"
"os"
"path/filepath"
+ "sync"
"syscall"
"github.com/hanwen/go-fuse/fuse"
@@ -234,6 +235,8 @@ func (fs *FS) Rmdir(path string, context *fuse.Context) (code fuse.Status) {
return fuse.OK
}
+var haveGetdentsWarnOnce sync.Once
+
// OpenDir implements pathfs.FileSystem
func (fs *FS) OpenDir(dirName string, context *fuse.Context) ([]fuse.DirEntry, fuse.Status) {
tlog.Debug.Printf("OpenDir(%s)", dirName)
@@ -252,6 +255,9 @@ func (fs *FS) OpenDir(dirName string, context *fuse.Context) ([]fuse.DirEntry, f
return nil, fuse.ToStatus(err)
}
} else {
+ haveGetdentsWarnOnce.Do(func() {
+ tlog.Warn.Printf("OpenDir: Getdents not available, falling back to OpenDir")
+ })
cipherEntries, status = fs.FileSystem.OpenDir(cDirName, context)
if !status.Ok() {
return nil, status
diff --git a/internal/syscallcompat/getdents_linux.go b/internal/syscallcompat/getdents_linux.go
index 97cd75f..55bffff 100644
--- a/internal/syscallcompat/getdents_linux.go
+++ b/internal/syscallcompat/getdents_linux.go
@@ -8,6 +8,7 @@ package syscallcompat
import (
"bytes"
+ "sync"
"syscall"
"unsafe"
@@ -121,6 +122,8 @@ func getdentsName(s syscall.Dirent) (string, error) {
return string(name), nil
}
+var dtUnknownWarnOnce sync.Once
+
// convertDType converts a Dirent.Type to at Stat_t.Mode value.
func convertDType(dtype uint8, file string) (uint32, error) {
if dtype != syscall.DT_UNKNOWN {
@@ -128,6 +131,9 @@ func convertDType(dtype uint8, file string) (uint32, error) {
return uint32(dtype) << 12, nil
}
// DT_UNKNOWN: we have to call Lstat()
+ dtUnknownWarnOnce.Do(func() {
+ tlog.Warn.Printf("Getdents: convertDType: received DT_UNKNOWN, falling back to Lstat")
+ })
var st syscall.Stat_t
err := syscall.Lstat(file, &st)
if err != nil {