Throughout, use FileBothDirectoryInformation info class rather than

FileDirectoryInformation info class to avoid problems with incomplete
	filesystem implementations.  Fix comments accordingly.
	* fhandler_disk_file.cc (fhandler_disk_file::readdir_helper): Set
	fname->Length to 0 in error case to avoid potential crash in debug
	output.
	(fhandler_disk_file::readdir): Try to speed up the working default case.
	Check for STATUS_INVALID_NETWORK_RESPONSE as potential status value
	returned by filesystems not implementing FileIdBothDirectoryInformation.
	* ntdll.h (STATUS_INVALID_NETWORK_RESPONSE): Define.
	(FILE_BOTH_DIRECTORY_INFORMATION): Rename to official name.
	* path.cc (symlink_info::check): Don't request FILE_READ_EA access, it's
	not required for NFS.  Try to speed up the working default case.  Check
	for STATUS_INVALID_NETWORK_RESPONSE as potential status value returned
	by filesystems not supporting non-NULL EA parameters.  Fix the way
	fs.update is called.  Improve debug output.
This commit is contained in:
Corinna Vinschen
2010-01-29 11:20:06 +00:00
parent 3d635c060e
commit 3432d6f1f7
4 changed files with 74 additions and 43 deletions

View File

@@ -514,7 +514,7 @@ getfileattr (const char *path, bool caseinsensitive) /* path has to be always ab
directory query. */
UNICODE_STRING dirname, basename;
HANDLE dir;
FILE_DIRECTORY_INFORMATION fdi;
FILE_BOTH_DIRECTORY_INFORMATION fdi;
RtlSplitUnicodePath (&upath, &dirname, &basename);
InitializeObjectAttributes (&attr, &dirname,
@@ -529,7 +529,7 @@ getfileattr (const char *path, bool caseinsensitive) /* path has to be always ab
{
status = NtQueryDirectoryFile (dir, NULL, NULL, 0, &io,
&fdi, sizeof fdi,
FileDirectoryInformation,
FileBothDirectoryInformation,
TRUE, &basename, TRUE);
NtClose (dir);
if (NT_SUCCESS (status) || status == STATUS_BUFFER_OVERFLOW)
@@ -2209,18 +2209,22 @@ symlink_info::check (char *path, const suffix_info *suffixes, unsigned opt,
Fortunately it's ignored on most other file systems so we don't have
to special case NFS too much. */
status = NtCreateFile (&h,
READ_CONTROL | FILE_READ_ATTRIBUTES | FILE_READ_EA,
READ_CONTROL | FILE_READ_ATTRIBUTES,
&attr, &io, NULL, 0, FILE_SHARE_VALID_FLAGS,
FILE_OPEN,
FILE_OPEN_REPARSE_POINT
| FILE_OPEN_FOR_BACKUP_INTENT,
eabuf, easize);
debug_printf ("%p = NtCreateFile (%S)", status, &upath);
/* No right to access EAs or EAs not supported? */
if (status == STATUS_ACCESS_DENIED || status == STATUS_EAS_NOT_SUPPORTED
|| status == STATUS_NOT_SUPPORTED
/* Or a bug in Samba 3.2.x (x <= 7) when accessing a share's root dir
which has EAs enabled? */
|| status == STATUS_INVALID_PARAMETER)
if (!NT_SUCCESS (status)
&& (status == STATUS_ACCESS_DENIED
|| status == STATUS_EAS_NOT_SUPPORTED
|| status == STATUS_NOT_SUPPORTED
|| status == STATUS_INVALID_NETWORK_RESPONSE
/* Or a bug in Samba 3.2.x (x <= 7) when accessing a share's
root dir which has EAs enabled? */
|| status == STATUS_INVALID_PARAMETER))
{
no_ea = true;
/* If EAs are not supported, there's no sense to check them again
@@ -2235,6 +2239,7 @@ symlink_info::check (char *path, const suffix_info *suffixes, unsigned opt,
&attr, &io, FILE_SHARE_VALID_FLAGS,
FILE_OPEN_REPARSE_POINT
| FILE_OPEN_FOR_BACKUP_INTENT);
debug_printf ("%p = NtOpenFile (no-EA, %S)", status, &upath);
}
if (status == STATUS_OBJECT_NAME_NOT_FOUND && ci_flag == 0
&& wincap.has_broken_udf ())
@@ -2247,6 +2252,7 @@ symlink_info::check (char *path, const suffix_info *suffixes, unsigned opt,
&attr, &io, FILE_SHARE_VALID_FLAGS,
FILE_OPEN_REPARSE_POINT
| FILE_OPEN_FOR_BACKUP_INTENT);
debug_printf ("%p = NtOpenFile (broken-UDF, %S)", status, &upath);
attr.Attributes = 0;
if (NT_SUCCESS (status))
{
@@ -2261,12 +2267,10 @@ 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)
/* Check file system while we're having the file open anyway.
This speeds up path_conv noticably (~10%). */
&& (fs_update_called || fs.update (&upath, h))
&& NT_SUCCESS (status = fs.has_buggy_basic_info ()
? NtQueryAttributesFile (&attr, &fbi)
: NtQueryInformationFile (h, &io, &fbi, sizeof fbi,
@@ -2306,7 +2310,7 @@ symlink_info::check (char *path, const suffix_info *suffixes, unsigned opt,
OBJECT_ATTRIBUTES dattr;
HANDLE dir;
struct {
FILE_DIRECTORY_INFORMATION fdi;
FILE_BOTH_DIRECTORY_INFORMATION fdi;
WCHAR dummy_buf[NAME_MAX + 1];
} fdi_buf;
@@ -2332,7 +2336,7 @@ symlink_info::check (char *path, const suffix_info *suffixes, unsigned opt,
{
status = NtQueryDirectoryFile (dir, NULL, NULL, NULL, &io,
&fdi_buf, sizeof fdi_buf,
FileDirectoryInformation,
FileBothDirectoryInformation,
TRUE, &basename, TRUE);
/* Take the opportunity to check file system while we're
having the handle to the parent dir. */