diff --git a/.github/workflows/build-infra-dockers.yaml b/.github/workflows/build-infra-dockers.yaml index f899a3524..5caf6e333 100644 --- a/.github/workflows/build-infra-dockers.yaml +++ b/.github/workflows/build-infra-dockers.yaml @@ -7,7 +7,7 @@ on: - infra-* env: - GO_VERSION: "~1.22.3" + GO_VERSION: "~1.23.0" CGO_ENABLED: "0" BUILD_USER: docker BUILD_HOST: github.syncthing.net diff --git a/.github/workflows/build-syncthing.yaml b/.github/workflows/build-syncthing.yaml index 984d222b7..42e76cd18 100644 --- a/.github/workflows/build-syncthing.yaml +++ b/.github/workflows/build-syncthing.yaml @@ -12,7 +12,7 @@ env: # The go version to use for builds. We set check-latest to true when # installing, so we get the latest patch version that matches the # expression. - GO_VERSION: "~1.22.3" + GO_VERSION: "~1.23.0" # Optimize compatibility on the slow archictures. GO386: softfloat @@ -48,7 +48,7 @@ jobs: runner: ["windows-latest", "ubuntu-latest", "macos-latest"] # The oldest version in this list should match what we have in our go.mod. # Variables don't seem to be supported here, or we could have done something nice. - go: ["~1.21.7", "~1.22.3"] + go: ["~1.22.6", "~1.23.0"] runs-on: ${{ matrix.runner }} steps: - name: Set git to use LF diff --git a/go.mod b/go.mod index 4a1743f1a..aeb9bdbf2 100644 --- a/go.mod +++ b/go.mod @@ -1,6 +1,6 @@ module github.com/syncthing/syncthing -go 1.21.0 +go 1.22.0 require ( github.com/AudriusButkevicius/recli v0.0.7-0.20220911121932-d000ce8fbf0f diff --git a/lib/fs/basicfs_lstat_windows.go b/lib/fs/basicfs_lstat_windows.go index 5a0024c71..de2f63280 100644 --- a/lib/fs/basicfs_lstat_windows.go +++ b/lib/fs/basicfs_lstat_windows.go @@ -11,15 +11,15 @@ package fs import ( "fmt" + "go/version" "os" + "runtime" "syscall" "unsafe" "golang.org/x/sys/windows" ) -const IO_REPARSE_TAG_DEDUP = 0x80000013 - func readReparseTag(path string) (uint32, error) { namep, err := syscall.UTF16PtrFromString(path) if err != nil { @@ -60,10 +60,6 @@ func isDirectoryJunction(reparseTag uint32) bool { return reparseTag == windows.IO_REPARSE_TAG_MOUNT_POINT } -func isDeduplicatedFile(reparseTag uint32) bool { - return reparseTag == IO_REPARSE_TAG_DEDUP -} - type dirJunctFileInfo struct { os.FileInfo } @@ -71,21 +67,22 @@ type dirJunctFileInfo struct { func (fi *dirJunctFileInfo) Mode() os.FileMode { // Simulate a directory and not a symlink; also set the execute // bits so the directory can be traversed Unix-side. - return fi.FileInfo.Mode() ^ os.ModeSymlink | os.ModeDir | 0111 + return fi.FileInfo.Mode() ^ junctionPointModeMask | os.ModeDir | 0111 } func (fi *dirJunctFileInfo) IsDir() bool { return true } -type dedupFileInfo struct { - os.FileInfo -} +var junctionPointModeMask os.FileMode -func (fi *dedupFileInfo) Mode() os.FileMode { - // A deduplicated file should be treated as a regular file and not an - // irregular file. - return fi.FileInfo.Mode() &^ os.ModeIrregular +func init() { + junctionPointModeMask = os.ModeSymlink + if version.Compare(runtime.Version(), "go1.23") >= 0 { + // if GODEBUG=winsymlink=0, then we are in g1.22 mode so let's check for + // os.ModeSymlink as well, as it can't hurt. + junctionPointModeMask |= os.ModeIrregular + } } func (f *BasicFilesystem) underlyingLstat(name string) (os.FileInfo, error) { @@ -96,19 +93,11 @@ func (f *BasicFilesystem) underlyingLstat(name string) (os.FileInfo, error) { if err == nil { // NTFS directory junctions can be treated as ordinary directories, // see https://forum.syncthing.net/t/option-to-follow-directory-junctions-symbolic-links/14750 - if fi.Mode()&os.ModeSymlink != 0 && f.junctionsAsDirs { + if fi.Mode()&junctionPointModeMask != 0 && f.junctionsAsDirs { if reparseTag, reparseErr := readReparseTag(name); reparseErr == nil && isDirectoryJunction(reparseTag) { return &dirJunctFileInfo{fi}, nil } } - - // Workaround for #9120 till golang properly handles deduplicated files by - // considering them regular files. - if fi.Mode()&os.ModeIrregular != 0 { - if reparseTag, reparseErr := readReparseTag(name); reparseErr == nil && isDeduplicatedFile(reparseTag) { - return &dedupFileInfo{fi}, nil - } - } } return fi, err