* fhandler_disk_file.cc (fhandler_base::fstat_by_name): Check for
file systems incapable of handling FileIdBothDirectoryInformation correctly. (fhandler_disk_file::opendir): Ditto. * path.cc (fs_info::update): Always clear at the start. Rearrange to make certain tests only on non-Samba, non-NFS remote drives. Add test for file systems known to be incapable of handling FileIdBothDirectoryInformation correctly. Right now that's just "UNIXFS". * path.h (struct fs_info): Add has_buggy_fileid_dirinfo flag and accessor methods. (class path_conv): Add has_buggy_fileid_dirinfo method.
This commit is contained in:
		| @@ -1,3 +1,19 @@ | ||||
| 2008-07-30  Corinna Vinschen  <corinna@vinschen.de> | ||||
|  | ||||
| 	* fhandler_disk_file.cc (fhandler_base::fstat_by_name): Check for | ||||
| 	file systems incapable of handling FileIdBothDirectoryInformation | ||||
| 	correctly. | ||||
| 	(fhandler_disk_file::opendir): Ditto. | ||||
| 	* path.cc (fs_info::update): Always clear at the start. | ||||
| 	Rearrange to make certain tests only on non-Samba, non-NFS remote | ||||
| 	drives. | ||||
| 	Add test for file systems known to be incapable of handling | ||||
| 	FileIdBothDirectoryInformation correctly.  Right now that's just | ||||
| 	"UNIXFS". | ||||
| 	* path.h (struct fs_info): Add has_buggy_fileid_dirinfo flag and | ||||
| 	accessor methods. | ||||
| 	(class path_conv): Add has_buggy_fileid_dirinfo method. | ||||
|  | ||||
| 2008-07-30  Corinna Vinschen  <corinna@vinschen.de> | ||||
|  | ||||
| 	* sec_auth.cc (extract_nt_dom_user): Return domain and user name as | ||||
|   | ||||
| @@ -390,7 +390,7 @@ fhandler_base::fstat_by_name (struct __stat64 *buf) | ||||
|       debug_printf ("%p = NtOpenFile(%S)", status, pc.get_nt_native_path ()); | ||||
|       goto too_bad; | ||||
|     } | ||||
|   if (wincap.has_fileid_dirinfo () | ||||
|   if (wincap.has_fileid_dirinfo () && !pc.has_buggy_fileid_dirinfo () | ||||
|       && NT_SUCCESS (status = NtQueryDirectoryFile (dir, NULL, NULL, 0, &io, | ||||
| 						 &fdi_buf.fdi, sizeof fdi_buf, | ||||
| 						 FileIdBothDirectoryInformation, | ||||
| @@ -1574,7 +1574,8 @@ fhandler_disk_file::opendir (int fd) | ||||
| 	      dir->__flags |= dirent_set_d_ino; | ||||
| 	      if (pc.fs_is_nfs ()) | ||||
| 	      	dir->__flags |= dirent_nfs_d_ino; | ||||
| 	      else if (wincap.has_fileid_dirinfo ()) | ||||
| 	      else if (wincap.has_fileid_dirinfo () | ||||
| 		       && !pc.has_buggy_fileid_dirinfo ()) | ||||
| 		dir->__flags |= dirent_get_d_ino; | ||||
| 	    } | ||||
| 	} | ||||
|   | ||||
| @@ -389,6 +389,7 @@ fs_info::update (PUNICODE_STRING upath, HANDLE in_vol) | ||||
|   } ffvi_buf; | ||||
|   UNICODE_STRING fsname, testname; | ||||
|  | ||||
|   clear (); | ||||
|   if (in_vol) | ||||
|     vol = in_vol; | ||||
|   else | ||||
| @@ -420,7 +421,6 @@ fs_info::update (PUNICODE_STRING upath, HANDLE in_vol) | ||||
| 	{ | ||||
| 	  debug_printf ("Cannot access path %S, status %08lx", | ||||
| 			attr.ObjectName, status); | ||||
| 	  clear (); | ||||
| 	  NtClose (vol); | ||||
| 	  return false; | ||||
| 	} | ||||
| @@ -450,8 +450,6 @@ fs_info::update (PUNICODE_STRING upath, HANDLE in_vol) | ||||
|     { | ||||
|       debug_printf ("Cannot get volume attributes (%S), %08lx", | ||||
| 		    attr.ObjectName, status); | ||||
|       has_buggy_open (false); | ||||
|       flags (0); | ||||
|       if (!in_vol) | ||||
| 	NtClose (vol); | ||||
|       return false; | ||||
| @@ -506,23 +504,38 @@ fs_info::update (PUNICODE_STRING upath, HANDLE in_vol) | ||||
| 	is_samba (RtlEqualUnicodeString (&fsname, &testname, FALSE) | ||||
| 		  && FS_IS_SAMBA); | ||||
|  | ||||
|       is_netapp (!is_samba () | ||||
| 		 && RtlEqualUnicodeString (&fsname, &testname, FALSE) | ||||
| 		 && FS_IS_NETAPP_DATAONTAP); | ||||
|       if (!is_samba ()) | ||||
|         { | ||||
| 	  is_netapp (RtlEqualUnicodeString (&fsname, &testname, FALSE) | ||||
| 		     && FS_IS_NETAPP_DATAONTAP); | ||||
|  | ||||
| 	  RtlInitUnicodeString (&testname, L"NFS"); | ||||
| 	  is_nfs (RtlEqualUnicodeString (&fsname, &testname, FALSE)); | ||||
|  | ||||
| 	  if (!is_nfs ()) | ||||
| 	    { | ||||
| 	      /* Known remote file systems which can't handle calls to | ||||
| 	         NtQueryDirectoryFile(FileIdBothDirectoryInformation) */ | ||||
| 	      RtlInitUnicodeString (&testname, L"UNIXFS"); | ||||
| 	      has_buggy_fileid_dirinfo (RtlEqualUnicodeString (&fsname, | ||||
| 							       &testname, | ||||
| 							       FALSE)); | ||||
|  | ||||
| 	      /* Known remote file systems with buggy open calls.  Further | ||||
| 		 explanation in fhandler.cc (fhandler_disk_file::open). */ | ||||
| 	      RtlInitUnicodeString (&testname, L"SUNWNFS"); | ||||
| 	      has_buggy_open (RtlEqualUnicodeString (&fsname, &testname, | ||||
| 						     FALSE)); | ||||
| 	    } | ||||
| 	} | ||||
|     } | ||||
|   is_ntfs (RtlEqualUnicodeString (&fsname, &testname, FALSE) | ||||
| 	   && !is_samba () && !is_netapp ()); | ||||
|   RtlInitUnicodeString (&testname, L"NFS"); | ||||
|   is_nfs (RtlEqualUnicodeString (&fsname, &testname, FALSE)); | ||||
|   is_cdrom (ffdi.DeviceType == FILE_DEVICE_CD_ROM); | ||||
|  | ||||
|   has_acls (flags () & FS_PERSISTENT_ACLS); | ||||
|   hasgood_inode (((flags () & FILE_PERSISTENT_ACLS) && !is_netapp ()) | ||||
| 		 || is_nfs ()); | ||||
|   /* Known file systems with buggy open calls. Further explanation | ||||
|      in fhandler.cc (fhandler_disk_file::open). */ | ||||
|   RtlInitUnicodeString (&testname, L"SUNWNFS"); | ||||
|   has_buggy_open (RtlEqualUnicodeString (&fsname, &testname, FALSE)); | ||||
|   /* Case sensitivity is supported if FILE_CASE_SENSITIVE_SEARCH is set, | ||||
|      except on Samba which handles Windows clients case insensitive. | ||||
|      NFS doesn't set the FILE_CASE_SENSITIVE_SEARCH flag but is case | ||||
|   | ||||
| @@ -91,17 +91,18 @@ struct fs_info | ||||
|     ULONG flags;                  /* Volume flags */ | ||||
|     ULONG samba_version;          /* Samba version if available */ | ||||
|     ULONG name_len;		  /* MaximumComponentNameLength */ | ||||
|     unsigned is_remote_drive : 1; | ||||
|     unsigned has_buggy_open  : 1; | ||||
|     unsigned has_acls	     : 1; | ||||
|     unsigned hasgood_inode   : 1; | ||||
|     unsigned caseinsensitive : 1; | ||||
|     unsigned is_fat	     : 1; | ||||
|     unsigned is_ntfs	     : 1; | ||||
|     unsigned is_samba	     : 1; | ||||
|     unsigned is_nfs	     : 1; | ||||
|     unsigned is_netapp       : 1; | ||||
|     unsigned is_cdrom	     : 1; | ||||
|     unsigned is_remote_drive		: 1; | ||||
|     unsigned has_buggy_open		: 1; | ||||
|     unsigned has_buggy_fileid_dirinfo	: 1; | ||||
|     unsigned has_acls			: 1; | ||||
|     unsigned hasgood_inode		: 1; | ||||
|     unsigned caseinsensitive		: 1; | ||||
|     unsigned is_fat			: 1; | ||||
|     unsigned is_ntfs			: 1; | ||||
|     unsigned is_samba			: 1; | ||||
|     unsigned is_nfs			: 1; | ||||
|     unsigned is_netapp 			: 1; | ||||
|     unsigned is_cdrom			: 1; | ||||
|   } status; | ||||
|   ULONG sernum; | ||||
|  public: | ||||
| @@ -113,6 +114,7 @@ struct fs_info | ||||
|   IMPLEMENT_STATUS_FLAG (ULONG, name_len) | ||||
|   IMPLEMENT_STATUS_FLAG (bool, is_remote_drive) | ||||
|   IMPLEMENT_STATUS_FLAG (bool, has_buggy_open) | ||||
|   IMPLEMENT_STATUS_FLAG (bool, has_buggy_fileid_dirinfo) | ||||
|   IMPLEMENT_STATUS_FLAG (bool, has_acls) | ||||
|   IMPLEMENT_STATUS_FLAG (bool, hasgood_inode) | ||||
|   IMPLEMENT_STATUS_FLAG (bool, caseinsensitive) | ||||
| @@ -149,6 +151,7 @@ class path_conv | ||||
|   bool isgood_inode (__ino64_t ino) const; | ||||
|   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 binmode () const | ||||
|   { | ||||
|     if (path_flags & PATH_BINARY) | ||||
|   | ||||
		Reference in New Issue
	
	Block a user