From 6c4b594d8cf7ff3939370db8014be5cec7f4416c Mon Sep 17 00:00:00 2001 From: corinna Date: Thu, 16 Jul 2009 09:56:24 +0000 Subject: [PATCH] * globals.cc: Reorder constant UNICODE_STRINGs for clarity. * mount.h (fs_info::sttaus): Move filesystem type flags into substructure. Add union to allow simple test for having set any one filesystem type flag. Replace has_buggy_open flag with is_sunwnfs flag. Replace has_buggy_fileid_dirinfo with is_unixfs flag. (fs_info::got_fs): New private method. (fs_info::has_buggy_open): New explicit implementation. (fs_info::has_buggy_fileid_dirinfo): Ditto. * mount.cc (fs_info::update): Optimize filesystem checks for speed. * winsup.h (IMPLEMENT_STATUS_FLAG): Change write accessor to return value just set. --- winsup/cygwin/ChangeLog | 14 ++++++++ winsup/cygwin/globals.cc | 11 ++++--- winsup/cygwin/mount.cc | 86 ++++++++++++++++++++---------------------------- winsup/cygwin/mount.h | 36 +++++++++++++------- winsup/cygwin/winsup.h | 2 +- 5 files changed, 81 insertions(+), 68 deletions(-) diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog index d86a2bc456..0a1b4ed2aa 100644 --- a/winsup/cygwin/ChangeLog +++ b/winsup/cygwin/ChangeLog @@ -1,5 +1,19 @@ 2009-07-15 Corinna Vinschen + * globals.cc: Reorder constant UNICODE_STRINGs for clarity. + * mount.h (fs_info::sttaus): Move filesystem type flags into + substructure. Add union to allow simple test for having set any + one filesystem type flag. Replace has_buggy_open flag with is_sunwnfs + flag. Replace has_buggy_fileid_dirinfo with is_unixfs flag. + (fs_info::got_fs): New private method. + (fs_info::has_buggy_open): New explicit implementation. + (fs_info::has_buggy_fileid_dirinfo): Ditto. + * mount.cc (fs_info::update): Optimize filesystem checks for speed. + * winsup.h (IMPLEMENT_STATUS_FLAG): Change write accessor to return + value just set. + +2009-07-15 Corinna Vinschen + * fhandler_netdrive.cc (GET_RESOURCE_INFO): Remove. (thread_netdrive): Drop GET_RESOURCE_INFO case. (fhandler_netdrive::exists): Use GET_RESOURCE_OPENENUM info class diff --git a/winsup/cygwin/globals.cc b/winsup/cygwin/globals.cc index c482fae520..ef17534259 100644 --- a/winsup/cygwin/globals.cc +++ b/winsup/cygwin/globals.cc @@ -84,16 +84,17 @@ UNICODE_STRING _RDATA ro_u_exe = _ROU (L".exe"); UNICODE_STRING _RDATA ro_u_com = _ROU (L".com"); UNICODE_STRING _RDATA ro_u_proc = _ROU (L"proc"); UNICODE_STRING _RDATA ro_u_pmem = _ROU (L"\\device\\physicalmemory"); +UNICODE_STRING _RDATA ro_u_natp = _ROU (L"\\??\\"); +UNICODE_STRING _RDATA ro_u_uncp = _ROU (L"\\??\\UNC\\"); UNICODE_STRING _RDATA ro_u_mtx = _ROU (L"mtx"); -UNICODE_STRING _RDATA ro_u_fat = _ROU (L"FAT"); UNICODE_STRING _RDATA ro_u_csc = _ROU (L"CSC-CACHE"); -UNICODE_STRING _RDATA ro_u_ntfs = _ROU (L"NTFS"); +UNICODE_STRING _RDATA ro_u_fat = _ROU (L"FAT"); +UNICODE_STRING _RDATA ro_u_mvfs = _ROU (L"MVFS"); UNICODE_STRING _RDATA ro_u_nfs = _ROU (L"NFS"); -UNICODE_STRING _RDATA ro_u_unixfs = _ROU (L"UNIXFS"); +UNICODE_STRING _RDATA ro_u_ntfs = _ROU (L"NTFS"); UNICODE_STRING _RDATA ro_u_sunwnfs = _ROU (L"SUNWNFS"); UNICODE_STRING _RDATA ro_u_udf = _ROU (L"UDF"); -UNICODE_STRING _RDATA ro_u_natp = _ROU (L"\\??\\"); -UNICODE_STRING _RDATA ro_u_uncp = _ROU (L"\\??\\UNC\\"); +UNICODE_STRING _RDATA ro_u_unixfs = _ROU (L"UNIXFS"); #undef _RDATA #undef _ROU diff --git a/winsup/cygwin/mount.cc b/winsup/cygwin/mount.cc index 0b87534de7..02c60deec9 100644 --- a/winsup/cygwin/mount.cc +++ b/winsup/cygwin/mount.cc @@ -171,12 +171,10 @@ fs_info::update (PUNICODE_STRING upath, HANDLE in_vol) if (!NT_SUCCESS (status)) ffdi.DeviceType = ffdi.Characteristics = 0; - if (ffdi.Characteristics & FILE_REMOTE_DEVICE + if ((ffdi.Characteristics & FILE_REMOTE_DEVICE) || (!ffdi.DeviceType && RtlEqualUnicodePathPrefix (attr.ObjectName, &ro_u_uncp, TRUE))) is_remote_drive (true); - else - is_remote_drive (false); if (!no_media) status = NtQueryVolumeInformationFile (vol, &io, &ffai_buf.ffai, @@ -217,8 +215,6 @@ fs_info::update (PUNICODE_STRING upath, HANDLE in_vol) | FILE_NAMED_STREAMS) RtlInitCountedUnicodeString (&fsname, ffai_buf.ffai.FileSystemName, ffai_buf.ffai.FileSystemNameLength); - is_fat (RtlEqualUnicodePathPrefix (&fsname, &ro_u_fat, TRUE)); - is_csc_cache (RtlEqualUnicodeString (&fsname, &ro_u_csc, FALSE)); if (is_remote_drive ()) { /* This always fails on NT4. */ @@ -234,40 +230,44 @@ fs_info::update (PUNICODE_STRING upath, HANDLE in_vol) samba_version (extended_info->samba_version); } } - /* Test for Samba on NT4 or for older Samba releases not supporting - extended info. */ - if (!is_samba ()) - is_samba (RtlEqualUnicodeString (&fsname, &ro_u_ntfs, FALSE) - && FS_IS_SAMBA); - - if (!is_samba ()) - { - is_netapp (RtlEqualUnicodeString (&fsname, &ro_u_ntfs, FALSE) - && FS_IS_NETAPP_DATAONTAP); - - is_nfs (RtlEqualUnicodeString (&fsname, &ro_u_nfs, FALSE)); - - if (!is_nfs ()) - { - /* Known remote file systems which can't handle calls to - NtQueryDirectoryFile(FileIdBothDirectoryInformation) */ - has_buggy_fileid_dirinfo (RtlEqualUnicodeString (&fsname, - &ro_u_unixfs, - FALSE)); - - /* Known remote file systems with buggy open calls. Further - explanation in fhandler.cc (fhandler_disk_file::open). */ - has_buggy_open (RtlEqualUnicodeString (&fsname, &ro_u_sunwnfs, - FALSE)); - } - } + if (!got_fs () + /* Test for Samba on NT4 or for older Samba releases not supporting + extended info. */ + && !is_samba (RtlEqualUnicodeString (&fsname, &ro_u_ntfs, FALSE) + && FS_IS_SAMBA) + /* Netapp inode info is unusable. */ + && !is_netapp (RtlEqualUnicodeString (&fsname, &ro_u_ntfs, FALSE) + && FS_IS_NETAPP_DATAONTAP) + /* Microsoft NFS needs distinct access methods for metadata. */ + && !is_nfs (RtlEqualUnicodeString (&fsname, &ro_u_nfs, FALSE)) + /* Known remote file system which can't handle calls to + NtQueryDirectoryFile(FileIdBothDirectoryInformation) */ + && !is_unixfs (RtlEqualUnicodeString (&fsname, &ro_u_unixfs, FALSE))) + /* Known remote file system with buggy open calls. Further + explanation in fhandler.cc (fhandler_disk_file::open). */ + is_sunwnfs (RtlEqualUnicodeString (&fsname, &ro_u_sunwnfs, FALSE)); + } + if (!got_fs () + && !is_ntfs (RtlEqualUnicodeString (&fsname, &ro_u_ntfs, FALSE)) + && !is_fat (RtlEqualUnicodePathPrefix (&fsname, &ro_u_fat, TRUE)) + && !is_csc_cache (RtlEqualUnicodeString (&fsname, &ro_u_csc, FALSE)) + && is_cdrom (ffdi.DeviceType == FILE_DEVICE_CD_ROM)) + { + is_udf (RtlEqualUnicodeString (&fsname, &ro_u_udf, FALSE)); + /* UDF on NT 5.x is broken (at least) in terms of case sensitivity. + The UDF driver reports the FILE_CASE_SENSITIVE_SEARCH capability + but: + - Opening the root directory for query seems to work at first, + but the filenames in the directory listing are mutilated. + - When trying to open a file or directory case sensitive, the file + appears to be non-existant. */ + if (is_udf () && wincap.has_broken_udf ()) + caseinsensitive (true); } - is_ntfs (RtlEqualUnicodeString (&fsname, &ro_u_ntfs, FALSE) - && !is_samba () && !is_netapp ()); has_acls (flags () & FS_PERSISTENT_ACLS); - hasgood_inode (((flags () & FILE_PERSISTENT_ACLS) && !is_netapp ()) - || is_nfs ()); + /* Netapp inodes numbers are fly-by-night. */ + hasgood_inode ((has_acls () && !is_netapp ()) || is_nfs ()); /* Case sensitivity is supported if FILE_CASE_SENSITIVE_SEARCH is set, except on Samba which handles Windows clients case insensitive. NFS doesn't set the FILE_CASE_SENSITIVE_SEARCH flag but is case @@ -275,20 +275,6 @@ fs_info::update (PUNICODE_STRING upath, HANDLE in_vol) caseinsensitive ((!(flags () & FILE_CASE_SENSITIVE_SEARCH) || is_samba ()) && !is_nfs ()); - is_cdrom (ffdi.DeviceType == FILE_DEVICE_CD_ROM); - if (is_cdrom ()) - { - is_udf (RtlEqualUnicodeString (&fsname, &ro_u_udf, FALSE)); - /* UDF on NT 5.x is broken (at least) in terms of case sensitivity. The - UDF driver reports the FILE_CASE_SENSITIVE_SEARCH capability but: - - Opening the root directory for query seems to work at first, but the - filenames in the directory listing are mutilated. - - When trying to open a file or directory case sensitive, the file - appears to be non-existant. */ - if (is_udf () && wincap.has_broken_udf ()) - caseinsensitive (true); - } - if (!in_vol) NtClose (vol); return true; diff --git a/winsup/cygwin/mount.h b/winsup/cygwin/mount.h index 9836636c7b..bc6de12b03 100644 --- a/winsup/cygwin/mount.h +++ b/winsup/cygwin/mount.h @@ -20,21 +20,30 @@ class fs_info ULONG samba_version; /* Samba version if available */ ULONG name_len; /* MaximumComponentNameLength */ unsigned is_remote_drive : 1; - unsigned has_buggy_open : 1; - unsigned has_buggy_fileid_dirinfo : 1; unsigned has_acls : 1; unsigned hasgood_inode : 1; unsigned caseinsensitive : 1; - unsigned is_fat : 1; - unsigned is_ntfs : 1; - unsigned is_samba : 1; - unsigned is_nfs : 1; - unsigned is_netapp : 1; - unsigned is_cdrom : 1; - unsigned is_udf : 1; - unsigned is_csc_cache : 1; + union + { + struct + { + unsigned is_fat : 1; + unsigned is_ntfs : 1; + unsigned is_samba : 1; + unsigned is_nfs : 1; + unsigned is_netapp : 1; + unsigned is_cdrom : 1; + unsigned is_udf : 1; + unsigned is_csc_cache : 1; + unsigned is_sunwnfs : 1; + unsigned is_unixfs : 1; + }; + unsigned long fs_flags; + }; } status; ULONG sernum; + unsigned long got_fs () { return status.fs_flags; } + public: void clear () { memset (&status, 0 , sizeof status); sernum = 0UL; } fs_info () { clear (); } @@ -43,8 +52,6 @@ class fs_info IMPLEMENT_STATUS_FLAG (ULONG, samba_version) IMPLEMENT_STATUS_FLAG (ULONG, name_len) IMPLEMENT_STATUS_FLAG (bool, is_remote_drive) - IMPLEMENT_STATUS_FLAG (bool, has_buggy_open) - IMPLEMENT_STATUS_FLAG (bool, has_buggy_fileid_dirinfo) IMPLEMENT_STATUS_FLAG (bool, has_acls) IMPLEMENT_STATUS_FLAG (bool, hasgood_inode) IMPLEMENT_STATUS_FLAG (bool, caseinsensitive) @@ -56,8 +63,13 @@ class fs_info IMPLEMENT_STATUS_FLAG (bool, is_cdrom) IMPLEMENT_STATUS_FLAG (bool, is_udf) IMPLEMENT_STATUS_FLAG (bool, is_csc_cache) + IMPLEMENT_STATUS_FLAG (bool, is_sunwnfs) + IMPLEMENT_STATUS_FLAG (bool, is_unixfs) ULONG serial_number () const { return sernum; } + int has_buggy_open () const {return is_sunwnfs ();} + int has_buggy_fileid_dirinfo () const {return is_unixfs ();} + bool update (PUNICODE_STRING, HANDLE) __attribute__ ((regparm (3))); }; diff --git a/winsup/cygwin/winsup.h b/winsup/cygwin/winsup.h index 91634dc132..7f0377ef8e 100644 --- a/winsup/cygwin/winsup.h +++ b/winsup/cygwin/winsup.h @@ -124,7 +124,7 @@ extern int cygserver_running; /* Used to define status flag accessor methods */ #define IMPLEMENT_STATUS_FLAG(type,flag) \ - void flag (type val) { status.flag = (val); } \ + type flag (type val) { return (type) (status.flag = (val)); } \ type flag () const { return (type) status.flag; } /* Used when treating / and \ as equivalent. */ -- 2.11.0