Skip to content

Commit 49319ed

Browse files
committed
os: avoid GetFileInformationByHandleEx call when stat'ing files on Windows
os.Stat and os.Lstat on Windows use GetFileInformationByHandleEx to retrieve file information for reparse points and files that GetFileAttributesEx does not handle. However, GetFileInformationByHandleEx is only necessary for reparse points, so we can avoid the call for regular files. With this change we can drop the FAT hack that was added in CL 154377, as files won't have the FILE_ATTRIBUTE_REPARSE_POINT attribute set on that file system. Change-Id: Id18639067a6c3fa1bb2c6706d5b79358c224fe37 Reviewed-on: https://go-review.googlesource.com/c/go/+/566397 Reviewed-by: Carlos Amedee <[email protected]> Reviewed-by: Alex Brainman <[email protected]> LUCI-TryBot-Result: Go LUCI <[email protected]> Reviewed-by: Bryan Mills <[email protected]>
1 parent f777768 commit 49319ed

File tree

1 file changed

+7
-11
lines changed

1 file changed

+7
-11
lines changed

src/os/types_windows.go

Lines changed: 7 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -48,18 +48,14 @@ func newFileStatFromGetFileInformationByHandle(path string, h syscall.Handle) (f
4848
return nil, &PathError{Op: "GetFileInformationByHandle", Path: path, Err: err}
4949
}
5050

51-
var ti windows.FILE_ATTRIBUTE_TAG_INFO
52-
err = windows.GetFileInformationByHandleEx(h, windows.FileAttributeTagInfo, (*byte)(unsafe.Pointer(&ti)), uint32(unsafe.Sizeof(ti)))
53-
if err != nil {
54-
if errno, ok := err.(syscall.Errno); ok && errno == windows.ERROR_INVALID_PARAMETER {
55-
// It appears calling GetFileInformationByHandleEx with
56-
// FILE_ATTRIBUTE_TAG_INFO fails on FAT file system with
57-
// ERROR_INVALID_PARAMETER. Clear ti.ReparseTag in that
58-
// instance to indicate no symlinks are possible.
59-
ti.ReparseTag = 0
60-
} else {
51+
var reparseTag uint32
52+
if d.FileAttributes&syscall.FILE_ATTRIBUTE_REPARSE_POINT != 0 {
53+
var ti windows.FILE_ATTRIBUTE_TAG_INFO
54+
err = windows.GetFileInformationByHandleEx(h, windows.FileAttributeTagInfo, (*byte)(unsafe.Pointer(&ti)), uint32(unsafe.Sizeof(ti)))
55+
if err != nil {
6156
return nil, &PathError{Op: "GetFileInformationByHandleEx", Path: path, Err: err}
6257
}
58+
reparseTag = ti.ReparseTag
6359
}
6460

6561
return &fileStat{
@@ -73,7 +69,7 @@ func newFileStatFromGetFileInformationByHandle(path string, h syscall.Handle) (f
7369
vol: d.VolumeSerialNumber,
7470
idxhi: d.FileIndexHigh,
7571
idxlo: d.FileIndexLow,
76-
ReparseTag: ti.ReparseTag,
72+
ReparseTag: reparseTag,
7773
// fileStat.path is used by os.SameFile to decide if it needs
7874
// to fetch vol, idxhi and idxlo. But these are already set,
7975
// so set fileStat.path to "" to prevent os.SameFile doing it again.

0 commit comments

Comments
 (0)