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:
parent
3d635c060e
commit
3432d6f1f7
|
@ -1,3 +1,22 @@
|
||||||
|
2010-01-29 Corinna Vinschen <corinna@vinschen.de>
|
||||||
|
|
||||||
|
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.
|
||||||
|
|
||||||
2010-01-28 Corinna Vinschen <corinna@vinschen.de>
|
2010-01-28 Corinna Vinschen <corinna@vinschen.de>
|
||||||
|
|
||||||
* Makefile.in (tags, ctags, CTAGS)): Add rules to create tags file.
|
* Makefile.in (tags, ctags, CTAGS)): Add rules to create tags file.
|
||||||
|
|
|
@ -211,11 +211,11 @@ path_conv::ndisk_links (DWORD nNumberOfLinks)
|
||||||
|
|
||||||
unsigned count = 0;
|
unsigned count = 0;
|
||||||
bool first = true;
|
bool first = true;
|
||||||
PFILE_DIRECTORY_INFORMATION fdibuf = (PFILE_DIRECTORY_INFORMATION)
|
PFILE_BOTH_DIRECTORY_INFORMATION fdibuf = (PFILE_BOTH_DIRECTORY_INFORMATION)
|
||||||
alloca (65536);
|
alloca (65536);
|
||||||
__DIR_mounts *dir = new __DIR_mounts (normalized_path);
|
__DIR_mounts *dir = new __DIR_mounts (normalized_path);
|
||||||
while (NT_SUCCESS (NtQueryDirectoryFile (fh, NULL, NULL, NULL, &io, fdibuf,
|
while (NT_SUCCESS (NtQueryDirectoryFile (fh, NULL, NULL, NULL, &io, fdibuf,
|
||||||
65536, FileDirectoryInformation,
|
65536, FileBothDirectoryInformation,
|
||||||
FALSE, NULL, first)))
|
FALSE, NULL, first)))
|
||||||
{
|
{
|
||||||
if (first)
|
if (first)
|
||||||
|
@ -227,9 +227,9 @@ path_conv::ndisk_links (DWORD nNumberOfLinks)
|
||||||
if (fdibuf->FileNameLength != 2 || fdibuf->FileName[0] != L'.')
|
if (fdibuf->FileNameLength != 2 || fdibuf->FileName[0] != L'.')
|
||||||
count = 2;
|
count = 2;
|
||||||
}
|
}
|
||||||
for (PFILE_DIRECTORY_INFORMATION pfdi = fdibuf;
|
for (PFILE_BOTH_DIRECTORY_INFORMATION pfdi = fdibuf;
|
||||||
pfdi;
|
pfdi;
|
||||||
pfdi = (PFILE_DIRECTORY_INFORMATION)
|
pfdi = (PFILE_BOTH_DIRECTORY_INFORMATION)
|
||||||
(pfdi->NextEntryOffset ? (PBYTE) pfdi + pfdi->NextEntryOffset
|
(pfdi->NextEntryOffset ? (PBYTE) pfdi + pfdi->NextEntryOffset
|
||||||
: NULL))
|
: NULL))
|
||||||
{
|
{
|
||||||
|
@ -434,7 +434,7 @@ fhandler_base::fstat_by_name (struct __stat64 *buf)
|
||||||
else if (NT_SUCCESS (status = NtQueryDirectoryFile (dir, NULL, NULL, NULL,
|
else if (NT_SUCCESS (status = NtQueryDirectoryFile (dir, NULL, NULL, NULL,
|
||||||
&io, &fdi_buf.fdi,
|
&io, &fdi_buf.fdi,
|
||||||
sizeof fdi_buf,
|
sizeof fdi_buf,
|
||||||
FileDirectoryInformation,
|
FileBothDirectoryInformation,
|
||||||
TRUE, &basename, TRUE)))
|
TRUE, &basename, TRUE)))
|
||||||
FileId.QuadPart = 0; /* get_ino is called in fstat_helper. */
|
FileId.QuadPart = 0; /* get_ino is called in fstat_helper. */
|
||||||
if (!NT_SUCCESS (status))
|
if (!NT_SUCCESS (status))
|
||||||
|
@ -1665,7 +1665,7 @@ fhandler_disk_file::opendir (int fd)
|
||||||
OS/FS combinations (say, Win2K/CDFS or so). Instead of
|
OS/FS combinations (say, Win2K/CDFS or so). Instead of
|
||||||
testing in readdir for yet another error code, let's use
|
testing in readdir for yet another error code, let's use
|
||||||
FileIdBothDirectoryInformation only on filesystems supporting
|
FileIdBothDirectoryInformation only on filesystems supporting
|
||||||
persistent ACLs, FileDirectoryInformation otherwise.
|
persistent ACLs, FileBothDirectoryInformation otherwise.
|
||||||
|
|
||||||
NFS clients hide dangling symlinks from directory queries,
|
NFS clients hide dangling symlinks from directory queries,
|
||||||
unless you use the FileNamesInformation info class.
|
unless you use the FileNamesInformation info class.
|
||||||
|
@ -1770,7 +1770,10 @@ fhandler_disk_file::readdir_helper (DIR *dir, dirent *de, DWORD w32_err,
|
||||||
if ((de->d_ino = d_mounts (dir)->check_missing_mount (fname)))
|
if ((de->d_ino = d_mounts (dir)->check_missing_mount (fname)))
|
||||||
added = true;
|
added = true;
|
||||||
if (!added)
|
if (!added)
|
||||||
|
{
|
||||||
|
fname->Length = 0;
|
||||||
return geterrno_from_win_error (w32_err);
|
return geterrno_from_win_error (w32_err);
|
||||||
|
}
|
||||||
|
|
||||||
attr = 0;
|
attr = 0;
|
||||||
dir->__flags &= ~dirent_set_d_ino;
|
dir->__flags &= ~dirent_set_d_ino;
|
||||||
|
@ -1891,30 +1894,32 @@ fhandler_disk_file::readdir (DIR *dir, dirent *de)
|
||||||
which return STATUS_NOT_SUPPORTED rather than handling this info
|
which return STATUS_NOT_SUPPORTED rather than handling this info
|
||||||
class. We just fall back to using a standard directory query in
|
class. We just fall back to using a standard directory query in
|
||||||
this case and note this case using the dirent_get_d_ino flag. */
|
this case and note this case using the dirent_get_d_ino flag. */
|
||||||
if (status == STATUS_INVALID_LEVEL
|
if (!NT_SUCCESS (status) && status != STATUS_NO_MORE_FILES
|
||||||
|
&& (status == STATUS_INVALID_LEVEL
|
||||||
|| status == STATUS_NOT_SUPPORTED
|
|| status == STATUS_NOT_SUPPORTED
|
||||||
|| status == STATUS_INVALID_PARAMETER
|
|| status == STATUS_INVALID_PARAMETER
|
||||||
|| status == STATUS_INVALID_INFO_CLASS)
|
|| status == STATUS_INVALID_NETWORK_RESPONSE
|
||||||
|
|| status == STATUS_INVALID_INFO_CLASS))
|
||||||
dir->__flags &= ~dirent_get_d_ino;
|
dir->__flags &= ~dirent_get_d_ino;
|
||||||
/* Something weird happens on Samba up to version 3.0.21c, which is
|
/* Something weird happens on Samba up to version 3.0.21c, which is
|
||||||
fixed in 3.0.22. FileIdBothDirectoryInformation seems to work
|
fixed in 3.0.22. FileIdBothDirectoryInformation seems to work
|
||||||
nicely, but only up to the 128th entry in the directory. After
|
nicely, but only up to the 128th entry in the directory. After
|
||||||
reaching this entry, the next call to NtQueryDirectoryFile
|
reaching this entry, the next call to NtQueryDirectoryFile
|
||||||
(FileIdBothDirectoryInformation) returns STATUS_INVALID_LEVEL.
|
(FileIdBothDirectoryInformation) returns STATUS_INVALID_LEVEL.
|
||||||
Why should we care, we can just switch to FileDirectoryInformation,
|
Why should we care, we can just switch to
|
||||||
isn't it? Nope! The next call to
|
FileBothDirectoryInformation, isn't it? Nope! The next call to
|
||||||
NtQueryDirectoryFile(FileDirectoryInformation)
|
NtQueryDirectoryFile(FileBothDirectoryInformation) actually
|
||||||
actually returns STATUS_NO_MORE_FILES, regardless how many files
|
returns STATUS_NO_MORE_FILES, regardless how many files are left
|
||||||
are left unread in the directory. This does not happen when using
|
unread in the directory. This does not happen when using
|
||||||
FileDirectoryInformation right from the start, but since
|
FileBothDirectoryInformation right from the start, but since
|
||||||
we can't decide whether the server we're talking with has this
|
we can't decide whether the server we're talking with has this
|
||||||
bug or not, we end up serving Samba shares always in the slow
|
bug or not, we end up serving Samba shares always in the slow
|
||||||
mode using FileDirectoryInformation. So, what we do here is
|
mode using FileBothDirectoryInformation. So, what we do here is
|
||||||
to implement the solution suggested by Andrew Tridgell, we just
|
to implement the solution suggested by Andrew Tridgell, we just
|
||||||
reread all entries up to dir->d_position using
|
reread all entries up to dir->d_position using
|
||||||
FileDirectoryInformation.
|
FileBothDirectoryInformation.
|
||||||
However, We do *not* mark this server as broken and fall back to
|
However, We do *not* mark this server as broken and fall back to
|
||||||
using FileDirectoryInformation further on. This would slow
|
using FileBothDirectoryInformation further on. This would slow
|
||||||
down every access to such a server, even for directories under
|
down every access to such a server, even for directories under
|
||||||
128 entries. Also, bigger dirs only suffer from one additional
|
128 entries. Also, bigger dirs only suffer from one additional
|
||||||
call per full directory scan, which shouldn't be too big a hit.
|
call per full directory scan, which shouldn't be too big a hit.
|
||||||
|
@ -1929,7 +1934,7 @@ fhandler_disk_file::readdir (DIR *dir, dirent *de)
|
||||||
status = NtQueryDirectoryFile (get_handle (), NULL, NULL,
|
status = NtQueryDirectoryFile (get_handle (), NULL, NULL,
|
||||||
NULL, &io, d_cache (dir),
|
NULL, &io, d_cache (dir),
|
||||||
DIR_BUF_SIZE,
|
DIR_BUF_SIZE,
|
||||||
FileDirectoryInformation,
|
FileBothDirectoryInformation,
|
||||||
FALSE, NULL, cnt == 0);
|
FALSE, NULL, cnt == 0);
|
||||||
if (!NT_SUCCESS (status))
|
if (!NT_SUCCESS (status))
|
||||||
goto go_ahead;
|
goto go_ahead;
|
||||||
|
@ -1949,7 +1954,7 @@ fhandler_disk_file::readdir (DIR *dir, dirent *de)
|
||||||
d_cache (dir), DIR_BUF_SIZE,
|
d_cache (dir), DIR_BUF_SIZE,
|
||||||
(dir->__flags & dirent_nfs_d_ino)
|
(dir->__flags & dirent_nfs_d_ino)
|
||||||
? FileNamesInformation
|
? FileNamesInformation
|
||||||
: FileDirectoryInformation,
|
: FileBothDirectoryInformation,
|
||||||
FALSE, NULL, dir->__d_position == 0);
|
FALSE, NULL, dir->__d_position == 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1982,9 +1987,11 @@ go_ahead:
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
FileName = ((PFILE_DIRECTORY_INFORMATION) buf)->FileName;
|
FileName = ((PFILE_BOTH_DIRECTORY_INFORMATION) buf)->FileName;
|
||||||
FileNameLength = ((PFILE_DIRECTORY_INFORMATION) buf)->FileNameLength;
|
FileNameLength =
|
||||||
FileAttributes = ((PFILE_DIRECTORY_INFORMATION) buf)->FileAttributes;
|
((PFILE_BOTH_DIRECTORY_INFORMATION) buf)->FileNameLength;
|
||||||
|
FileAttributes =
|
||||||
|
((PFILE_BOTH_DIRECTORY_INFORMATION) buf)->FileAttributes;
|
||||||
}
|
}
|
||||||
RtlInitCountedUnicodeString (&fname, FileName, FileNameLength);
|
RtlInitCountedUnicodeString (&fname, FileName, FileNameLength);
|
||||||
de->d_ino = d_mounts (dir)->check_mount (&fname, de->d_ino);
|
de->d_ino = d_mounts (dir)->check_mount (&fname, de->d_ino);
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/* ntdll.h. Contains ntdll specific stuff not defined elsewhere.
|
/* ntdll.h. Contains ntdll specific stuff not defined elsewhere.
|
||||||
|
|
||||||
Copyright 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008,
|
Copyright 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008,
|
||||||
2009 Red Hat, Inc.
|
2009, 2010 Red Hat, Inc.
|
||||||
|
|
||||||
This file is part of Cygwin.
|
This file is part of Cygwin.
|
||||||
|
|
||||||
|
@ -39,6 +39,7 @@
|
||||||
#define STATUS_DISK_FULL ((NTSTATUS) 0xc000007f)
|
#define STATUS_DISK_FULL ((NTSTATUS) 0xc000007f)
|
||||||
#define STATUS_WORKING_SET_QUOTA ((NTSTATUS) 0xc00000a1)
|
#define STATUS_WORKING_SET_QUOTA ((NTSTATUS) 0xc00000a1)
|
||||||
#define STATUS_NOT_SUPPORTED ((NTSTATUS) 0xc00000bb)
|
#define STATUS_NOT_SUPPORTED ((NTSTATUS) 0xc00000bb)
|
||||||
|
#define STATUS_INVALID_NETWORK_RESPONSE ((NTSTATUS) 0xc00000c3)
|
||||||
#define STATUS_DIRECTORY_NOT_EMPTY ((NTSTATUS) 0xc0000101)
|
#define STATUS_DIRECTORY_NOT_EMPTY ((NTSTATUS) 0xc0000101)
|
||||||
#define STATUS_CANNOT_DELETE ((NTSTATUS) 0xc0000121)
|
#define STATUS_CANNOT_DELETE ((NTSTATUS) 0xc0000121)
|
||||||
#define STATUS_INVALID_LEVEL ((NTSTATUS) 0xc0000148)
|
#define STATUS_INVALID_LEVEL ((NTSTATUS) 0xc0000148)
|
||||||
|
@ -153,7 +154,7 @@ typedef struct _FILE_DIRECTORY_INFORMATION {
|
||||||
WCHAR FileName[1];
|
WCHAR FileName[1];
|
||||||
} FILE_DIRECTORY_INFORMATION, *PFILE_DIRECTORY_INFORMATION;
|
} FILE_DIRECTORY_INFORMATION, *PFILE_DIRECTORY_INFORMATION;
|
||||||
|
|
||||||
typedef struct _FILE_BOTH_DIR_INFORMATION
|
typedef struct _FILE_BOTH_DIRECTORY_INFORMATION
|
||||||
{
|
{
|
||||||
ULONG NextEntryOffset;
|
ULONG NextEntryOffset;
|
||||||
ULONG FileIndex;
|
ULONG FileIndex;
|
||||||
|
@ -169,7 +170,7 @@ typedef struct _FILE_BOTH_DIR_INFORMATION
|
||||||
CCHAR ShortNameLength;
|
CCHAR ShortNameLength;
|
||||||
WCHAR ShortName[12];
|
WCHAR ShortName[12];
|
||||||
WCHAR FileName[1];
|
WCHAR FileName[1];
|
||||||
} FILE_BOTH_DIR_INFORMATION, *PFILE_BOTH_DIR_INFORMATION;
|
} FILE_BOTH_DIRECTORY_INFORMATION, *PFILE_BOTH_DIRECTORY_INFORMATION;
|
||||||
|
|
||||||
typedef struct _FILE_ID_BOTH_DIR_INFORMATION
|
typedef struct _FILE_ID_BOTH_DIR_INFORMATION
|
||||||
{
|
{
|
||||||
|
|
|
@ -514,7 +514,7 @@ getfileattr (const char *path, bool caseinsensitive) /* path has to be always ab
|
||||||
directory query. */
|
directory query. */
|
||||||
UNICODE_STRING dirname, basename;
|
UNICODE_STRING dirname, basename;
|
||||||
HANDLE dir;
|
HANDLE dir;
|
||||||
FILE_DIRECTORY_INFORMATION fdi;
|
FILE_BOTH_DIRECTORY_INFORMATION fdi;
|
||||||
|
|
||||||
RtlSplitUnicodePath (&upath, &dirname, &basename);
|
RtlSplitUnicodePath (&upath, &dirname, &basename);
|
||||||
InitializeObjectAttributes (&attr, &dirname,
|
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,
|
status = NtQueryDirectoryFile (dir, NULL, NULL, 0, &io,
|
||||||
&fdi, sizeof fdi,
|
&fdi, sizeof fdi,
|
||||||
FileDirectoryInformation,
|
FileBothDirectoryInformation,
|
||||||
TRUE, &basename, TRUE);
|
TRUE, &basename, TRUE);
|
||||||
NtClose (dir);
|
NtClose (dir);
|
||||||
if (NT_SUCCESS (status) || status == STATUS_BUFFER_OVERFLOW)
|
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
|
Fortunately it's ignored on most other file systems so we don't have
|
||||||
to special case NFS too much. */
|
to special case NFS too much. */
|
||||||
status = NtCreateFile (&h,
|
status = NtCreateFile (&h,
|
||||||
READ_CONTROL | FILE_READ_ATTRIBUTES | FILE_READ_EA,
|
READ_CONTROL | FILE_READ_ATTRIBUTES,
|
||||||
&attr, &io, NULL, 0, FILE_SHARE_VALID_FLAGS,
|
&attr, &io, NULL, 0, FILE_SHARE_VALID_FLAGS,
|
||||||
FILE_OPEN,
|
FILE_OPEN,
|
||||||
FILE_OPEN_REPARSE_POINT
|
FILE_OPEN_REPARSE_POINT
|
||||||
| FILE_OPEN_FOR_BACKUP_INTENT,
|
| FILE_OPEN_FOR_BACKUP_INTENT,
|
||||||
eabuf, easize);
|
eabuf, easize);
|
||||||
|
debug_printf ("%p = NtCreateFile (%S)", status, &upath);
|
||||||
/* No right to access EAs or EAs not supported? */
|
/* No right to access EAs or EAs not supported? */
|
||||||
if (status == STATUS_ACCESS_DENIED || status == STATUS_EAS_NOT_SUPPORTED
|
if (!NT_SUCCESS (status)
|
||||||
|
&& (status == STATUS_ACCESS_DENIED
|
||||||
|
|| status == STATUS_EAS_NOT_SUPPORTED
|
||||||
|| status == STATUS_NOT_SUPPORTED
|
|| status == STATUS_NOT_SUPPORTED
|
||||||
/* Or a bug in Samba 3.2.x (x <= 7) when accessing a share's root dir
|
|| status == STATUS_INVALID_NETWORK_RESPONSE
|
||||||
which has EAs enabled? */
|
/* Or a bug in Samba 3.2.x (x <= 7) when accessing a share's
|
||||||
|| status == STATUS_INVALID_PARAMETER)
|
root dir which has EAs enabled? */
|
||||||
|
|| status == STATUS_INVALID_PARAMETER))
|
||||||
{
|
{
|
||||||
no_ea = true;
|
no_ea = true;
|
||||||
/* If EAs are not supported, there's no sense to check them again
|
/* 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,
|
&attr, &io, FILE_SHARE_VALID_FLAGS,
|
||||||
FILE_OPEN_REPARSE_POINT
|
FILE_OPEN_REPARSE_POINT
|
||||||
| FILE_OPEN_FOR_BACKUP_INTENT);
|
| FILE_OPEN_FOR_BACKUP_INTENT);
|
||||||
|
debug_printf ("%p = NtOpenFile (no-EA, %S)", status, &upath);
|
||||||
}
|
}
|
||||||
if (status == STATUS_OBJECT_NAME_NOT_FOUND && ci_flag == 0
|
if (status == STATUS_OBJECT_NAME_NOT_FOUND && ci_flag == 0
|
||||||
&& wincap.has_broken_udf ())
|
&& 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,
|
&attr, &io, FILE_SHARE_VALID_FLAGS,
|
||||||
FILE_OPEN_REPARSE_POINT
|
FILE_OPEN_REPARSE_POINT
|
||||||
| FILE_OPEN_FOR_BACKUP_INTENT);
|
| FILE_OPEN_FOR_BACKUP_INTENT);
|
||||||
|
debug_printf ("%p = NtOpenFile (broken-UDF, %S)", status, &upath);
|
||||||
attr.Attributes = 0;
|
attr.Attributes = 0;
|
||||||
if (NT_SUCCESS (status))
|
if (NT_SUCCESS (status))
|
||||||
{
|
{
|
||||||
|
@ -2261,12 +2267,10 @@ symlink_info::check (char *path, const suffix_info *suffixes, unsigned opt,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (NT_SUCCESS (status)
|
||||||
/* 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%). */
|
||||||
if (!fs_update_called)
|
&& (fs_update_called || fs.update (&upath, h))
|
||||||
fs.update (&upath, h);
|
|
||||||
|
|
||||||
if (NT_SUCCESS (status)
|
|
||||||
&& NT_SUCCESS (status = fs.has_buggy_basic_info ()
|
&& NT_SUCCESS (status = fs.has_buggy_basic_info ()
|
||||||
? NtQueryAttributesFile (&attr, &fbi)
|
? NtQueryAttributesFile (&attr, &fbi)
|
||||||
: NtQueryInformationFile (h, &io, &fbi, sizeof 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;
|
OBJECT_ATTRIBUTES dattr;
|
||||||
HANDLE dir;
|
HANDLE dir;
|
||||||
struct {
|
struct {
|
||||||
FILE_DIRECTORY_INFORMATION fdi;
|
FILE_BOTH_DIRECTORY_INFORMATION fdi;
|
||||||
WCHAR dummy_buf[NAME_MAX + 1];
|
WCHAR dummy_buf[NAME_MAX + 1];
|
||||||
} fdi_buf;
|
} fdi_buf;
|
||||||
|
|
||||||
|
@ -2332,7 +2336,7 @@ symlink_info::check (char *path, const suffix_info *suffixes, unsigned opt,
|
||||||
{
|
{
|
||||||
status = NtQueryDirectoryFile (dir, NULL, NULL, NULL, &io,
|
status = NtQueryDirectoryFile (dir, NULL, NULL, NULL, &io,
|
||||||
&fdi_buf, sizeof fdi_buf,
|
&fdi_buf, sizeof fdi_buf,
|
||||||
FileDirectoryInformation,
|
FileBothDirectoryInformation,
|
||||||
TRUE, &basename, TRUE);
|
TRUE, &basename, TRUE);
|
||||||
/* Take the opportunity to check file system while we're
|
/* Take the opportunity to check file system while we're
|
||||||
having the handle to the parent dir. */
|
having the handle to the parent dir. */
|
||||||
|
|
Loading…
Reference in New Issue