go: os: `ReadDir` fails on file systems without File ID support on Windows

What version of Go are you using (go version)?

$ go version
go version go1.21.0 windows/amd64

Does this issue reproduce with the latest release?

Yes

What operating system and processor architecture are you using (go env)?

go env Output
$ go env
set GO111MODULE=
set GOARCH=amd64
set GOBIN=
set GOCACHE=C:\Users\hajimehoshi\AppData\Local\go-build
set GOENV=C:\Users\hajimehoshi\AppData\Roaming\go\env
set GOEXE=.exe
set GOEXPERIMENT=
set GOFLAGS=
set GOHOSTARCH=amd64
set GOHOSTOS=windows
set GOINSECURE=
set GOMODCACHE=C:\Users\hajimehoshi\go\pkg\mod
set GONOPROXY=
set GONOSUMDB=
set GOOS=windows
set GOPATH=C:\Users\hajimehoshi\go
set GOPRIVATE=
set GOPROXY=https://proxy.golang.org,direct
set GOROOT=C:\Program Files\Go
set GOSUMDB=sum.golang.org
set GOTMPDIR=
set GOTOOLCHAIN=auto
set GOTOOLDIR=C:\Program Files\Go\pkg\tool\windows_amd64
set GOVCS=
set GOVERSION=go1.21.0
set GCCGO=gccgo
set GOAMD64=v1
set AR=ar
set CC=gcc
set CXX=g++
set CGO_ENABLED=1
set GOMOD=\\Mac\Home\unctest\go.mod
set GOWORK=
set CGO_CFLAGS=-O2 -g
set CGO_CPPFLAGS=
set CGO_CXXFLAGS=-O2 -g
set CGO_FFLAGS=-O2 -g
set CGO_LDFLAGS=-O2 -g
set PKG_CONFIG=pkg-config
set GOGCCFLAGS=-m64 -mthreads -Wl,--no-gc-sections -fmessage-length=0 -ffile-prefix-map=C:\Users\HAJIME~1\AppData\Local\Temp\go-build3663691949=/tmp/go-build -gno-record-gcc-switches

What did you do?

Prepare these files in a UNC directory starting with \\ like \\Mac\Home\unctest. Here, I assume the current directory is \\Mac\Home\unctest:

\\Mac\Home\unctest\go.mod:

module foo

go 1.21

\\Mac\Home\unctest\main.go

package main

import (
        "foo/bar"
)

func main() {
        bar.Hello()
}

\\Mac\Home\unctest\bar\hello.go

package bar                                                                                                                                                                                                                                                                           
                                                                                                                                                                                                                                                                                      
func Hello() {                                                                                                                                                                                                                                                                        
        println("bar")                                                                                                                                                                                                                                                                
} 

And run go run . at \\Mac\Home\unctest.

What did you expect to see?

bar is printed

What did you see instead?

Running the program fails:

PS Microsoft.PowerShell.Core\FileSystem::\\Mac\Home\unctest> go run .
GetFileInformationByHandleEx \\Mac\Home\unctest: The parameter is incorrect.

About this issue

  • Original URL
  • State: closed
  • Created a year ago
  • Comments: 32 (29 by maintainers)

Most upvoted comments

PS Microsoft.PowerShell.Core\FileSystem::\\Mac\Home\unctest> gotip download 518196
This will download and execute code from golang.org/cl/518196, continue? [y/n] y
Fetching CL 518196, Patch Set 5...
remote: Finding sources: 100% (47720/47720)
Receiving objects: 100% (47720/47720), 58.92 MiB | 6.34 MiB/s, done.

Resolving deltas: 100% (31893/31893), completed with 675 local objects.
From https://go.googlesource.com/go
 * branch                  refs/changes/96/518196/5 -> FETCH_HEAD
Warning: you are leaving 1 commit behind, not connected to
any of your branches:

  ddd112b9f7 [release-branch.go1.21] os: support file systems without file IDs when reading directories on windows

