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] Fetch and store FileAllInformation rather than FileNetworkOpenInformation


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

commit eed35efbe67e3b0588d5afbdf7926eb9f52e5766
Author: Corinna Vinschen <corinna@vinschen.de>
Date:   Thu Dec 10 00:02:34 2015 +0100

    Fetch and store FileAllInformation rather than FileNetworkOpenInformation
    
            * path.h (class path_conv_handle): Use FILE_ALL_INFORMATION instead of
            FILE_NETWORK_OPEN_INFORMATION.  Use definitions from ntdll.h since it's
            included anyway.
            (path_conv_handle::fai): Change name from fnoi.
            (path_conv::fai): Ditto.
            (file_get_fai): Change name from file_get_fnoi.  Drop second parameter.
            * path.cc (file_get_fai): Ditto.  Fetch FileAllInformation rather than
            FileNetworkOpenInformation.  Convert STATUS_BUFFER_OVERFLOW to
            STATUS_SUCCESS.  Remove workaround to fetch FileBasicInformation and
            FileStandardInformation on filesystems with broken
            FileNetworkOpenInformation handling.
            (symlink_info::check): Accommodate above changes.  In case of using
            the NtQueryDirectoryFile fallback, fetch FileIdBothDirectoryInformation
            to get inode number as well.
            * fhandler_disk_file.cc (fhandler_base::fstat_by_handle): Drop outdated
            comment.  Accommodate change to using FileAllInformation.  Drop
            extra function calls to fetch NumberOfLinks and IndexNumber.  Set ino
            directly from IndexNumber stored in pc.fai().  Drop second argument
            from call to fstat_helper.
            (fhandler_base::fstat_by_name): Drop second argument from call to
            fstat_helper.
            (fhandler_base::fstat_helper): Drop second parameter.  Accommodate
            the fact that we access a FILE_ALL_INFORMATION structure now.
            (fhandler_base::open_fs): Set ino directly from IndexNumber stored in
            pc.fai().
            * fhandler.h (fhandler_base::fstat_helper): Fix declaration accrdingly.
    
    Signed-off-by: Corinna Vinschen <corinna@vinschen.de>

Diff:
---
 winsup/cygwin/ChangeLog             | 29 +++++++++++++
 winsup/cygwin/fhandler.h            |  3 +-
 winsup/cygwin/fhandler_disk_file.cc | 81 ++++++++++++-------------------------
 winsup/cygwin/path.cc               | 68 ++++++++++---------------------
 winsup/cygwin/path.h                | 21 +++-------
 5 files changed, 83 insertions(+), 119 deletions(-)

diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog
index 079aa89..3c9804b 100644
--- a/winsup/cygwin/ChangeLog
+++ b/winsup/cygwin/ChangeLog
@@ -1,5 +1,34 @@
 2015-12-10  Corinna Vinschen  <corinna@vinschen.de>
 
+	* path.h (class path_conv_handle): Use FILE_ALL_INFORMATION instead of
+	FILE_NETWORK_OPEN_INFORMATION.  Use definitions from ntdll.h since it's
+	included anyway.
+	(path_conv_handle::fai): Change name from fnoi.
+	(path_conv::fai): Ditto.
+	(file_get_fai): Change name from file_get_fnoi.  Drop second parameter.
+	* path.cc (file_get_fai): Ditto.  Fetch FileAllInformation rather than
+	FileNetworkOpenInformation.  Convert STATUS_BUFFER_OVERFLOW to
+	STATUS_SUCCESS.  Remove workaround to fetch FileBasicInformation and
+	FileStandardInformation on filesystems with broken
+	FileNetworkOpenInformation handling.
+	(symlink_info::check): Accommodate above changes.  In case of using
+	the NtQueryDirectoryFile fallback, fetch FileIdBothDirectoryInformation
+	to get inode number as well.
+	* fhandler_disk_file.cc (fhandler_base::fstat_by_handle): Drop outdated
+	comment.  Accommodate change to using FileAllInformation.  Drop
+	extra function calls to fetch NumberOfLinks and IndexNumber.  Set ino
+	directly from IndexNumber stored in pc.fai().  Drop second argument
+	from call to fstat_helper.
+	(fhandler_base::fstat_by_name): Drop second argument from call to
+	fstat_helper.
+	(fhandler_base::fstat_helper): Drop second parameter.  Accommodate
+	the fact that we access a FILE_ALL_INFORMATION structure now.
+	(fhandler_base::open_fs): Set ino directly from IndexNumber stored in
+	pc.fai().
+	* fhandler.h (fhandler_base::fstat_helper): Fix declaration accrdingly.
+
+2015-12-10  Corinna Vinschen  <corinna@vinschen.de>
+
 	* fhandler_disk_file.cc (path_conv::ndisk_links): Drop unused method.
 	(fhandler_base::fstat_helper): Drop unused call to ndisk_links.
 
