* fhandler_procsys.cc (fhandler_procsys::readdir): Just test
ObjectTypeName for object types rather than calling lstat to avoid performance hit. * globals.cc (ro_u_natdir): Define. (ro_u_natsyml): Define. (ro_u_natdev): Define.
This commit is contained in:
parent
50f799240e
commit
f49469bb1e
@ -1,3 +1,12 @@
|
|||||||
|
2014-10-09 Corinna Vinschen <corinna@vinschen.de>
|
||||||
|
|
||||||
|
* fhandler_procsys.cc (fhandler_procsys::readdir): Just test
|
||||||
|
ObjectTypeName for object types rather than calling lstat to avoid
|
||||||
|
performance hit.
|
||||||
|
* globals.cc (ro_u_natdir): Define.
|
||||||
|
(ro_u_natsyml): Define.
|
||||||
|
(ro_u_natdev): Define.
|
||||||
|
|
||||||
2014-10-09 Corinna Vinschen <corinna@vinschen.de>
|
2014-10-09 Corinna Vinschen <corinna@vinschen.de>
|
||||||
|
|
||||||
* fhandler_disk_file.cc (fhandler_disk_file::readdir_helper): Set d_type
|
* fhandler_disk_file.cc (fhandler_disk_file::readdir_helper): Set d_type
|
||||||
|
@ -177,30 +177,28 @@ fhandler_procsys::exists (struct stat *buf)
|
|||||||
/* Don't call NtQueryInformationFile unless we know it's a safe type.
|
/* Don't call NtQueryInformationFile unless we know it's a safe type.
|
||||||
The call is known to crash machines, if the underlying driver is
|
The call is known to crash machines, if the underlying driver is
|
||||||
badly written. */
|
badly written. */
|
||||||
if (!NT_SUCCESS (status))
|
if (NT_SUCCESS (status))
|
||||||
{
|
{
|
||||||
NtClose (h);
|
if (ffdi.DeviceType == FILE_DEVICE_NETWORK_FILE_SYSTEM)
|
||||||
return file_type;
|
|
||||||
}
|
|
||||||
if (ffdi.DeviceType == FILE_DEVICE_NETWORK_FILE_SYSTEM)
|
|
||||||
file_type = virt_blk;
|
|
||||||
else if (ffdi.DeviceType == FILE_DEVICE_NAMED_PIPE)
|
|
||||||
file_type = internal ? virt_blk : virt_pipe;
|
|
||||||
else if (ffdi.DeviceType == FILE_DEVICE_DISK
|
|
||||||
|| ffdi.DeviceType == FILE_DEVICE_CD_ROM
|
|
||||||
|| ffdi.DeviceType == FILE_DEVICE_DFS
|
|
||||||
|| ffdi.DeviceType == FILE_DEVICE_VIRTUAL_DISK)
|
|
||||||
{
|
|
||||||
/* Check for file attributes. If we get them, we peeked
|
|
||||||
into a real FS through /proc/sys. */
|
|
||||||
status = NtQueryInformationFile (h, &io, &fbi, sizeof fbi,
|
|
||||||
FileBasicInformation);
|
|
||||||
debug_printf ("NtQueryInformationFile: %y", status);
|
|
||||||
if (!NT_SUCCESS (status))
|
|
||||||
file_type = virt_blk;
|
file_type = virt_blk;
|
||||||
else
|
else if (ffdi.DeviceType == FILE_DEVICE_NAMED_PIPE)
|
||||||
file_type = (fbi.FileAttributes & FILE_ATTRIBUTE_DIRECTORY)
|
file_type = internal ? virt_blk : virt_pipe;
|
||||||
? virt_fsdir : virt_fsfile;
|
else if (ffdi.DeviceType == FILE_DEVICE_DISK
|
||||||
|
|| ffdi.DeviceType == FILE_DEVICE_CD_ROM
|
||||||
|
|| ffdi.DeviceType == FILE_DEVICE_DFS
|
||||||
|
|| ffdi.DeviceType == FILE_DEVICE_VIRTUAL_DISK)
|
||||||
|
{
|
||||||
|
/* Check for file attributes. If we get them, we peeked
|
||||||
|
into a real FS through /proc/sys. */
|
||||||
|
status = NtQueryInformationFile (h, &io, &fbi, sizeof fbi,
|
||||||
|
FileBasicInformation);
|
||||||
|
debug_printf ("NtQueryInformationFile: %y", status);
|
||||||
|
if (!NT_SUCCESS (status))
|
||||||
|
file_type = virt_blk;
|
||||||
|
else
|
||||||
|
file_type = (fbi.FileAttributes & FILE_ATTRIBUTE_DIRECTORY)
|
||||||
|
? virt_fsdir : virt_fsfile;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
NtClose (h);
|
NtClose (h);
|
||||||
}
|
}
|
||||||
@ -346,7 +344,6 @@ fhandler_procsys::readdir (DIR *dir, dirent *de)
|
|||||||
WCHAR buf[2][NAME_MAX + 1];
|
WCHAR buf[2][NAME_MAX + 1];
|
||||||
} f;
|
} f;
|
||||||
int res = EBADF;
|
int res = EBADF;
|
||||||
tmp_pathbuf tp;
|
|
||||||
|
|
||||||
if (dir->__handle != INVALID_HANDLE_VALUE)
|
if (dir->__handle != INVALID_HANDLE_VALUE)
|
||||||
{
|
{
|
||||||
@ -358,16 +355,19 @@ fhandler_procsys::readdir (DIR *dir, dirent *de)
|
|||||||
res = ENMFILE;
|
res = ENMFILE;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
struct stat st;
|
|
||||||
char *file = tp.c_get ();
|
|
||||||
|
|
||||||
sys_wcstombs (de->d_name, NAME_MAX + 1, f.dbi.ObjectName.Buffer,
|
sys_wcstombs (de->d_name, NAME_MAX + 1, f.dbi.ObjectName.Buffer,
|
||||||
f.dbi.ObjectName.Length / sizeof (WCHAR));
|
f.dbi.ObjectName.Length / sizeof (WCHAR));
|
||||||
de->d_ino = hash_path_name (get_ino (), de->d_name);
|
de->d_ino = hash_path_name (get_ino (), de->d_name);
|
||||||
stpcpy (stpcpy (stpcpy (file, get_name ()), "/"), de->d_name);
|
if (RtlEqualUnicodeString (&f.dbi.ObjectTypeName, &ro_u_natdir,
|
||||||
if (!lstat64 (file, &st))
|
FALSE))
|
||||||
de->d_type = IFTODT (st.st_mode);
|
de->d_type = DT_DIR;
|
||||||
else
|
else if (RtlEqualUnicodeString (&f.dbi.ObjectTypeName, &ro_u_natsyml,
|
||||||
|
FALSE))
|
||||||
|
de->d_type = DT_LNK;
|
||||||
|
else if (!RtlEqualUnicodeString (&f.dbi.ObjectTypeName, &ro_u_natdev,
|
||||||
|
FALSE))
|
||||||
|
de->d_type = DT_CHR;
|
||||||
|
else /* Can't nail down "Device" objects without further testing. */
|
||||||
de->d_type = DT_UNKNOWN;
|
de->d_type = DT_UNKNOWN;
|
||||||
res = 0;
|
res = 0;
|
||||||
}
|
}
|
||||||
|
@ -148,6 +148,9 @@ extern "C" {
|
|||||||
extern UNICODE_STRING _RDATA ro_u_pipedir = _ROU (L"\\\\?\\PIPE\\");
|
extern UNICODE_STRING _RDATA ro_u_pipedir = _ROU (L"\\\\?\\PIPE\\");
|
||||||
extern UNICODE_STRING _RDATA ro_u_globalroot = _ROU (L"\\\\.\\GLOBALROOT");
|
extern UNICODE_STRING _RDATA ro_u_globalroot = _ROU (L"\\\\.\\GLOBALROOT");
|
||||||
extern UNICODE_STRING _RDATA ro_u_null = _ROU (L"\\Device\\Null");
|
extern UNICODE_STRING _RDATA ro_u_null = _ROU (L"\\Device\\Null");
|
||||||
|
extern UNICODE_STRING _RDATA ro_u_natdir = _ROU (L"Directory");
|
||||||
|
extern UNICODE_STRING _RDATA ro_u_natsyml = _ROU (L"SymbolicLink");
|
||||||
|
extern UNICODE_STRING _RDATA ro_u_natdev = _ROU (L"Device");
|
||||||
#undef _ROU
|
#undef _ROU
|
||||||
|
|
||||||
/* Cygwin properties are meant to be readonly data placed in the DLL, but
|
/* Cygwin properties are meant to be readonly data placed in the DLL, but
|
||||||
|
Loading…
x
Reference in New Issue
Block a user