* 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.
This commit is contained in:
Corinna Vinschen 2008-07-30 14:41:59 +00:00
parent b54881352d
commit d79a78e5c8
4 changed files with 58 additions and 25 deletions

View File

@ -1,3 +1,19 @@
2008-07-30 Corinna Vinschen <corinna@vinschen.de>
* 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 <corinna@vinschen.de>
* sec_auth.cc (extract_nt_dom_user): Return domain and user name as

View File

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

View File

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

View File

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