diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog index 8a84c10c0..c961944a4 100644 --- a/winsup/cygwin/ChangeLog +++ b/winsup/cygwin/ChangeLog @@ -1,3 +1,19 @@ +2008-07-30 Corinna Vinschen + + * fhandler_disk_file.cc (fhandler_base::fstat_by_name): Check for + file systems incapable of handling FileIdBothDirectoryInformation + correctly. + (fhandler_disk_file::opendir): Ditto. + * path.cc (fs_info::update): Always clear at the start. + Rearrange to make certain tests only on non-Samba, non-NFS remote + drives. + Add test for file systems known to be incapable of handling + FileIdBothDirectoryInformation correctly. Right now that's just + "UNIXFS". + * path.h (struct fs_info): Add has_buggy_fileid_dirinfo flag and + accessor methods. + (class path_conv): Add has_buggy_fileid_dirinfo method. + 2008-07-30 Corinna Vinschen * sec_auth.cc (extract_nt_dom_user): Return domain and user name as diff --git a/winsup/cygwin/fhandler_disk_file.cc b/winsup/cygwin/fhandler_disk_file.cc index be098ead9..de2b0d06e 100644 --- a/winsup/cygwin/fhandler_disk_file.cc +++ b/winsup/cygwin/fhandler_disk_file.cc @@ -390,7 +390,7 @@ fhandler_base::fstat_by_name (struct __stat64 *buf) debug_printf ("%p = NtOpenFile(%S)", status, pc.get_nt_native_path ()); goto too_bad; } - if (wincap.has_fileid_dirinfo () + if (wincap.has_fileid_dirinfo () && !pc.has_buggy_fileid_dirinfo () && NT_SUCCESS (status = NtQueryDirectoryFile (dir, NULL, NULL, 0, &io, &fdi_buf.fdi, sizeof fdi_buf, FileIdBothDirectoryInformation, @@ -1574,7 +1574,8 @@ fhandler_disk_file::opendir (int fd) dir->__flags |= dirent_set_d_ino; if (pc.fs_is_nfs ()) dir->__flags |= dirent_nfs_d_ino; - else if (wincap.has_fileid_dirinfo ()) + else if (wincap.has_fileid_dirinfo () + && !pc.has_buggy_fileid_dirinfo ()) dir->__flags |= dirent_get_d_ino; } } diff --git a/winsup/cygwin/path.cc b/winsup/cygwin/path.cc index 4729bc999..66e174771 100644 --- a/winsup/cygwin/path.cc +++ b/winsup/cygwin/path.cc @@ -389,6 +389,7 @@ fs_info::update (PUNICODE_STRING upath, HANDLE in_vol) } ffvi_buf; UNICODE_STRING fsname, testname; + clear (); if (in_vol) vol = in_vol; else @@ -420,7 +421,6 @@ fs_info::update (PUNICODE_STRING upath, HANDLE in_vol) { debug_printf ("Cannot access path %S, status %08lx", attr.ObjectName, status); - clear (); NtClose (vol); return false; } @@ -450,8 +450,6 @@ fs_info::update (PUNICODE_STRING upath, HANDLE in_vol) { debug_printf ("Cannot get volume attributes (%S), %08lx", attr.ObjectName, status); - has_buggy_open (false); - flags (0); if (!in_vol) NtClose (vol); return false; @@ -506,23 +504,38 @@ fs_info::update (PUNICODE_STRING upath, HANDLE in_vol) is_samba (RtlEqualUnicodeString (&fsname, &testname, FALSE) && FS_IS_SAMBA); - is_netapp (!is_samba () - && RtlEqualUnicodeString (&fsname, &testname, FALSE) - && FS_IS_NETAPP_DATAONTAP); + if (!is_samba ()) + { + is_netapp (RtlEqualUnicodeString (&fsname, &testname, FALSE) + && FS_IS_NETAPP_DATAONTAP); + + RtlInitUnicodeString (&testname, L"NFS"); + is_nfs (RtlEqualUnicodeString (&fsname, &testname, FALSE)); + + if (!is_nfs ()) + { + /* Known remote file systems which can't handle calls to + NtQueryDirectoryFile(FileIdBothDirectoryInformation) */ + RtlInitUnicodeString (&testname, L"UNIXFS"); + has_buggy_fileid_dirinfo (RtlEqualUnicodeString (&fsname, + &testname, + FALSE)); + + /* Known remote file systems with buggy open calls. Further + explanation in fhandler.cc (fhandler_disk_file::open). */ + RtlInitUnicodeString (&testname, L"SUNWNFS"); + has_buggy_open (RtlEqualUnicodeString (&fsname, &testname, + FALSE)); + } + } } is_ntfs (RtlEqualUnicodeString (&fsname, &testname, FALSE) && !is_samba () && !is_netapp ()); - RtlInitUnicodeString (&testname, L"NFS"); - is_nfs (RtlEqualUnicodeString (&fsname, &testname, FALSE)); is_cdrom (ffdi.DeviceType == FILE_DEVICE_CD_ROM); has_acls (flags () & FS_PERSISTENT_ACLS); hasgood_inode (((flags () & FILE_PERSISTENT_ACLS) && !is_netapp ()) || is_nfs ()); - /* Known file systems with buggy open calls. Further explanation - in fhandler.cc (fhandler_disk_file::open). */ - RtlInitUnicodeString (&testname, L"SUNWNFS"); - has_buggy_open (RtlEqualUnicodeString (&fsname, &testname, FALSE)); /* 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 diff --git a/winsup/cygwin/path.h b/winsup/cygwin/path.h index a9f0cc32f..4c6f5cba1 100644 --- a/winsup/cygwin/path.h +++ b/winsup/cygwin/path.h @@ -91,17 +91,18 @@ struct fs_info ULONG flags; /* Volume flags */ ULONG samba_version; /* Samba version if available */ ULONG name_len; /* MaximumComponentNameLength */ - unsigned is_remote_drive : 1; - unsigned has_buggy_open : 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_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; } status; ULONG sernum; public: @@ -113,6 +114,7 @@ struct fs_info 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) @@ -149,6 +151,7 @@ class path_conv bool isgood_inode (__ino64_t ino) const; int has_symlinks () const {return path_flags & PATH_HAS_SYMLINKS;} int has_buggy_open () const {return fs.has_buggy_open ();} + int has_buggy_fileid_dirinfo () const {return fs.has_buggy_fileid_dirinfo ();} int binmode () const { if (path_flags & PATH_BINARY)