https://sourceware.org/git/gitweb.cgi?p=newlib-cygwin.git;h=35a1e39679735cde80cec99d0d09bb1d5915a99f

commit 35a1e39679735cde80cec99d0d09bb1d5915a99f
Author:     Corinna Vinschen <[email protected]>
AuthorDate: Mon Feb 2 21:24:08 2026 +0100
Commit:     Corinna Vinschen <[email protected]>
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 <[email protected]>

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;
        }

Reply via email to