* 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> | 2010-01-12  Corinna Vinschen  <corinna@vinschen.de> | ||||||
|  |  | ||||||
| 	* dtable.cc (build_fh_name_worker): Remove.  Move all functionality | 	* dtable.cc (build_fh_name_worker): Remove.  Move all functionality | ||||||
|   | |||||||
| @@ -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 |      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 |      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). */ |      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_STANDARD_INFORMATION fsi; | ||||||
|   FILE_INTERNAL_INFORMATION fii; |   FILE_INTERNAL_INFORMATION fii; | ||||||
|  |  | ||||||
|   status = NtQueryInformationFile (get_handle (), &io, &fbi, sizeof fbi, |   if (pc.has_buggy_basic_info ()) | ||||||
| 				   FileBasicInformation); |     { | ||||||
|  |       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)) |   if (!NT_SUCCESS (status)) | ||||||
|     { |     { | ||||||
|       debug_printf ("%p = NtQueryInformationFile(%S, FileBasicInformation)", |       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 |      support a change timestamp.  In that case use the LastWriteTime | ||||||
|      entry, as in other calls to fstat_helper. */ |      entry, as in other calls to fstat_helper. */ | ||||||
|   if (pc.is_rep_symlink ()) |   if (pc.is_rep_symlink ()) | ||||||
|     fbi.FileAttributes &= ~FILE_ATTRIBUTE_DIRECTORY; |     fi.fbi.FileAttributes &= ~FILE_ATTRIBUTE_DIRECTORY; | ||||||
|   pc.file_attributes (fbi.FileAttributes); |   pc.file_attributes (fi.fbi.FileAttributes); | ||||||
|   return fstat_helper (buf, |   return fstat_helper (buf, | ||||||
| 		   fbi.ChangeTime.QuadPart ? &fbi.ChangeTime | 		       fi.fbi.ChangeTime.QuadPart ? &fi.fbi.ChangeTime | ||||||
| 					   : &fbi.LastWriteTime, | 						  : &fi.fbi.LastWriteTime, | ||||||
| 		   &fbi.LastAccessTime, | 		       &fi.fbi.LastAccessTime, | ||||||
| 		   &fbi.LastWriteTime, | 		       &fi.fbi.LastWriteTime, | ||||||
| 		   &fbi.CreationTime, | 		       &fi.fbi.CreationTime, | ||||||
| 		   get_dev (), | 		       get_dev (), | ||||||
| 		   fsi.EndOfFile.QuadPart, | 		       fsi.EndOfFile.QuadPart, | ||||||
| 		   fsi.AllocationSize.QuadPart, | 		       fsi.AllocationSize.QuadPart, | ||||||
| 		   fii.FileId.QuadPart, | 		       fii.FileId.QuadPart, | ||||||
| 		   fsi.NumberOfLinks, | 		       fsi.NumberOfLinks, | ||||||
| 		   fbi.FileAttributes); | 		       fi.fbi.FileAttributes); | ||||||
| } | } | ||||||
|  |  | ||||||
| int __stdcall | int __stdcall | ||||||
|   | |||||||
| @@ -1,7 +1,7 @@ | |||||||
| /* globals.cc - Define global variables here. | /* globals.cc - Define global variables here. | ||||||
|  |  | ||||||
|    Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, |    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. | 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_sunwnfs = _ROU (L"SUNWNFS"); | ||||||
| UNICODE_STRING _RDATA ro_u_udf = _ROU (L"UDF"); | UNICODE_STRING _RDATA ro_u_udf = _ROU (L"UDF"); | ||||||
| UNICODE_STRING _RDATA ro_u_unixfs = _ROU (L"UNIXFS"); | 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{"); | UNICODE_STRING _RDATA ro_u_volume = _ROU (L"\\??\\Volume{"); | ||||||
| #undef _ROU | #undef _ROU | ||||||
|  |  | ||||||
|   | |||||||
| @@ -1,7 +1,7 @@ | |||||||
| /* mount.cc: mount handling. | /* mount.cc: mount handling. | ||||||
|  |  | ||||||
|    Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, |    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. | 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_ntfs (RtlEqualUnicodeString (&fsname, &ro_u_ntfs, FALSE)) | ||||||
|       && !is_fat (RtlEqualUnicodePathPrefix (&fsname, &ro_u_fat, TRUE)) |       && !is_fat (RtlEqualUnicodePathPrefix (&fsname, &ro_u_fat, TRUE)) | ||||||
|       && !is_csc_cache (RtlEqualUnicodeString (&fsname, &ro_u_csc, FALSE)) |       && !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_cdrom (ffdi.DeviceType == FILE_DEVICE_CD_ROM)) | ||||||
|     is_udf (RtlEqualUnicodeString (&fsname, &ro_u_udf, FALSE)); |     is_udf (RtlEqualUnicodeString (&fsname, &ro_u_udf, FALSE)); | ||||||
|   if (!got_fs ()) |   if (!got_fs ()) | ||||||
| @@ -300,8 +301,14 @@ fs_info::update (PUNICODE_STRING upath, HANDLE in_vol) | |||||||
|       strlwr (fsn); |       strlwr (fsn); | ||||||
|     } |     } | ||||||
|   has_acls (flags () & FS_PERSISTENT_ACLS); |   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 ()); |   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, |   /* Case sensitivity is supported if FILE_CASE_SENSITIVE_SEARCH is set, | ||||||
|      except on Samba which handles Windows clients case insensitive. |      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", |     "sunwnfs", | ||||||
|     "unixfs", |     "unixfs", | ||||||
|     "mvfs", |     "mvfs", | ||||||
|     "cifs" |     "cifs", | ||||||
|  |     "nwfs" | ||||||
|   }; |   }; | ||||||
|  |  | ||||||
|   if (mntinfo.what_fs () > 0 && mntinfo.what_fs () < max_fs_type) |   if (mntinfo.what_fs () > 0 && mntinfo.what_fs () < max_fs_type) | ||||||
|   | |||||||
| @@ -1,7 +1,7 @@ | |||||||
| /* mount.h: mount definitions. | /* mount.h: mount definitions. | ||||||
|  |  | ||||||
|    Copyright 1996, 1997, 1998, 2000, 2001, 2002, 2003, 2004, 2005, |    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. | This file is part of Cygwin. | ||||||
|  |  | ||||||
| @@ -27,6 +27,7 @@ enum fs_info_type | |||||||
|   unixfs, |   unixfs, | ||||||
|   mvfs, |   mvfs, | ||||||
|   cifs, |   cifs, | ||||||
|  |   nwfs, | ||||||
|   /* Always last. */ |   /* Always last. */ | ||||||
|   max_fs_type |   max_fs_type | ||||||
| }; | }; | ||||||
| @@ -49,6 +50,7 @@ class fs_info | |||||||
|     unsigned caseinsensitive		: 1; |     unsigned caseinsensitive		: 1; | ||||||
|     unsigned has_buggy_open		: 1; |     unsigned has_buggy_open		: 1; | ||||||
|     unsigned has_buggy_fileid_dirinfo	: 1; |     unsigned has_buggy_fileid_dirinfo	: 1; | ||||||
|  |     unsigned has_buggy_basic_info	: 1; | ||||||
|   } status; |   } status; | ||||||
|   ULONG sernum;			/* Volume Serial Number */ |   ULONG sernum;			/* Volume Serial Number */ | ||||||
|   char fsn[80];			/* Windows filesystem name */ |   char fsn[80];			/* Windows filesystem name */ | ||||||
| @@ -72,6 +74,7 @@ class fs_info | |||||||
|   IMPLEMENT_STATUS_FLAG (bool, caseinsensitive) |   IMPLEMENT_STATUS_FLAG (bool, caseinsensitive) | ||||||
|   IMPLEMENT_STATUS_FLAG (bool, has_buggy_open) |   IMPLEMENT_STATUS_FLAG (bool, has_buggy_open) | ||||||
|   IMPLEMENT_STATUS_FLAG (bool, has_buggy_fileid_dirinfo) |   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_fat, fat) | ||||||
|   IMPLEMENT_FS_FLAG (is_ntfs, ntfs) |   IMPLEMENT_FS_FLAG (is_ntfs, ntfs) | ||||||
|   IMPLEMENT_FS_FLAG (is_samba, samba) |   IMPLEMENT_FS_FLAG (is_samba, samba) | ||||||
| @@ -84,6 +87,7 @@ class fs_info | |||||||
|   IMPLEMENT_FS_FLAG (is_unixfs, unixfs) |   IMPLEMENT_FS_FLAG (is_unixfs, unixfs) | ||||||
|   IMPLEMENT_FS_FLAG (is_mvfs, mvfs) |   IMPLEMENT_FS_FLAG (is_mvfs, mvfs) | ||||||
|   IMPLEMENT_FS_FLAG (is_cifs, cifs) |   IMPLEMENT_FS_FLAG (is_cifs, cifs) | ||||||
|  |   IMPLEMENT_FS_FLAG (is_nwfs, nwfs) | ||||||
|   fs_info_type what_fs () const { return status.fs_type; } |   fs_info_type what_fs () const { return status.fs_type; } | ||||||
|  |  | ||||||
|   ULONG serial_number () const { return sernum; } |   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) |       if (NT_SUCCESS (status) | ||||||
| 	  && NT_SUCCESS (status | 	  && NT_SUCCESS (status = fs.has_buggy_basic_info () | ||||||
| 			 = NtQueryInformationFile (h, &io, &fbi, sizeof fbi, | 			 ? NtQueryAttributesFile (&attr, &fbi) | ||||||
|  | 			 : NtQueryInformationFile (h, &io, &fbi, sizeof fbi, | ||||||
| 						   FileBasicInformation))) | 						   FileBasicInformation))) | ||||||
| 	fileattr = fbi.FileAttributes; | 	fileattr = fbi.FileAttributes; | ||||||
|       else |       else | ||||||
| @@ -2359,11 +2366,6 @@ symlink_info::check (char *path, const suffix_info *suffixes, unsigned opt, | |||||||
| 	  continue; | 	  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; |       ext_tacked_on = !!*ext_here; | ||||||
|  |  | ||||||
|       res = -1; |       res = -1; | ||||||
|   | |||||||
| @@ -111,6 +111,7 @@ class path_conv | |||||||
|   int has_symlinks () const {return path_flags & PATH_HAS_SYMLINKS;} |   int has_symlinks () const {return path_flags & PATH_HAS_SYMLINKS;} | ||||||
|   int has_buggy_open () const {return fs.has_buggy_open ();} |   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_fileid_dirinfo () const {return fs.has_buggy_fileid_dirinfo ();} | ||||||
|  |   int has_buggy_basic_info () const {return fs.has_buggy_basic_info ();} | ||||||
|   int binmode () const |   int binmode () const | ||||||
|   { |   { | ||||||
|     if (path_flags & PATH_BINARY) |     if (path_flags & PATH_BINARY) | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user