This is the mail archive of the cygwin-cvs@cygwin.com mailing list for the Cygwin project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[newlib-cygwin] readdir() with mount point dentry, return mount point INO


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

commit 0a9edd73e3abb85162f9d79bc57cf4df1f9d8f1e
Author: Joe Lowe <joe@pismotec.com>
Date:   Tue Jun 13 11:12:50 2017 -0700

    readdir() with mount point dentry, return mount point INO
    
    This patch fixes a minor compatibility issue w/ cygwin mount point handling in
    readdir(), compared to equivalent behavior of Linux and MacOS. dentry.d_ino
    should indicate the INO of the mount point itself, not the target volume root
    folder.
    
    Changed return type from readdir_check_reparse_point to uint8_t, to avoid
    unnecessarily being implicitly cast to and from a signed int.
    
    Renamed a related local variable "attr" to "oattr" that was eclipsing a member
    variable with the same name.
    
    Joe L.

Diff:
---
 winsup/cygwin/fhandler_disk_file.cc | 33 ++++++++++-----------------------
 1 file changed, 10 insertions(+), 23 deletions(-)

diff --git a/winsup/cygwin/fhandler_disk_file.cc b/winsup/cygwin/fhandler_disk_file.cc
index bf5f988..f360304 100644
--- a/winsup/cygwin/fhandler_disk_file.cc
+++ b/winsup/cygwin/fhandler_disk_file.cc
@@ -178,10 +178,10 @@ path_conv::isgood_inode (ino_t ino) const
    are directory mount points, which are treated as symlinks.
    IO_REPARSE_TAG_SYMLINK types are always symlinks.  We don't know
    anything about other reparse points, so they are treated as unknown.  */
-static inline int
+static inline uint8_t
 readdir_check_reparse_point (POBJECT_ATTRIBUTES attr)
 {
-  DWORD ret = DT_UNKNOWN;
+  uint8_t ret = DT_UNKNOWN;
   IO_STATUS_BLOCK io;
   HANDLE reph;
   UNICODE_STRING subst;
@@ -2016,32 +2016,19 @@ fhandler_disk_file::readdir_helper (DIR *dir, dirent *de, DWORD w32_err,
 	de->d_type = DT_REG;
     }
 
-  /* Check for directory reparse point.  These are potential volume mount
-     points which have another inode than the underlying directory. */
+  /* Check for directory reparse point. These may be treated as a posix
+     symlink, or as mount point, so need to figure out whether to return
+     a directory or link type. In all cases, returning the INO of the
+     reparse point (not of the target) matches behavior of posix systems.
+     */
   if ((attr & (FILE_ATTRIBUTE_DIRECTORY | FILE_ATTRIBUTE_REPARSE_POINT))
       == (FILE_ATTRIBUTE_DIRECTORY | FILE_ATTRIBUTE_REPARSE_POINT))
     {
-      HANDLE reph;
-      OBJECT_ATTRIBUTES attr;
-      IO_STATUS_BLOCK io;
+      OBJECT_ATTRIBUTES oattr;
 
-      InitializeObjectAttributes (&attr, fname, pc.objcaseinsensitive (),
+      InitializeObjectAttributes (&oattr, fname, pc.objcaseinsensitive (),
 				  get_handle (), NULL);
-      de->d_type = readdir_check_reparse_point (&attr);
-      if (de->d_type == DT_DIR)
-	{
-	  /* Volume mountpoints are treated as directories.  We have to fix
-	     the inode number, otherwise we have the inode number of the
-	     mount point, rather than the inode number of the toplevel
-	     directory of the mounted drive. */
-	  if (NT_SUCCESS (NtOpenFile (&reph, READ_CONTROL, &attr, &io,
-				      FILE_SHARE_VALID_FLAGS,
-				      FILE_OPEN_FOR_BACKUP_INTENT)))
-	    {
-	      de->d_ino = pc.get_ino_by_handle (reph);
-	      NtClose (reph);
-	    }
-	}
+      de->d_type = readdir_check_reparse_point (&oattr);
     }
 
   /* Check for Windows shortcut. If it's a Cygwin or U/WIN symlink, drop the


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]