* fhandler_disk_file.cc (fhandler_disk_file::readdir): Fix inode number
evaluation for faked "." entry. * mount.cc (fs_info::update): Move setting of is_cdrom after checking for caseinsensitivity. Recognize UDF in is_cdrom case and set caseinsensitive flag according to UDF brokenness determined by OS. Add comment to explain why. * mount.h (class fs_info): Add is_udf status flag. * path.cc (symlink_info::check): Add workaround for UDF bug in terms of casesensitivity on certain OSes. * wincap.h (wincaps::has_broken_udf): New element. (wincaps::has_broken_udf): New element
This commit is contained in:
		| @@ -1,3 +1,18 @@ | |||||||
|  | 2009-01-29  Corinna Vinschen  <corinna@vinschen.de> | ||||||
|  |  | ||||||
|  | 	* fhandler_disk_file.cc (fhandler_disk_file::readdir): Fix inode number | ||||||
|  | 	evaluation for faked "." entry. | ||||||
|  |  | ||||||
|  | 	* mount.cc (fs_info::update): Move setting of is_cdrom after checking | ||||||
|  | 	for caseinsensitivity.  Recognize UDF in is_cdrom case and set | ||||||
|  | 	caseinsensitive flag according to UDF brokenness determined by OS. | ||||||
|  | 	Add comment to explain why. | ||||||
|  | 	* mount.h (class fs_info): Add is_udf status flag. | ||||||
|  | 	* path.cc (symlink_info::check): Add workaround for UDF bug in | ||||||
|  | 	terms of casesensitivity on certain OSes. | ||||||
|  | 	* wincap.h (wincaps::has_broken_udf): New element. | ||||||
|  | 	(wincaps::has_broken_udf): New element | ||||||
|  |  | ||||||
| 2009-01-27  Christopher Faylor  <me+cygwin@cgf.cx> | 2009-01-27  Christopher Faylor  <me+cygwin@cgf.cx> | ||||||
|  |  | ||||||
| 	* fhandler.cc (fhandler_base::wait_overlapped): Set bytes to -1 on | 	* fhandler.cc (fhandler_base::wait_overlapped): Set bytes to -1 on | ||||||
|   | |||||||
| @@ -1928,7 +1928,8 @@ go_ahead: | |||||||
|   else if (!(dir->__flags & dirent_saw_dot)) |   else if (!(dir->__flags & dirent_saw_dot)) | ||||||
|     { |     { | ||||||
|       strcpy (de->d_name , "."); |       strcpy (de->d_name , "."); | ||||||
|       de->d_ino = get_ino_by_handle (get_handle ()); |       if (pc.isgood_inode (de->d_ino)) | ||||||
|  | 	de->d_ino = get_ino_by_handle (get_handle ()); | ||||||
|       dir->__d_position++; |       dir->__d_position++; | ||||||
|       dir->__flags |= dirent_saw_dot; |       dir->__flags |= dirent_saw_dot; | ||||||
|       res = 0; |       res = 0; | ||||||
|   | |||||||
| @@ -262,7 +262,6 @@ fs_info::update (PUNICODE_STRING upath, HANDLE in_vol) | |||||||
|     } |     } | ||||||
|   is_ntfs (RtlEqualUnicodeString (&fsname, &testname, FALSE) |   is_ntfs (RtlEqualUnicodeString (&fsname, &testname, FALSE) | ||||||
| 	   && !is_samba () && !is_netapp ()); | 	   && !is_samba () && !is_netapp ()); | ||||||
|   is_cdrom (ffdi.DeviceType == FILE_DEVICE_CD_ROM); |  | ||||||
|  |  | ||||||
|   has_acls (flags () & FS_PERSISTENT_ACLS); |   has_acls (flags () & FS_PERSISTENT_ACLS); | ||||||
|   hasgood_inode (((flags () & FILE_PERSISTENT_ACLS) && !is_netapp ()) |   hasgood_inode (((flags () & FILE_PERSISTENT_ACLS) && !is_netapp ()) | ||||||
| @@ -274,6 +273,21 @@ fs_info::update (PUNICODE_STRING upath, HANDLE in_vol) | |||||||
|   caseinsensitive ((!(flags () & FILE_CASE_SENSITIVE_SEARCH) || is_samba ()) |   caseinsensitive ((!(flags () & FILE_CASE_SENSITIVE_SEARCH) || is_samba ()) | ||||||
| 		   && !is_nfs ()); | 		   && !is_nfs ()); | ||||||
|  |  | ||||||
|  |   is_cdrom (ffdi.DeviceType == FILE_DEVICE_CD_ROM); | ||||||
|  |   if (is_cdrom ()) | ||||||
|  |     { | ||||||
|  |       RtlInitUnicodeString (&testname, L"UDF"); | ||||||
|  |       is_udf (RtlEqualUnicodeString (&fsname, &testname, FALSE)); | ||||||
|  |       /* UDF on NT 5.x is broken (at least) in terms of case sensitivity.  The | ||||||
|  | 	 UDF driver reports the FILE_CASE_SENSITIVE_SEARCH capability but: | ||||||
|  | 	 - Opening the root directory for query seems to work at first, but the | ||||||
|  | 	   filenames in the directory listing are mutilated. | ||||||
|  | 	 - When trying to open a file or directory case sensitive, the file | ||||||
|  | 	   appears to be non-existant. */ | ||||||
|  |       if (is_udf () && wincap.has_broken_udf ()) | ||||||
|  | 	caseinsensitive (true); | ||||||
|  |     } | ||||||
|  |  | ||||||
|   if (!in_vol) |   if (!in_vol) | ||||||
|     NtClose (vol); |     NtClose (vol); | ||||||
|   return true; |   return true; | ||||||
|   | |||||||
| @@ -31,6 +31,7 @@ class fs_info | |||||||
|     unsigned is_nfs			: 1; |     unsigned is_nfs			: 1; | ||||||
|     unsigned is_netapp 			: 1; |     unsigned is_netapp 			: 1; | ||||||
|     unsigned is_cdrom			: 1; |     unsigned is_cdrom			: 1; | ||||||
|  |     unsigned is_udf			: 1; | ||||||
|   } status; |   } status; | ||||||
|   ULONG sernum; |   ULONG sernum; | ||||||
|  public: |  public: | ||||||
| @@ -52,6 +53,7 @@ class fs_info | |||||||
|   IMPLEMENT_STATUS_FLAG (bool, is_nfs) |   IMPLEMENT_STATUS_FLAG (bool, is_nfs) | ||||||
|   IMPLEMENT_STATUS_FLAG (bool, is_netapp) |   IMPLEMENT_STATUS_FLAG (bool, is_netapp) | ||||||
|   IMPLEMENT_STATUS_FLAG (bool, is_cdrom) |   IMPLEMENT_STATUS_FLAG (bool, is_cdrom) | ||||||
|  |   IMPLEMENT_STATUS_FLAG (bool, is_udf) | ||||||
|   ULONG serial_number () const { return sernum; } |   ULONG serial_number () const { return sernum; } | ||||||
|  |  | ||||||
|   bool update (PUNICODE_STRING, HANDLE) __attribute__ ((regparm (3))); |   bool update (PUNICODE_STRING, HANDLE) __attribute__ ((regparm (3))); | ||||||
|   | |||||||
| @@ -2140,6 +2140,7 @@ symlink_info::check (char *path, const suffix_info *suffixes, unsigned opt, | |||||||
|       NTSTATUS status; |       NTSTATUS status; | ||||||
|       IO_STATUS_BLOCK io; |       IO_STATUS_BLOCK io; | ||||||
|       bool no_ea = false; |       bool no_ea = false; | ||||||
|  |       bool fs_update_called = false; | ||||||
|  |  | ||||||
|       error = 0; |       error = 0; | ||||||
|       get_nt_native_path (suffix.path, upath); |       get_nt_native_path (suffix.path, upath); | ||||||
| @@ -2179,6 +2180,30 @@ symlink_info::check (char *path, const suffix_info *suffixes, unsigned opt, | |||||||
| 			       FILE_OPEN_REPARSE_POINT | 			       FILE_OPEN_REPARSE_POINT | ||||||
| 			       | FILE_OPEN_FOR_BACKUP_INTENT); | 			       | FILE_OPEN_FOR_BACKUP_INTENT); | ||||||
| 	} | 	} | ||||||
|  |       if (status == STATUS_OBJECT_NAME_NOT_FOUND && ci_flag == 0 | ||||||
|  | 	  && wincap.has_broken_udf ()) | ||||||
|  |         { | ||||||
|  | 	  /* On NT 5.x UDF is broken (at least) in terms of case sensitivity. | ||||||
|  | 	     When trying to open a file case sensitive, the file appears to be | ||||||
|  | 	     non-existant.  Another bug is described in fs_info::update. */ | ||||||
|  | 	  attr.Attributes = OBJ_CASE_INSENSITIVE; | ||||||
|  | 	  status = NtOpenFile (&h, READ_CONTROL | FILE_READ_ATTRIBUTES, | ||||||
|  | 			       &attr, &io, FILE_SHARE_VALID_FLAGS, | ||||||
|  | 			       FILE_OPEN_REPARSE_POINT | ||||||
|  | 			       | FILE_OPEN_FOR_BACKUP_INTENT); | ||||||
|  | 	  attr.Attributes = ci_flag; | ||||||
|  | 	  if (NT_SUCCESS (status)) | ||||||
|  | 	    { | ||||||
|  | 	      fs.update (&upath, h); | ||||||
|  | 	      if (fs.is_udf ()) | ||||||
|  | 		fs_update_called = true; | ||||||
|  | 	      else | ||||||
|  | 	      	{ | ||||||
|  | 		  NtClose (h); | ||||||
|  | 		  status = STATUS_OBJECT_NAME_NOT_FOUND; | ||||||
|  | 		} | ||||||
|  | 	    } | ||||||
|  | 	} | ||||||
|       if (NT_SUCCESS (status) |       if (NT_SUCCESS (status) | ||||||
| 	  && NT_SUCCESS (status | 	  && NT_SUCCESS (status | ||||||
| 			 = NtQueryInformationFile (h, &io, &fbi, sizeof fbi, | 			 = NtQueryInformationFile (h, &io, &fbi, sizeof fbi, | ||||||
| @@ -2271,7 +2296,8 @@ symlink_info::check (char *path, const suffix_info *suffixes, unsigned opt, | |||||||
|  |  | ||||||
|       /* Check file system while we're having the file open anyway. |       /* Check file system while we're having the file open anyway. | ||||||
| 	 This speeds up path_conv noticably (~10%). */ | 	 This speeds up path_conv noticably (~10%). */ | ||||||
|       fs.update (&upath, h); |       if (!fs_update_called) | ||||||
|  | 	fs.update (&upath, h); | ||||||
|  |  | ||||||
|       ext_tacked_on = !!*ext_here; |       ext_tacked_on = !!*ext_here; | ||||||
|  |  | ||||||
|   | |||||||
| @@ -53,6 +53,7 @@ wincaps wincap_unknown __attribute__((section (".cygwin_dll_common"), shared)) = | |||||||
|   ts_has_dep_problem:false, |   ts_has_dep_problem:false, | ||||||
|   has_recvmsg:false, |   has_recvmsg:false, | ||||||
|   has_sendmsg:false, |   has_sendmsg:false, | ||||||
|  |   has_broken_udf:false, | ||||||
| }; | }; | ||||||
|  |  | ||||||
| wincaps wincap_nt4 __attribute__((section (".cygwin_dll_common"), shared)) = { | wincaps wincap_nt4 __attribute__((section (".cygwin_dll_common"), shared)) = { | ||||||
| @@ -88,6 +89,7 @@ wincaps wincap_nt4 __attribute__((section (".cygwin_dll_common"), shared)) = { | |||||||
|   ts_has_dep_problem:false, |   ts_has_dep_problem:false, | ||||||
|   has_recvmsg:false, |   has_recvmsg:false, | ||||||
|   has_sendmsg:false, |   has_sendmsg:false, | ||||||
|  |   has_broken_udf:false, | ||||||
| }; | }; | ||||||
|  |  | ||||||
| wincaps wincap_nt4sp4 __attribute__((section (".cygwin_dll_common"), shared)) = { | wincaps wincap_nt4sp4 __attribute__((section (".cygwin_dll_common"), shared)) = { | ||||||
| @@ -123,6 +125,7 @@ wincaps wincap_nt4sp4 __attribute__((section (".cygwin_dll_common"), shared)) = | |||||||
|   ts_has_dep_problem:false, |   ts_has_dep_problem:false, | ||||||
|   has_recvmsg:false, |   has_recvmsg:false, | ||||||
|   has_sendmsg:false, |   has_sendmsg:false, | ||||||
|  |   has_broken_udf:false, | ||||||
| }; | }; | ||||||
|  |  | ||||||
| wincaps wincap_2000 __attribute__((section (".cygwin_dll_common"), shared)) = { | wincaps wincap_2000 __attribute__((section (".cygwin_dll_common"), shared)) = { | ||||||
| @@ -158,6 +161,7 @@ wincaps wincap_2000 __attribute__((section (".cygwin_dll_common"), shared)) = { | |||||||
|   ts_has_dep_problem:false, |   ts_has_dep_problem:false, | ||||||
|   has_recvmsg:false, |   has_recvmsg:false, | ||||||
|   has_sendmsg:false, |   has_sendmsg:false, | ||||||
|  |   has_broken_udf:true, | ||||||
| }; | }; | ||||||
|  |  | ||||||
| wincaps wincap_2000sp4 __attribute__((section (".cygwin_dll_common"), shared)) = { | wincaps wincap_2000sp4 __attribute__((section (".cygwin_dll_common"), shared)) = { | ||||||
| @@ -193,6 +197,7 @@ wincaps wincap_2000sp4 __attribute__((section (".cygwin_dll_common"), shared)) = | |||||||
|   ts_has_dep_problem:false, |   ts_has_dep_problem:false, | ||||||
|   has_recvmsg:false, |   has_recvmsg:false, | ||||||
|   has_sendmsg:false, |   has_sendmsg:false, | ||||||
|  |   has_broken_udf:true, | ||||||
| }; | }; | ||||||
|  |  | ||||||
| wincaps wincap_xp __attribute__((section (".cygwin_dll_common"), shared)) = { | wincaps wincap_xp __attribute__((section (".cygwin_dll_common"), shared)) = { | ||||||
| @@ -228,6 +233,7 @@ wincaps wincap_xp __attribute__((section (".cygwin_dll_common"), shared)) = { | |||||||
|   ts_has_dep_problem:false, |   ts_has_dep_problem:false, | ||||||
|   has_recvmsg:true, |   has_recvmsg:true, | ||||||
|   has_sendmsg:false, |   has_sendmsg:false, | ||||||
|  |   has_broken_udf:true, | ||||||
| }; | }; | ||||||
|  |  | ||||||
| wincaps wincap_xpsp1 __attribute__((section (".cygwin_dll_common"), shared)) = { | wincaps wincap_xpsp1 __attribute__((section (".cygwin_dll_common"), shared)) = { | ||||||
| @@ -263,6 +269,7 @@ wincaps wincap_xpsp1 __attribute__((section (".cygwin_dll_common"), shared)) = { | |||||||
|   ts_has_dep_problem:false, |   ts_has_dep_problem:false, | ||||||
|   has_recvmsg:true, |   has_recvmsg:true, | ||||||
|   has_sendmsg:false, |   has_sendmsg:false, | ||||||
|  |   has_broken_udf:true, | ||||||
| }; | }; | ||||||
|  |  | ||||||
| wincaps wincap_xpsp2 __attribute__((section (".cygwin_dll_common"), shared)) = { | wincaps wincap_xpsp2 __attribute__((section (".cygwin_dll_common"), shared)) = { | ||||||
| @@ -298,6 +305,7 @@ wincaps wincap_xpsp2 __attribute__((section (".cygwin_dll_common"), shared)) = { | |||||||
|   ts_has_dep_problem:false, |   ts_has_dep_problem:false, | ||||||
|   has_recvmsg:true, |   has_recvmsg:true, | ||||||
|   has_sendmsg:false, |   has_sendmsg:false, | ||||||
|  |   has_broken_udf:true, | ||||||
| }; | }; | ||||||
|  |  | ||||||
| wincaps wincap_2003 __attribute__((section (".cygwin_dll_common"), shared)) = { | wincaps wincap_2003 __attribute__((section (".cygwin_dll_common"), shared)) = { | ||||||
| @@ -333,6 +341,7 @@ wincaps wincap_2003 __attribute__((section (".cygwin_dll_common"), shared)) = { | |||||||
|   ts_has_dep_problem:false, |   ts_has_dep_problem:false, | ||||||
|   has_recvmsg:true, |   has_recvmsg:true, | ||||||
|   has_sendmsg:false, |   has_sendmsg:false, | ||||||
|  |   has_broken_udf:true, | ||||||
| }; | }; | ||||||
|  |  | ||||||
| wincaps wincap_vista __attribute__((section (".cygwin_dll_common"), shared)) = { | wincaps wincap_vista __attribute__((section (".cygwin_dll_common"), shared)) = { | ||||||
| @@ -368,6 +377,7 @@ wincaps wincap_vista __attribute__((section (".cygwin_dll_common"), shared)) = { | |||||||
|   ts_has_dep_problem:false, |   ts_has_dep_problem:false, | ||||||
|   has_recvmsg:true, |   has_recvmsg:true, | ||||||
|   has_sendmsg:true, |   has_sendmsg:true, | ||||||
|  |   has_broken_udf:false, | ||||||
| }; | }; | ||||||
|  |  | ||||||
| wincapc wincap __attribute__((section (".cygwin_dll_common"), shared)); | wincapc wincap __attribute__((section (".cygwin_dll_common"), shared)); | ||||||
|   | |||||||
| @@ -45,6 +45,7 @@ struct wincaps | |||||||
|   unsigned ts_has_dep_problem				: 1; |   unsigned ts_has_dep_problem				: 1; | ||||||
|   unsigned has_recvmsg					: 1; |   unsigned has_recvmsg					: 1; | ||||||
|   unsigned has_sendmsg					: 1; |   unsigned has_sendmsg					: 1; | ||||||
|  |   unsigned has_broken_udf				: 1; | ||||||
| }; | }; | ||||||
|  |  | ||||||
| class wincapc | class wincapc | ||||||
| @@ -96,6 +97,7 @@ public: | |||||||
|   bool	IMPLEMENT (ts_has_dep_problem) |   bool	IMPLEMENT (ts_has_dep_problem) | ||||||
|   bool	IMPLEMENT (has_recvmsg) |   bool	IMPLEMENT (has_recvmsg) | ||||||
|   bool	IMPLEMENT (has_sendmsg) |   bool	IMPLEMENT (has_sendmsg) | ||||||
|  |   bool	IMPLEMENT (has_broken_udf) | ||||||
|  |  | ||||||
| #undef IMPLEMENT | #undef IMPLEMENT | ||||||
| }; | }; | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user