* fhandler_disk_file.cc (fhandler_disk_file::opendir): Try to open
directory with stat()-friendly access mask first. Explain why.
This commit is contained in:
		| @@ -1,3 +1,8 @@ | |||||||
|  | 2010-02-19  Corinna Vinschen  <corinna@vinschen.de> | ||||||
|  |  | ||||||
|  | 	* fhandler_disk_file.cc (fhandler_disk_file::opendir): Try to open | ||||||
|  | 	directory with stat()-friendly access mask first.  Explain why. | ||||||
|  |  | ||||||
| 2010-02-19  Corinna Vinschen  <corinna@vinschen.de> | 2010-02-19  Corinna Vinschen  <corinna@vinschen.de> | ||||||
|  |  | ||||||
| 	* fhandler_disk_file.cc (fhandler_base::fstat_helper):  Set st_rdev | 	* fhandler_disk_file.cc (fhandler_base::fstat_helper):  Set st_rdev | ||||||
|   | |||||||
| @@ -1660,20 +1660,42 @@ fhandler_disk_file::opendir (int fd) | |||||||
| 	      OBJECT_ATTRIBUTES attr; | 	      OBJECT_ATTRIBUTES attr; | ||||||
| 	      NTSTATUS status; | 	      NTSTATUS status; | ||||||
| 	      IO_STATUS_BLOCK io; | 	      IO_STATUS_BLOCK io; | ||||||
|  | 	      /* Tools like ls(1) call dirfd() to fetch the directory | ||||||
|  | 		 descriptor for calls to facl or fstat.  The tight access mask | ||||||
|  | 		 used so far is not sufficient to reuse the handle for these | ||||||
|  | 		 calls, instead the facl/fstat calls find the handle to be | ||||||
|  | 		 unusable and have to re-open the file for reading attributes | ||||||
|  | 		 and control data.  So, what we do here is to try to open the | ||||||
|  | 		 directory with more relaxed access mask which enables to use | ||||||
|  | 		 the handle for the aforementioned purpose.  This should work | ||||||
|  | 		 in almost all cases.  Only if it doesn't work due to | ||||||
|  | 		 permission problems, we drop the additional access bits and | ||||||
|  | 		 try again. */ | ||||||
|  | 	      ACCESS_MASK fstat_mask = READ_CONTROL | FILE_READ_ATTRIBUTES; | ||||||
|  |  | ||||||
|  | 	      do | ||||||
|  | 		{ | ||||||
| 		  status = NtOpenFile (&get_handle (), | 		  status = NtOpenFile (&get_handle (), | ||||||
| 				   SYNCHRONIZE | FILE_LIST_DIRECTORY, | 				       SYNCHRONIZE | FILE_LIST_DIRECTORY | ||||||
|  | 				       | fstat_mask, | ||||||
| 				       pc.get_object_attr (attr, sec_none_nih), | 				       pc.get_object_attr (attr, sec_none_nih), | ||||||
| 				       &io, FILE_SHARE_VALID_FLAGS, | 				       &io, FILE_SHARE_VALID_FLAGS, | ||||||
| 				       FILE_SYNCHRONOUS_IO_NONALERT | 				       FILE_SYNCHRONOUS_IO_NONALERT | ||||||
| 				       | FILE_OPEN_FOR_BACKUP_INTENT | 				       | FILE_OPEN_FOR_BACKUP_INTENT | ||||||
| 				       | FILE_DIRECTORY_FILE); | 				       | FILE_DIRECTORY_FILE); | ||||||
| 		  if (!NT_SUCCESS (status)) | 		  if (!NT_SUCCESS (status)) | ||||||
|  | 		    { | ||||||
|  | 		      if (status == STATUS_ACCESS_DENIED && fstat_mask) | ||||||
|  | 			fstat_mask = 0; | ||||||
|  | 		      else | ||||||
| 			{ | 			{ | ||||||
| 			  __seterrno_from_nt_status (status); | 			  __seterrno_from_nt_status (status); | ||||||
| 			  goto free_mounts; | 			  goto free_mounts; | ||||||
| 			} | 			} | ||||||
| 		    } | 		    } | ||||||
|  | 		} | ||||||
|  | 	      while (!NT_SUCCESS (status)); | ||||||
|  | 	    } | ||||||
|  |  | ||||||
| 	  /* FileIdBothDirectoryInformation is apparently unsupported on | 	  /* FileIdBothDirectoryInformation is apparently unsupported on | ||||||
| 	     XP when accessing directories on UDF.  When trying to use it | 	     XP when accessing directories on UDF.  When trying to use it | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user