[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