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 [...]"
This commit is contained in:
parent
a710451d92
commit
538cae610c
@ -7,6 +7,7 @@ import (
|
|||||||
"io"
|
"io"
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
"sync"
|
||||||
"syscall"
|
"syscall"
|
||||||
|
|
||||||
"github.com/hanwen/go-fuse/fuse"
|
"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
|
return fuse.OK
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var haveGetdentsWarnOnce sync.Once
|
||||||
|
|
||||||
// OpenDir implements pathfs.FileSystem
|
// OpenDir implements pathfs.FileSystem
|
||||||
func (fs *FS) OpenDir(dirName string, context *fuse.Context) ([]fuse.DirEntry, fuse.Status) {
|
func (fs *FS) OpenDir(dirName string, context *fuse.Context) ([]fuse.DirEntry, fuse.Status) {
|
||||||
tlog.Debug.Printf("OpenDir(%s)", dirName)
|
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)
|
return nil, fuse.ToStatus(err)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
haveGetdentsWarnOnce.Do(func() {
|
||||||
|
tlog.Warn.Printf("OpenDir: Getdents not available, falling back to OpenDir")
|
||||||
|
})
|
||||||
cipherEntries, status = fs.FileSystem.OpenDir(cDirName, context)
|
cipherEntries, status = fs.FileSystem.OpenDir(cDirName, context)
|
||||||
if !status.Ok() {
|
if !status.Ok() {
|
||||||
return nil, status
|
return nil, status
|
||||||
|
@ -8,6 +8,7 @@ package syscallcompat
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
|
"sync"
|
||||||
"syscall"
|
"syscall"
|
||||||
"unsafe"
|
"unsafe"
|
||||||
|
|
||||||
@ -121,6 +122,8 @@ func getdentsName(s syscall.Dirent) (string, error) {
|
|||||||
return string(name), nil
|
return string(name), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var dtUnknownWarnOnce sync.Once
|
||||||
|
|
||||||
// convertDType converts a Dirent.Type to at Stat_t.Mode value.
|
// convertDType converts a Dirent.Type to at Stat_t.Mode value.
|
||||||
func convertDType(dtype uint8, file string) (uint32, error) {
|
func convertDType(dtype uint8, file string) (uint32, error) {
|
||||||
if dtype != syscall.DT_UNKNOWN {
|
if dtype != syscall.DT_UNKNOWN {
|
||||||
@ -128,6 +131,9 @@ func convertDType(dtype uint8, file string) (uint32, error) {
|
|||||||
return uint32(dtype) << 12, nil
|
return uint32(dtype) << 12, nil
|
||||||
}
|
}
|
||||||
// DT_UNKNOWN: we have to call Lstat()
|
// 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
|
var st syscall.Stat_t
|
||||||
err := syscall.Lstat(file, &st)
|
err := syscall.Lstat(file, &st)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
Loading…
Reference in New Issue
Block a user