diff --git a/winsup/cygwin/fhandler.h b/winsup/cygwin/fhandler.h
index 43e56ef..adb8441 100644
--- a/winsup/cygwin/fhandler.h
+++ b/winsup/cygwin/fhandler.h
@@ -341,8 +341,7 @@ class fhandler_base
   void __reg2 stat_fixup (struct stat *buf);
   int __reg2 fstat_fs (struct stat *buf);
 private:
-  int __reg3 fstat_helper (struct stat *buf,
-			      DWORD nNumberOfLinks);
+  int __reg2 fstat_helper (struct stat *buf);
   int __reg2 fstat_by_nfs_ea (struct stat *buf);
   int __reg2 fstat_by_handle (struct stat *buf);
   int __reg2 fstat_by_name (struct stat *buf);
diff --git a/winsup/cygwin/fhandler_disk_file.cc b/winsup/cygwin/fhandler_disk_file.cc
index e7e22a2..fe9dd03 100644
--- a/winsup/cygwin/fhandler_disk_file.cc
+++ b/winsup/cygwin/fhandler_disk_file.cc
@@ -319,59 +319,25 @@ fhandler_base::fstat_by_nfs_ea (struct stat *buf)
 int __reg2
 fhandler_base::fstat_by_handle (struct stat *buf)
 {
-  /* Don't use FileAllInformation info class.  It returns a pathname rather
-     than a filename, so it needs a really big buffer for no good reason
-     since we don't need the name anyway.  So we just call the three info
-     classes necessary to get all information required by stat(2). */
-  FILE_STANDARD_INFORMATION fsi;
-  FILE_INTERNAL_INFORMATION fii;
-
   HANDLE h = get_stat_handle ();
   NTSTATUS status = 0;
-  IO_STATUS_BLOCK io;
 
   /* If the file has been opened for other purposes than stat, we can't rely
-     on the information stored in pc.fnoi.  So we overwrite them here. */
+     on the information stored in pc.fai.  So we overwrite them here. */
   if (get_io_handle ())
     {
-      status = file_get_fnoi (h, pc.has_broken_fnoi (), pc.fnoi ());
+      status = file_get_fai (h, pc.fai ());
       if (!NT_SUCCESS (status))
        {
-	 debug_printf ("%y = NtQueryInformationFile(%S, "
-		       "FileNetworkOpenInformation)",
+	 debug_printf ("%y = NtQueryInformationFile(%S, FileAllInformation)",
 		       status, pc.get_nt_native_path ());
 	 return -1;
        }
     }
-  if (!pc.hasgood_inode ())
-    fsi.NumberOfLinks = 1;
-  else
-    {
-      status = NtQueryInformationFile (h, &io, &fsi, sizeof fsi,
-				       FileStandardInformation);
-      if (!NT_SUCCESS (status))
-	{
-	  debug_printf ("%y = NtQueryInformationFile(%S, "
-			"FileStandardInformation)",
-			status, pc.get_nt_native_path ());
-	  return -1;
-	}
-      if (!ino)
-	{
-	  status = NtQueryInformationFile (h, &io, &fii, sizeof fii,
-					   FileInternalInformation);
-	  if (!NT_SUCCESS (status))
-	    {
-	      debug_printf ("%y = NtQueryInformationFile(%S, "
-			    "FileInternalInformation)",
-			    status, pc.get_nt_native_path ());
-	      return -1;
-	    }
-	  else if (pc.isgood_inode (fii.IndexNumber.QuadPart))
-	    ino = fii.IndexNumber.QuadPart;
-	}
-    }
-  return fstat_helper (buf, fsi.NumberOfLinks);
+  if (pc.hasgood_inode ()
+      && pc.isgood_inode (pc.fai ()->InternalInformation.IndexNumber.QuadPart))
+    ino = pc.fai ()->InternalInformation.IndexNumber.QuadPart;
+  return fstat_helper (buf);
 }
 
 int __reg2
@@ -415,7 +381,7 @@ fhandler_base::fstat_by_name (struct stat *buf)
 	    ino = fdi_buf.fdi.FileId.QuadPart;
 	}
     }