HEAD is now at 7ba8a3b518 [release-branch.go1.21] os: support file systems without file IDs when reading directories on windows
Building Go cmd/dist using C:\Program Files\Go. (go1.21.0 windows/amd64)
Building Go toolchain1 using C:\Program Files\Go.
Building Go bootstrap cmd/go (go_bootstrap) using Go toolchain1.
Building Go toolchain2 using go_bootstrap and Go toolchain1.
Building Go toolchain3 using go_bootstrap and Go toolchain2.
Building packages and commands for windows/amd64.
---
Installed Go for windows/amd64 in C:\Users\hajimehoshi\sdk\gotip
Installed commands in C:\Users\hajimehoshi\sdk\gotip\bin
Success. You may now run 'gotip'!
PS Microsoft.PowerShell.Core\FileSystem::\\Mac\Home\unctest> gotip run .\main.go
os.SameFile(f1, f1): true
os.SameFile(f2, f2): true
os.SameFile(f3, f3): true
os.SameFile(f4, f4): true
os.SameFile(f1, f2): false
os.SameFile(f1, f3): true
os.SameFile(f2, f3): false
os.SameFile(f2, f4): true

This seems to be fixed.

@qmuntal Yep, the patch seems to work now.

PS C:\Users\hajimehoshi> gotip download 518196
This will download and execute code from golang.org/cl/518196, continue? [y/n] y
Fetching CL 518196, Patch Set 4...
remote: Finding sources: 100% (47719/47719)
Receiving objects: 100% (47719/47719), 58.93 MiB | 6.33 MiB/s, done.
remote: Total 47719 (delta 31888), reused 42826 (delta 31888)
Resolving deltas: 100% (31888/31888), completed with 675 local objects.
From https://go.googlesource.com/go
 * branch                  refs/changes/96/518196/4 -> FETCH_HEAD
Warning: you are leaving 262 commits behind, not connected to
any of your branches:

  e17e4a5e3f os: support file systems without file IDs when reading directories on windows
  d9f7e1dc73 runtime: fix asan asm on amd64
  e6637f3293 os: test that copying to append-only files doesn't fail on Linux
  6c5fc6d7ce all: update vendored dependencies
 ... and 258 more.

HEAD is now at ddd112b9f7 [release-branch.go1.21] os: support file systems without file IDs when reading directories on windows
Building Go cmd/dist using C:\Program Files\Go. (go1.21.0 windows/amd64)
Building Go toolchain1 using C:\Program Files\Go.
Building Go bootstrap cmd/go (go_bootstrap) using Go toolchain1.
Building Go toolchain2 using go_bootstrap and Go toolchain1.
Building Go toolchain3 using go_bootstrap and Go toolchain2.
Building packages and commands for windows/amd64.
---
Installed Go for windows/amd64 in C:\Users\hajimehoshi\sdk\gotip
Installed commands in C:\Users\hajimehoshi\sdk\gotip\bin
Success. You may now run 'gotip'!
PS Z:\unctest> gotip version
go version go1.21.0 windows/amd64
PS Z:\unctest> gotip run .
PS Z:\unctest> gotip run .\main.go

I’m not familiar with this, but smb, maybe?

if you mount the UNC path as a drive letter, and refer to it by the drive letter instead of the UNC path, does ReadDir still fail?

I’ll try tomorrow.

@bcmills

does os.ReadDir(\\Mac\Home\unctest) succeed for that directory?

Apparently no:

package main

import (
        "os"
)

func main() {
        _, err := os.ReadDir(`\\Mac\Home\unctest`)
        if err != nil {
                println("os.ReadDir failed!: ", err.Error())
        }
}
PS Microsoft.PowerShell.Core\FileSystem::\\Mac\Home\unctest> go run .\main.go
os.ReadDir failed!:  GetFileInformationByHandleEx \\Mac\Home\unctest: The parameter is incorrect.

What kind of filesystem is serving that path?

I’m using Parallels. The host is macOS and the guest is Windows. \\Mac\Home is a path for my home directory of macOS from Windows.