[newlib-cygwin/main] Cygwin: readdir: allow using FileIdBothDirectoryInformation on NFS
Corinna Vinschen
corinna@sourceware.org
Mon Feb 2 20:34:37 GMT 2026
https://sourceware.org/git/gitweb.cgi?p=newlib-cygwin.git;h=35a1e39679735cde80cec99d0d09bb1d5915a99f
commit 35a1e39679735cde80cec99d0d09bb1d5915a99f
Author: Corinna Vinschen <corinna@vinschen.de>
AuthorDate: Mon Feb 2 21:24:08 2026 +0100
Commit: Corinna Vinschen <corinna@vinschen.de>
CommitDate: Mon Feb 2 21:24:28 2026 +0100
Cygwin: readdir: allow using FileIdBothDirectoryInformation on NFS
As the comment in opendir() already outlines, dangling NFS symlinks
only show up in directory listings with FileIdBothDirectoryInformation,
if the NFS share is mounted to a drive letter. For that reason we
always use FileNamesInformation on NFS instead.
Add a check if the path is a drive letter path. If so, switch to
using FileIdBothDirectoryInformation. This should give us a
performance gain because this call immediately returns the inode
number. We don't have to open every listed file, too, to fetch the
inode number.
Signed-off-by: Corinna Vinschen <corinna@vinschen.de>
Diff:
---
winsup/cygwin/fhandler/disk_file.cc | 11 +++++++++--
1 file changed, 9 insertions(+), 2 deletions(-)
diff --git a/winsup/cygwin/fhandler/disk_file.cc b/winsup/cygwin/fhandler/disk_file.cc
index d54d3747eae6..f284b4a05c9f 100644
--- a/winsup/cygwin/fhandler/disk_file.cc
+++ b/winsup/cygwin/fhandler/disk_file.cc
@@ -2254,7 +2254,11 @@ fhandler_disk_file::opendir (int fd)
{
dir->__flags |= dirent_set_d_ino;
if (pc.fs_is_nfs ())
- dir->__flags |= dirent_nfs_d_ino;
+ {
+ dir->__flags |= dirent_nfs_d_ino;
+ if (isdrive (pc.get_win32 ()))
+ dir->__flags |= dirent_get_d_ino;
+ }
else if (!pc.has_buggy_fileid_dirinfo ())
dir->__flags |= dirent_get_d_ino;
}
@@ -2501,7 +2505,10 @@ fhandler_disk_file::readdir (DIR *dir, dirent *de)
{
FileName = buf->FileName;
FileNameLength = buf->FileNameLength;
- FileAttributes = buf->FileAttributes;
+ /* Ignore FileAttributes on NFS. The value is copied from
+ the symlink target and thus wrong. */
+ FileAttributes = (dir->__flags & dirent_nfs_d_ino)
+ ? 0 : buf->FileAttributes;
if ((dir->__flags & dirent_set_d_ino))
de->d_ino = buf->FileId.QuadPart;
}
More information about the Cygwin-cvs
mailing list