-  return fstat_helper (buf, 1);
+  return fstat_helper (buf);
 }
 
 int __reg2
@@ -463,22 +429,23 @@ fhandler_base::fstat_fs (struct stat *buf)
 }
 
 int __reg3
-fhandler_base::fstat_helper (struct stat *buf, DWORD nNumberOfLinks)
+fhandler_base::fstat_helper (struct stat *buf)
 {
   IO_STATUS_BLOCK st;
   FILE_COMPRESSION_INFORMATION fci;
   HANDLE h = get_stat_handle ();
-  PFILE_NETWORK_OPEN_INFORMATION pfnoi = pc.fnoi ();
+  PFILE_ALL_INFORMATION pfai = pc.fai ();
   ULONG attributes = pc.file_attributes ();
 
-  to_timestruc_t (&pfnoi->LastAccessTime, &buf->st_atim);
-  to_timestruc_t (&pfnoi->LastWriteTime, &buf->st_mtim);
+  to_timestruc_t (&pfai->BasicInformation.LastAccessTime, &buf->st_atim);
+  to_timestruc_t (&pfai->BasicInformation.LastWriteTime, &buf->st_mtim);
   /* If the ChangeTime is 0, the underlying FS doesn't support this timestamp
      (FAT for instance).  If so, it's faked using LastWriteTime. */
-  to_timestruc_t (pfnoi->ChangeTime.QuadPart ? &pfnoi->ChangeTime
-					     : &pfnoi->LastWriteTime,
+  to_timestruc_t (pfai->BasicInformation.ChangeTime.QuadPart
+		  ? &pfai->BasicInformation.ChangeTime
+		  : &pfai->BasicInformation.LastWriteTime,
 		  &buf->st_ctim);
-  to_timestruc_t (&pfnoi->CreationTime, &buf->st_birthtim);
+  to_timestruc_t (&pfai->BasicInformation.CreationTime, &buf->st_birthtim);
   buf->st_dev = get_dev ();
   /* CV 2011-01-13: Observations on the Cygwin mailing list point to an
      interesting behaviour in some Windows versions.  Apparently the size of
@@ -487,11 +454,13 @@ fhandler_base::fstat_helper (struct stat *buf, DWORD nNumberOfLinks)
      0 in the first call and size > 0 in the second call.  This in turn can
      affect applications like newer tar.
      FIXME: Is the allocation size affected as well? */
-  buf->st_size = pc.isdir () ? 0 : (off_t) pfnoi->EndOfFile.QuadPart;
+  buf->st_size = pc.isdir ()
+		 ? 0
+		 : (off_t) pfai->StandardInformation.EndOfFile.QuadPart;
   /* The number of links to a directory includes the number of subdirectories
      in the directory, since all those subdirectories point to it.  However,
      this is painfully slow, so we do without it. */
-  buf->st_nlink = nNumberOfLinks;
+  buf->st_nlink = pc.fai()->StandardInformation.NumberOfLinks;
 
   /* Enforce namehash as inode number on untrusted file systems. */
   if (ino && pc.isgood_inode (ino))
@@ -501,11 +470,11 @@ fhandler_base::fstat_helper (struct stat *buf, DWORD nNumberOfLinks)
 
   buf->st_blksize = PREFERRED_IO_BLKSIZE;
 
-  if (pfnoi->AllocationSize.QuadPart >= 0LL)
+  if (pfai->StandardInformation.AllocationSize.QuadPart >= 0LL)
     /* A successful NtQueryInformationFile returns the allocation size
        correctly for compressed and sparse files as well. */
-    buf->st_blocks = (pfnoi->AllocationSize.QuadPart + S_BLKSIZE - 1)
-		     / S_BLKSIZE;
+    buf->st_blocks = (pfai->StandardInformation.AllocationSize.QuadPart
+		      + S_BLKSIZE - 1) / S_BLKSIZE;
   else if (::has_attribute (attributes, FILE_ATTRIBUTE_COMPRESSED
 					| FILE_ATTRIBUTE_SPARSE_FILE)
 	   && h && !is_fs_special ()
@@ -1509,7 +1478,9 @@ fhandler_base::open_fs (int flags, mode_t mode)
       return 0;
     }
 
-  ino = pc.get_ino_by_handle (get_handle ());
+  if (pc.hasgood_inode ()
+      && pc.isgood_inode (pc.fai ()->InternalInformation.IndexNumber.QuadPart))
+    ino = pc.fai ()->InternalInformation.IndexNumber.QuadPart;
 
 out:
   syscall_printf ("%d = fhandler_disk_file::open(%S, %y)", res,
diff --git a/winsup/cygwin/path.cc b/winsup/cygwin/path.cc
index d86cf99..e49f180 100644
--- a/winsup/cygwin/path.cc
+++ b/winsup/cygwin/path.cc
@@ -1300,44 +1300,18 @@ path_conv::is_binary ()
 	 && (bin == SCS_32BIT_BINARY || bin == SCS_64BIT_BINARY);
 }
 
-/* Helper function to fill the fnoi datastructure for a file. */
+/* Helper function to fill the fai datastructure for a file. */
 NTSTATUS
-file_get_fnoi (HANDLE h, bool skip_network_open_inf,
-	       PFILE_NETWORK_OPEN_INFORMATION pfnoi)
+file_get_fai (HANDLE h, PFILE_ALL_INFORMATION pfai)
 {
   NTSTATUS status;
   IO_STATUS_BLOCK io;
 
   /* Some FSes (Netapps) don't implement FileNetworkOpenInformation. */
-  status = skip_network_open_inf ? STATUS_INVALID_PARAMETER
-	   : NtQueryInformationFile (h, &io, pfnoi, sizeof *pfnoi,
-				     FileNetworkOpenInformation);
-  if (status == STATUS_INVALID_PARAMETER)
-    {
-      /* Apart from accessing Netapps, this also occurs when accessing SMB
-	 share root dirs hosted on NT4. */
-      FILE_BASIC_INFORMATION fbi;
-      FILE_STANDARD_INFORMATION fsi;
-
-      status = NtQueryInformationFile (h, &io, &fbi, sizeof fbi,
-				       FileBasicInformation);
-      if (NT_SUCCESS (status))
-	{
-	  memcpy (pfnoi, &fbi, 4 * sizeof (LARGE_INTEGER));
-	  if (NT_SUCCESS (NtQueryInformationFile (h, &io, &fsi,
-					 sizeof fsi,
-					 FileStandardInformation)))
-	    {
-	      pfnoi->EndOfFile.QuadPart = fsi.EndOfFile.QuadPart;
-	      pfnoi->AllocationSize.QuadPart
-		= fsi.AllocationSize.QuadPart;
-	    }
-	  else
-	    pfnoi->EndOfFile.QuadPart
-	      = pfnoi->AllocationSize.QuadPart = 0;
-	  pfnoi->FileAttributes = fbi.FileAttributes;
-	}
-    }
+  status = NtQueryInformationFile (h, &io, pfai, sizeof *pfai,
+				   FileAllInformation);
+  if (status == STATUS_BUFFER_OVERFLOW)
+    status = STATUS_SUCCESS;
   return status;
 }
 
@@ -2833,10 +2807,9 @@ restart:
 	    }
 	  else
 	    {
-	      status = file_get_fnoi (h, fs.has_broken_fnoi (),
-				      conv_hdl.fnoi ());
+	      status = file_get_fai (h, conv_hdl.fai ());
 	      if (NT_SUCCESS (status))
-		fileattr = conv_hdl.fnoi ()->FileAttributes;
+		fileattr = conv_hdl.fai ()->BasicInformation.FileAttributes;
 	    }
 	}
       if (!NT_SUCCESS (status))
