* 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.
This commit is contained in:
		| @@ -1,3 +1,17 @@ | ||||
| 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 | ||||
|   | ||||
| @@ -337,11 +337,24 @@ 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). */ | ||||
|  | ||||
|   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, | ||||
|   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)) | ||||
|     { | ||||
| @@ -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, | ||||
| 		       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, | ||||
| 		   fbi.FileAttributes); | ||||
| 		       fi.fbi.FileAttributes); | ||||
| } | ||||
|  | ||||
| int __stdcall | ||||
|   | ||||
| @@ -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 | ||||
|  | ||||
|   | ||||
| @@ -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) | ||||
|   | ||||
| @@ -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; } | ||||
|   | ||||
| @@ -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; | ||||
|   | ||||
| @@ -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) | ||||
|   | ||||
		Reference in New Issue
	
	Block a user