OSDN Git Service

* globals.cc (ro_u_nwfs): New R/O unicode string.
authorcorinna <corinna>
Tue, 12 Jan 2010 14:47:45 +0000 (14:47 +0000)
committercorinna <corinna>
Tue, 12 Jan 2010 14:47:45 +0000 (14:47 +0000)
* mount.cc (fs_info::update): Check for NWFS filesystem.  Set
has_buggy_basic_info, if so.  Add comment to explain why.
(fillout_mntent): Add "nwfs" string to fs_names array.
* mount.h (enum fs_info_type): Add nwfs.
(class fs_info): Add has_buggy_basic_info status flag.  Add accessors
for has_buggy_basic_info and is_nwfs.
* fhandler_disk_file.cc (fhandler_base::fstat_by_handle): Accommodate
filesystems with broken FileBasicInformation handling.
* path.cc (symlink_info::check): Ditto.
* path.h (path_conv::has_buggy_basic_info): Add method.

winsup/cygwin/ChangeLog
winsup/cygwin/fhandler_disk_file.cc
winsup/cygwin/globals.cc
winsup/cygwin/mount.cc
winsup/cygwin/mount.h
winsup/cygwin/path.cc
winsup/cygwin/path.h

index 724eb44..02a0659 100644 (file)
@@ -1,5 +1,19 @@
 2010-01-12  Corinna Vinschen  <corinna@vinschen.de>
 
+       * globals.cc (ro_u_nwfs): New R/O unicode string.
+       * mount.cc (fs_info::update): Check for NWFS filesystem.  Set
+       has_buggy_basic_info, if so.  Add comment to explain why.
+       (fillout_mntent): Add "nwfs" string to fs_names array.
+       * mount.h (enum fs_info_type): Add nwfs.
+       (class fs_info): Add has_buggy_basic_info status flag.  Add accessors
+       for has_buggy_basic_info and is_nwfs.
+       * fhandler_disk_file.cc (fhandler_base::fstat_by_handle): Accommodate
+       filesystems with broken FileBasicInformation handling.
+       * path.cc (symlink_info::check): Ditto.
+       * path.h (path_conv::has_buggy_basic_info): Add method.
+
+2010-01-12  Corinna Vinschen  <corinna@vinschen.de>
+
        * dtable.cc (build_fh_name_worker): Remove.  Move all functionality
        back into build_fh_name.
        (build_fh_name): Drop unused HANDLE parameter.  Drop call to pc.fillin.
index 797f420..8be74ad 100644 (file)
@@ -337,12 +337,25 @@ fhandler_base::fstat_by_handle (struct __stat64 *buf)
      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_BASIC_INFORMATION fbi;
+
+  union {
+    FILE_BASIC_INFORMATION fbi;
+    FILE_NETWORK_OPEN_INFORMATION fnoi;
+  } fi;
   FILE_STANDARD_INFORMATION fsi;
   FILE_INTERNAL_INFORMATION fii;
 
-  status = NtQueryInformationFile (get_handle (), &io, &fbi, sizeof fbi,
-                                  FileBasicInformation);
+  if (pc.has_buggy_basic_info ())
+    {
+      status = NtQueryInformationFile (get_handle (), &io, &fi, sizeof fi,
+                                      FileNetworkOpenInformation);
+      /* The timestamps are in the same relative memory location, only
+        the DOS attributes have to be moved. */
+      fi.fbi.FileAttributes = fi.fnoi.FileAttributes;
+    }
+  else
+    status = NtQueryInformationFile (get_handle (), &io, &fi.fbi, sizeof fi.fbi,
+                                    FileBasicInformation);
   if (!NT_SUCCESS (status))
     {
       debug_printf ("%p = NtQueryInformationFile(%S, FileBasicInformation)",
@@ -369,20 +382,20 @@ fhandler_base::fstat_by_handle (struct __stat64 *buf)
      support a change timestamp.  In that case use the LastWriteTime
      entry, as in other calls to fstat_helper. */
   if (pc.is_rep_symlink ())
-    fbi.FileAttributes &= ~FILE_ATTRIBUTE_DIRECTORY;
-  pc.file_attributes (fbi.FileAttributes);
+    fi.fbi.FileAttributes &= ~FILE_ATTRIBUTE_DIRECTORY;
+  pc.file_attributes (fi.fbi.FileAttributes);
   return fstat_helper (buf,
-                  fbi.ChangeTime.QuadPart ? &fbi.ChangeTime
-                                          : &fbi.LastWriteTime,
-                  &fbi.LastAccessTime,
-                  &fbi.LastWriteTime,
-                  &fbi.CreationTime,
-                  get_dev (),
-                  fsi.EndOfFile.QuadPart,
-                  fsi.AllocationSize.QuadPart,
-                  fii.FileId.QuadPart,
-                  fsi.NumberOfLinks,
-                  fbi.FileAttributes);
+                      fi.fbi.ChangeTime.QuadPart ? &fi.fbi.ChangeTime
+                                                 : &fi.fbi.LastWriteTime,
+                      &fi.fbi.LastAccessTime,
+                      &fi.fbi.LastWriteTime,
+                      &fi.fbi.CreationTime,
+                      get_dev (),
+                      fsi.EndOfFile.QuadPart,
+                      fsi.AllocationSize.QuadPart,
+                      fii.FileId.QuadPart,
+                      fsi.NumberOfLinks,
+                      fi.fbi.FileAttributes);
 }
 
 int __stdcall