@@ -2874,7 +2847,7 @@ restart:
 	      OBJECT_ATTRIBUTES dattr;
 	      HANDLE dir;
 	      struct {
-		FILE_BOTH_DIR_INFORMATION fdi;
+		FILE_ID_BOTH_DIR_INFORMATION fdi;
 		WCHAR dummy_buf[NAME_MAX + 1];
 	      } fdi_buf;
 
@@ -2906,7 +2879,7 @@ restart:
 		{
 		  status = NtQueryDirectoryFile (dir, NULL, NULL, NULL, &io,
 						 &fdi_buf, sizeof fdi_buf,
-						 FileBothDirectoryInformation,
+						 FileIdBothDirectoryInformation,
 						 TRUE, &basename, TRUE);
 		  /* Take the opportunity to check file system while we're
 		     having the handle to the parent dir. */
@@ -2932,18 +2905,20 @@ restart:
 		    }
 		  else
 		    {
-		      PFILE_NETWORK_OPEN_INFORMATION pfnoi = conv_hdl.fnoi ();
+		      PFILE_ALL_INFORMATION pfai = conv_hdl.fai ();
 
 		      fileattr = fdi_buf.fdi.FileAttributes;
-		      memcpy (pfnoi, &fdi_buf.fdi.CreationTime, sizeof *pfnoi);
-		      /* Amazing, but true:  The FILE_NETWORK_OPEN_INFORMATION
-			 structure has the AllocationSize and EndOfFile members
-			 interchanged relative to the directory information
-			 classes. */
-		      pfnoi->AllocationSize.QuadPart
+		      memcpy (&pfai->BasicInformation.CreationTime,
+			      &fdi_buf.fdi.CreationTime,
+			      4 * sizeof (LARGE_INTEGER));
+		      pfai->BasicInformation.FileAttributes = fileattr;
+		      pfai->StandardInformation.AllocationSize.QuadPart
 			= fdi_buf.fdi.AllocationSize.QuadPart;
-		      pfnoi->EndOfFile.QuadPart
+		      pfai->StandardInformation.EndOfFile.QuadPart
 			= fdi_buf.fdi.EndOfFile.QuadPart;
+		      pfai->StandardInformation.NumberOfLinks = 1;
+		      pfai->InternalInformation.IndexNumber.QuadPart
+			= fdi_buf.fdi.FileId.QuadPart;
 		    }
 		}
 	      ext_tacked_on = !!*ext_here;
