summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJakob Borg <jakob@kastelo.net>2017-12-29 21:23:06 +0000
committerAudrius Butkevicius <audrius.butkevicius@gmail.com>2017-12-29 21:23:06 +0000
commita9f0659f2f4bf910f82b652fd27a864074ec7ab8 (patch)
tree0c93cfc43a6c8d7776861acdafe68ba29eb552c2
parent9988044bbe637c50db59053672f8ae74df10e433 (diff)
downloadsyncthing-0.14.43-rc.1.tar.gz
syncthing-0.14.43-rc.1.zip
lib/fs: Handle deduplicated files on NTFS (fixes #1845)v0.14.43-rc.1v0.14.43
These files always have the symlink bit set, because they are reparse points. Nonetheless they are not symlinks, and Lstat reports a size for them. We use this fact to disambiguate, and hope fervently that nothing else matches this description so it comes back to bite us... GitHub-Pull-Request: https://github.com/syncthing/syncthing/pull/4622
-rw-r--r--lib/fs/basicfs.go12
-rw-r--r--lib/fs/filesystem.go2
-rw-r--r--lib/fs/fsfileinfo_unix.go13
-rw-r--r--lib/fs/fsfileinfo_windows.go21
4 files changed, 41 insertions, 7 deletions
diff --git a/lib/fs/basicfs.go b/lib/fs/basicfs.go
index 4a0dc0919..8736d621b 100644
--- a/lib/fs/basicfs.go
+++ b/lib/fs/basicfs.go
@@ -322,14 +322,12 @@ type fsFileInfo struct {
os.FileInfo
}
-func (e fsFileInfo) Mode() FileMode {
- return FileMode(e.FileInfo.Mode())
+func (e fsFileInfo) IsSymlink() bool {
+ // Must use fsFileInfo.Mode() because it may apply magic.
+ return e.Mode()&ModeSymlink != 0
}
func (e fsFileInfo) IsRegular() bool {
- return e.FileInfo.Mode().IsRegular()
-}
-
-func (e fsFileInfo) IsSymlink() bool {
- return e.FileInfo.Mode()&os.ModeSymlink == os.ModeSymlink
+ // Must use fsFileInfo.Mode() because it may apply magic.
+ return e.Mode()&ModeType == 0
}
diff --git a/lib/fs/filesystem.go b/lib/fs/filesystem.go
index fe267ac00..346dd2548 100644
--- a/lib/fs/filesystem.go
+++ b/lib/fs/filesystem.go
@@ -126,6 +126,8 @@ const ModePerm = FileMode(os.ModePerm)
const ModeSetgid = FileMode(os.ModeSetgid)
const ModeSetuid = FileMode(os.ModeSetuid)
const ModeSticky = FileMode(os.ModeSticky)
+const ModeSymlink = FileMode(os.ModeSymlink)
+const ModeType = FileMode(os.ModeType)
const PathSeparator = os.PathSeparator
const OptAppend = os.O_APPEND
const OptCreate = os.O_CREATE
diff --git a/lib/fs/fsfileinfo_unix.go b/lib/fs/fsfileinfo_unix.go
new file mode 100644
index 000000000..96b1a392f
--- /dev/null
+++ b/lib/fs/fsfileinfo_unix.go
@@ -0,0 +1,13 @@
+// Copyright (C) 2017 The Syncthing Authors.
+//
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this file,
+// You can obtain one at https://mozilla.org/MPL/2.0/.
+
+// +build !windows
+
+package fs
+
+func (e fsFileInfo) Mode() FileMode {
+ return FileMode(e.FileInfo.Mode())
+}
diff --git a/lib/fs/fsfileinfo_windows.go b/lib/fs/fsfileinfo_windows.go
new file mode 100644
index 000000000..fdd524d1c
--- /dev/null
+++ b/lib/fs/fsfileinfo_windows.go
@@ -0,0 +1,21 @@
+// Copyright (C) 2017 The Syncthing Authors.
+//
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this file,
+// You can obtain one at https://mozilla.org/MPL/2.0/.
+
+package fs
+
+import (
+ "os"
+)
+
+func (e fsFileInfo) Mode() FileMode {
+ m := e.FileInfo.Mode()
+ if m&os.ModeSymlink != 0 && e.Size() > 0 {
+ // "Symlinks" with nonzero size are in fact "hard" links, such as
+ // NTFS deduped files. Remove the symlink bit.
+ m &^= os.ModeSymlink
+ }
+ return FileMode(m)
+}