index 9554ac8..5934a72 100644 (file)
@@ -1,7 +1,7 @@
 /* globals.cc - Define global variables here.
 
    Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
-   2006, 2007, 2008, 2009 Red Hat, Inc.
+   2006, 2007, 2008, 2009, 2010 Red Hat, Inc.
 
 This file is part of Cygwin.
 
@@ -106,6 +106,7 @@ UNICODE_STRING _RDATA ro_u_ntfs = _ROU (L"NTFS");
 UNICODE_STRING _RDATA ro_u_sunwnfs = _ROU (L"SUNWNFS");
 UNICODE_STRING _RDATA ro_u_udf = _ROU (L"UDF");
 UNICODE_STRING _RDATA ro_u_unixfs = _ROU (L"UNIXFS");
+UNICODE_STRING _RDATA ro_u_nwfs = _ROU (L"NWFS");
 UNICODE_STRING _RDATA ro_u_volume = _ROU (L"\\??\\Volume{");
 #undef _ROU
 
index b99a9b8..63507e7 100644 (file)
@@ -1,7 +1,7 @@
 /* mount.cc: mount handling.
 
    Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
-   2006, 2007, 2008, 2009 Red Hat, Inc.
+   2006, 2007, 2008, 2009, 2010 Red Hat, Inc.
 
 This file is part of Cygwin.
 
@@ -289,6 +289,7 @@ fs_info::update (PUNICODE_STRING upath, HANDLE in_vol)
       && !is_ntfs (RtlEqualUnicodeString (&fsname, &ro_u_ntfs, FALSE))
       && !is_fat (RtlEqualUnicodePathPrefix (&fsname, &ro_u_fat, TRUE))
       && !is_csc_cache (RtlEqualUnicodeString (&fsname, &ro_u_csc, FALSE))
+      && !is_nwfs (RtlEqualUnicodeString (&fsname, &ro_u_nwfs, FALSE))
       && is_cdrom (ffdi.DeviceType == FILE_DEVICE_CD_ROM))
     is_udf (RtlEqualUnicodeString (&fsname, &ro_u_udf, FALSE));
   if (!got_fs ())
@@ -300,8 +301,14 @@ fs_info::update (PUNICODE_STRING upath, HANDLE in_vol)
       strlwr (fsn);
     }
   has_acls (flags () & FS_PERSISTENT_ACLS);
-  /* Netapp inodes numbers are fly-by-night. */
+  /* Netapp inode numbers are fly-by-night. */
   hasgood_inode ((has_acls () && !is_netapp ()) || is_nfs ());
+  /* NWFS is known to have a broken FileBasicInformation info class.  It
+     can't be used to fetch information, only to set information.  Therefore,
+     for NWFS we have to fallback to the FileNetworkOpenInformation info
+     class.  Unfortunately we can't use FileNetworkOpenInformation all the
+     time since that fails on other filesystems like NFS. */
+  has_buggy_basic_info (is_nwfs ());
   /* Case sensitivity is supported if FILE_CASE_SENSITIVE_SEARCH is set,
      except on Samba which handles Windows clients case insensitive.
 
@@ -1443,7 +1450,8 @@ fillout_mntent (const char *native_path, const char *posix_path, unsigned flags)
     "sunwnfs",
     "unixfs",
     "mvfs",
-    "cifs"
+    "cifs",
+    "nwfs"
   };
 
   if (mntinfo.what_fs () > 0 && mntinfo.what_fs () < max_fs_type)
index 39d2756..95a158a 100644 (file)
@@ -1,7 +1,7 @@
 /* mount.h: mount definitions.
 
    Copyright 1996, 1997, 1998, 2000, 2001, 2002, 2003, 2004, 2005,
-   2006, 2007, 2008, 2009 Red Hat, Inc.
+   2006, 2007, 2008, 2009, 2010 Red Hat, Inc.
 
 This file is part of Cygwin.
 
@@ -27,6 +27,7 @@ enum fs_info_type
   unixfs,
   mvfs,
   cifs,
+  nwfs,
   /* Always last. */
   max_fs_type
 };
@@ -49,6 +50,7 @@ class fs_info
     unsigned caseinsensitive           : 1;
     unsigned has_buggy_open            : 1;
     unsigned has_buggy_fileid_dirinfo  : 1;
+    unsigned has_buggy_basic_info      : 1;
   } status;
   ULONG sernum;                        /* Volume Serial Number */
   char fsn[80];                        /* Windows filesystem name */
@@ -72,6 +74,7 @@ class fs_info
   IMPLEMENT_STATUS_FLAG (bool, caseinsensitive)
   IMPLEMENT_STATUS_FLAG (bool, has_buggy_open)
   IMPLEMENT_STATUS_FLAG (bool, has_buggy_fileid_dirinfo)
+  IMPLEMENT_STATUS_FLAG (bool, has_buggy_basic_info)
   IMPLEMENT_FS_FLAG (is_fat, fat)
   IMPLEMENT_FS_FLAG (is_ntfs, ntfs)
   IMPLEMENT_FS_FLAG (is_samba, samba)
@@ -84,6 +87,7 @@ class fs_info
   IMPLEMENT_FS_FLAG (is_unixfs, unixfs)
   IMPLEMENT_FS_FLAG (is_mvfs, mvfs)
   IMPLEMENT_FS_FLAG (is_cifs, cifs)
+  IMPLEMENT_FS_FLAG (is_nwfs, nwfs)
   fs_info_type what_fs () const { return status.fs_type; }
 
   ULONG serial_number () const { return sernum; }
index 47274b4..8ad8d2e 100644 (file)
@@ -2260,9 +2260,16 @@ symlink_info::check (char *path, const suffix_info *suffixes, unsigned opt,
                }
            }
        }
+
+      /* Check file system while we're having the file open anyway.
+        This speeds up path_conv noticably (~10%). */
+      if (!fs_update_called)
+       fs.update (&upath, h);
+
       if (NT_SUCCESS (status)
-         && NT_SUCCESS (status
-                        = NtQueryInformationFile (h, &io, &fbi, sizeof fbi,
+         && NT_SUCCESS (status = fs.has_buggy_basic_info ()
+                        ? NtQueryAttributesFile (&attr, &fbi)
+                        : NtQueryInformationFile (h, &io, &fbi, sizeof fbi,
                                                   FileBasicInformation)))
        fileattr = fbi.FileAttributes;
       else
@@ -2359,11 +2366,6 @@ symlink_info::check (char *path, const suffix_info *suffixes, unsigned opt,
          continue;
        }
 
-      /* Check file system while we're having the file open anyway.
-        This speeds up path_conv noticably (~10%). */
-      if (!fs_update_called)
-       fs.update (&upath, h);
-
       ext_tacked_on = !!*ext_here;
 
       res = -1;
index b310dc7..18eb494 100644 (file)
@@ -111,6 +111,7 @@ class path_conv
   int has_symlinks () const {return path_flags & PATH_HAS_SYMLINKS;}
   int has_buggy_open () const {return fs.has_buggy_open ();}
   int has_buggy_fileid_dirinfo () const {return fs.has_buggy_fileid_dirinfo ();}
+  int has_buggy_basic_info () const {return fs.has_buggy_basic_info ();}
   int binmode () const
   {
     if (path_flags & PATH_BINARY)