* 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:
Corinna Vinschen 2014-10-09 17:45:27 +00:00
parent 50f799240e
commit f49469bb1e
3 changed files with 42 additions and 30 deletions

View File

@ -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>
* fhandler_disk_file.cc (fhandler_disk_file::readdir_helper): Set d_type

View File

@ -177,30 +177,28 @@ fhandler_procsys::exists (struct stat *buf)
/* Don't call NtQueryInformationFile unless we know it's a safe type.
The call is known to crash machines, if the underlying driver is
badly written. */
if (!NT_SUCCESS (status))
if (NT_SUCCESS (status))
{
NtClose (h);
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))
if (ffdi.DeviceType == FILE_DEVICE_NETWORK_FILE_SYSTEM)
file_type = virt_blk;
else
file_type = (fbi.FileAttributes & FILE_ATTRIBUTE_DIRECTORY)
? virt_fsdir : virt_fsfile;
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;
else
file_type = (fbi.FileAttributes & FILE_ATTRIBUTE_DIRECTORY)
? virt_fsdir : virt_fsfile;
}
}
NtClose (h);
}
@ -346,7 +344,6 @@ fhandler_procsys::readdir (DIR *dir, dirent *de)
WCHAR buf[2][NAME_MAX + 1];
} f;
int res = EBADF;
tmp_pathbuf tp;
if (dir->__handle != INVALID_HANDLE_VALUE)
{
@ -358,16 +355,19 @@ fhandler_procsys::readdir (DIR *dir, dirent *de)
res = ENMFILE;
else
{
struct stat st;
char *file = tp.c_get ();
sys_wcstombs (de->d_name, NAME_MAX + 1, f.dbi.ObjectName.Buffer,
f.dbi.ObjectName.Length / sizeof (WCHAR));
de->d_ino = hash_path_name (get_ino (), de->d_name);
stpcpy (stpcpy (stpcpy (file, get_name ()), "/"), de->d_name);
if (!lstat64 (file, &st))
de->d_type = IFTODT (st.st_mode);
else
if (RtlEqualUnicodeString (&f.dbi.ObjectTypeName, &ro_u_natdir,
FALSE))
de->d_type = DT_DIR;
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;
res = 0;
}

View File

@ -148,6 +148,9 @@ extern "C" {
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_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
/* Cygwin properties are meant to be readonly data placed in the DLL, but