-
Notifications
You must be signed in to change notification settings - Fork 17.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
os: ReadDir
fails on file systems without File ID support on Windows
#61907
Comments
I have confirmed Go 1.20 worked:
So, this is a regression. |
I could minimize the test case:
package main
func main() {
println("hello")
} and then run
|
CC @bcmills maybe? |
succeeded, and
failed. I think using something related to a module fails when the current directory is a UNC path. |
I wasn't aware that it was even possible for the current working directory to be a UNC path. (To my knowledge it still isn't possible with I suspect that this may be a side effect of https://go.dev/cl/452995 (attn @qmuntal). (CC @golang/windows) |
@hajimehoshi, does |
Apparently no: package main
import (
"os"
)
func main() {
_, err := os.ReadDir(`\\Mac\Home\unctest`)
if err != nil {
println("os.ReadDir failed!: ", err.Error())
}
}
I'm using Parallels. The host is macOS and the guest is Windows. |
ReadDir
fails for UNC paths shared with Windows using Parallels
@gopherbot, please backport to Go 1.21. This is a significant regression in |
Backport issue(s) opened: #61910 (for 1.21). Remember to create the cherry-pick CL(s) as soon as the patch is submitted to master, according to https://go.dev/wiki/MinorReleases. |
UNC paths are available even without Parallels. For example: |
Makes sense. Do you happen to know whether your share is using SMB or AFP? |
And, another question: if you mount the UNC path as a drive letter, and refer to it by the drive letter instead of the UNC path, does |
I'm not familiar with this, but smb, maybe?
I'll try tomorrow. |
Z: is the drive letter for the same home directory. package main
import (
"os"
)
func main() {
if _, err := os.ReadDir(`\\Mac\Home\unctest`); err != nil {
println("os.ReadDir with UNC failed!: ", err.Error())
}
if _, err := os.ReadDir(`Z:\`); err != nil {
println("os.ReadDir with Z: failed!: ", err.Error())
}
} and
So, whether the path is UNC or not doesn't matter! EDIT: Go 1.20 worked (after modifying go.mod for Go 1.20):
|
Thanks for the detailed report @hajimehoshi. I suspect that your file system doesn't support traversing directories using FILE_ID_BOTH_DIR_INFO, probably because it can't generate unique 64-bit file IDs. I'll prepare a CL to fallback to FILE_FULL_DIR_INFO if |
Change https://go.dev/cl/518195 mentions this issue: |
@hajimehoshi can you test if CL 452995 fixes your issue? You need to follow these steps to run the Go toolchain at CL 452995:
Edit: fix CL number |
@qmuntal This was not fixed unfortunately:
|
Wasn't the fix https://go-review.googlesource.com/c/go/+/518195, not https://go-review.googlesource.com/c/go/+/452995 by the way? |
So, should I install go at ~/Go1.4...? |
Change https://go.dev/cl/518196 mentions this issue: |
Yep, my fault.
CL 518195 is based on master, which needs at least go1.20 to build. You probably don't have it installed. I've just cherry-picked it into go1.21 release branch: https://go-review.googlesource.com/c/go/+/518196. Please try with |
@qmuntal Yep, the patch seems to work now.
|
ReadDir
fails for UNC paths shared with Windows using ParallelsReadDir
fails on fyle systems without File ID support on Windows
ReadDir
fails on fyle systems without File ID support on WindowsReadDir
fails on file systems without File ID support on Windows
@hajimehoshi could you check if os.SameFile returns true for two different files under |
@qmuntal This seems to work as expected, even with the current Go 1.21.0. package main
import (
"fmt"
"os"
)
func main() {
// \\Mac\Home\ and Z:\ are the same path.
f1, err := os.Stat(`\\Mac\Home\unctest\main.go`)
if err != nil {
fmt.Fprintf(os.Stderr, "%v\n", err)
}
f2, err := os.Stat(`Z:\unctest\main.go`)
if err != nil {
fmt.Fprintf(os.Stderr, "%v\n", err)
}
fmt.Printf("os.SameFile(f1, f1): %t\n", os.SameFile(f1, f1))
fmt.Printf("os.SameFile(f2, f2): %t\n", os.SameFile(f2, f2))
fmt.Printf("os.SameFile(f1, f2): %t\n", os.SameFile(f1, f2))
} Not patched:
Patched:
|
Oh two different files? Wait a sec. |
package main
import (
"fmt"
"os"
)
func main() {
f1, err := os.Stat(`\\Mac\Home\unctest\main.go`)
if err != nil {
fmt.Fprintf(os.Stderr, "%v\n", err)
}
f2, err := os.Stat(`\\Mac\Home\unctest\go.mod`)
if err != nil {
fmt.Fprintf(os.Stderr, "%v\n", err)
}
fmt.Printf("os.SameFile(f1, f1): %t\n", os.SameFile(f1, f1))
fmt.Printf("os.SameFile(f2, f2): %t\n", os.SameFile(f2, f2))
fmt.Printf("os.SameFile(f1, f2): %t\n", os.SameFile(f1, f2))
} Not patched:
Patched:
Is this expected? |
I was expecting it to always return Here is another experiment: package main
import (
"fmt"
"os"
)
func main() {
files, err := os.ReadDir(`\\Mac\Home\unctest`)
if err != nil {
println("os.ReadDir with UNC failed!: ", err.Error())
}
f1, _ := files[0].Info()
f2, _ := files[1].Info()
f3, err := os.Stat(`\\Mac\Home\unctest\` + f1.Name())
if err != nil {
fmt.Fprintf(os.Stderr, "%v\n", err)
}
f4, err := os.Stat(`\\Mac\Home\unctest\` + f2.Name())
if err != nil {
fmt.Fprintf(os.Stderr, "%v\n", err)
}
fmt.Printf("os.SameFile(f1, f1): %t\n", os.SameFile(f1, f1))
fmt.Printf("os.SameFile(f2, f2): %t\n", os.SameFile(f2, f2))
fmt.Printf("os.SameFile(f3, f3): %t\n", os.SameFile(f3, f3))
fmt.Printf("os.SameFile(f4, f4): %t\n", os.SameFile(f4, f4))
fmt.Printf("os.SameFile(f1, f2): %t\n", os.SameFile(f1, f2))
fmt.Printf("os.SameFile(f1, f3): %t\n", os.SameFile(f1, f3))
fmt.Printf("os.SameFile(f2, f3): %t\n", os.SameFile(f2, f3))
fmt.Printf("os.SameFile(f2, f4): %t\n", os.SameFile(f2, f4))
} Use go1.20 and go1.21 patched please. There might has been |
Go 1.20:
Go 1.21:
Go 1.21 patched:
|
Thanks! There is clearly something weird in go1.21 that hasn't been fixed in CL 518196. I'll give it another pass to see what's happening. |
Done. @hajimehoshi can you updated the patched go1.21 toolchain(run |
This seems to be fixed. |
What version of Go are you using (
go version
)?Does this issue reproduce with the latest release?
Yes
What operating system and processor architecture are you using (
go env
)?go env
OutputWhat 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
:\\Mac\Home\unctest\main.go
\\Mac\Home\unctest\bar\hello.go
And run
go run .
at\\Mac\Home\unctest
.What did you expect to see?
bar
is printedWhat did you see instead?
Running the program fails:
The text was updated successfully, but these errors were encountered: