* 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.
This commit is contained in:
Corinna Vinschen 2009-07-16 09:56:25 +00:00
parent 5e5a843711
commit fc261e53f0
5 changed files with 84 additions and 71 deletions

View File

@ -1,3 +1,17 @@
2009-07-15 Corinna Vinschen <corinna@vinschen.de>
* 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 <corinna@vinschen.de>
* fhandler_netdrive.cc (GET_RESOURCE_INFO): Remove.

View File

@ -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_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_nfs = _ROU (L"NFS");
UNICODE_STRING _RDATA ro_u_unixfs = _ROU (L"UNIXFS");
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_mtx = _ROU (L"mtx");
UNICODE_STRING _RDATA ro_u_csc = _ROU (L"CSC-CACHE");
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_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_unixfs = _ROU (L"UNIXFS");
#undef _RDATA
#undef _ROU

View File

@ -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;

View File

@ -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)));
};

View File

@ -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. */