@@ -2977,7 +2952,8 @@ restart:
 	  if (res > 0)
 	    {
 	      /* A symlink is never a directory. */
-	      conv_hdl.fnoi ()->FileAttributes &= ~FILE_ATTRIBUTE_DIRECTORY;
+	      conv_hdl.fai ()->BasicInformation.FileAttributes
+		&= ~FILE_ATTRIBUTE_DIRECTORY;
 	      break;
 	    }
 	  else
diff --git a/winsup/cygwin/path.h b/winsup/cygwin/path.h
index ab7222e..730f943 100644
--- a/winsup/cygwin/path.h
+++ b/winsup/cygwin/path.h
@@ -91,23 +91,12 @@ enum path_types
 };
 
 class symlink_info;
-struct _FILE_NETWORK_OPEN_INFORMATION;
 
 class path_conv_handle
 {
   HANDLE      hdl;
   union {
-    /* Identical to FILE_NETWORK_OPEN_INFORMATION.  We don't want to pull in
-       ntdll.h here, though. */
-    struct {
-      LARGE_INTEGER CreationTime;
-      LARGE_INTEGER LastAccessTime;
-      LARGE_INTEGER LastWriteTime;
-      LARGE_INTEGER ChangeTime;
-      LARGE_INTEGER AllocationSize;
-      LARGE_INTEGER EndOfFile;
-      ULONG FileAttributes;
-    } _fnoi;
+    FILE_ALL_INFORMATION _fai;
     /* For NFS. */
     fattr3 _fattr3;
   } attribs;
@@ -128,8 +117,8 @@ public:
       hdl = NULL;
   }
   inline HANDLE handle () const { return hdl; }
-  inline struct _FILE_NETWORK_OPEN_INFORMATION *fnoi ()
-  { return (struct _FILE_NETWORK_OPEN_INFORMATION *) &attribs._fnoi; }
+  inline PFILE_ALL_INFORMATION fai ()
+  { return (PFILE_ALL_INFORMATION) &attribs._fai; }
   inline struct fattr3 *nfsattr ()
   { return (struct fattr3 *) &attribs._fattr3; }
 };
@@ -390,7 +379,7 @@ class path_conv
   bool is_binary ();
 
   HANDLE handle () const { return conv_handle.handle (); }
-  struct _FILE_NETWORK_OPEN_INFORMATION *fnoi () { return conv_handle.fnoi (); }
+  PFILE_ALL_INFORMATION fai () { return conv_handle.fai (); }
   struct fattr3 *nfsattr () { return conv_handle.nfsattr (); }
   void reset_conv_handle () { conv_handle.set (NULL); }
   void close_conv_handle () { conv_handle.close (); }
@@ -444,7 +433,7 @@ bool __reg2 has_dot_last_component (const char *dir, bool test_dot_dot);
 int __reg3 path_prefix_p (const char *path1, const char *path2, int len1,
 		   bool caseinsensitive);
 
-NTSTATUS file_get_fnoi (HANDLE, bool, struct _FILE_NETWORK_OPEN_INFORMATION *);
+NTSTATUS file_get_fai (HANDLE, PFILE_ALL_INFORMATION);
 int normalize_win32_path (const char *, char *, char *&);
 int normalize_posix_path (const char *, char *, char *&);
 PUNICODE_STRING __reg3 get_nt_native_path (const char *, UNICODE_STRING&, bool);


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