summaryrefslogtreecommitdiff
path: root/internal/syscallcompat
diff options
context:
space:
mode:
authorJakob Unterwurzacher2018-11-17 17:44:21 +0100
committerJakob Unterwurzacher2018-11-17 17:44:21 +0100
commite665df71795a3a4656f6eae70211bb59723cd01e (patch)
tree954826dd8044800a4475ad9d4385b792507d1c07 /internal/syscallcompat
parentd882ed45da9464e0e244cd8a3bf0168b5b618fd9 (diff)
syscallcompat: downgrade DT_UNKNOWN message level on XFS
Old XFS filesystems always return DT_UNKNOWN. Downgrade the message to "info" level if we are on XFS. Using the "warning" level means that users on old XFS filesystems cannot run the test suite as it intentionally aborts on any warnings. Fixes https://github.com/rfjakob/gocryptfs/issues/267
Diffstat (limited to 'internal/syscallcompat')
-rw-r--r--internal/syscallcompat/getdents_linux.go19
1 files changed, 16 insertions, 3 deletions
diff --git a/internal/syscallcompat/getdents_linux.go b/internal/syscallcompat/getdents_linux.go
index 1387023..3853f2d 100644
--- a/internal/syscallcompat/getdents_linux.go
+++ b/internal/syscallcompat/getdents_linux.go
@@ -123,6 +123,21 @@ func getdentsName(s unix.Dirent) (string, error) {
var dtUnknownWarnOnce sync.Once
+func dtUnknownWarn(dirfd int) {
+ const XFS_SUPER_MAGIC = 0x58465342 // From man 2 statfs
+ var buf syscall.Statfs_t
+ err := syscall.Fstatfs(dirfd, &buf)
+ if err == nil && buf.Type == XFS_SUPER_MAGIC {
+ // Old XFS filesystems always return DT_UNKNOWN. Downgrade the message
+ // to "info" level if we are on XFS.
+ // https://github.com/rfjakob/gocryptfs/issues/267
+ tlog.Info.Printf("Getdents: convertDType: received DT_UNKNOWN, fstype=xfs, falling back to stat")
+ } else {
+ tlog.Warn.Printf("Getdents: convertDType: received DT_UNKNOWN, fstype=%#x, falling back to stat",
+ buf.Type)
+ }
+}
+
// convertDType converts a Dirent.Type to at Stat_t.Mode value.
func convertDType(dirfd int, name string, dtype uint8) (uint32, error) {
if dtype != syscall.DT_UNKNOWN {
@@ -130,9 +145,7 @@ func convertDType(dirfd int, name string, dtype uint8) (uint32, error) {
return uint32(dtype) << 12, nil
}
// DT_UNKNOWN: we have to call stat()
- dtUnknownWarnOnce.Do(func() {
- tlog.Warn.Printf("Getdents: convertDType: received DT_UNKNOWN, falling back to stat")
- })
+ dtUnknownWarnOnce.Do(func() { dtUnknownWarn(dirfd) })
var st unix.Stat_t
err := Fstatat(dirfd, name, &st, unix.AT_SYMLINK_NOFOLLOW)
if err != nil {