* globals.cc (ro_u_nwfs): New R/O unicode string.

* mount.cc (fs_info::update): Check for NWFS filesystem.  Set
	has_buggy_basic_info, if so.  Add comment to explain why.
	(fillout_mntent): Add "nwfs" string to fs_names array.
	* mount.h (enum fs_info_type): Add nwfs.
	(class fs_info): Add has_buggy_basic_info status flag.  Add accessors
	for has_buggy_basic_info and is_nwfs.
	* fhandler_disk_file.cc (fhandler_base::fstat_by_handle): Accommodate
	filesystems with broken FileBasicInformation handling.
	* path.cc (symlink_info::check): Ditto.
	* path.h (path_conv::has_buggy_basic_info): Add method.
This commit is contained in:
Corinna Vinschen 2010-01-12 14:47:46 +00:00
parent 4ee93264fd
commit c04ed45d82
7 changed files with 71 additions and 28 deletions

View File

@ -1,3 +1,17 @@
2010-01-12 Corinna Vinschen <corinna@vinschen.de>
* globals.cc (ro_u_nwfs): New R/O unicode string.
* mount.cc (fs_info::update): Check for NWFS filesystem. Set
has_buggy_basic_info, if so. Add comment to explain why.
(fillout_mntent): Add "nwfs" string to fs_names array.
* mount.h (enum fs_info_type): Add nwfs.
(class fs_info): Add has_buggy_basic_info status flag. Add accessors
for has_buggy_basic_info and is_nwfs.
* fhandler_disk_file.cc (fhandler_base::fstat_by_handle): Accommodate
filesystems with broken FileBasicInformation handling.
* path.cc (symlink_info::check): Ditto.
* path.h (path_conv::has_buggy_basic_info): Add method.
2010-01-12 Corinna Vinschen <corinna@vinschen.de>
* dtable.cc (build_fh_name_worker): Remove. Move all functionality

View File

@ -337,12 +337,25 @@ fhandler_base::fstat_by_handle (struct __stat64 *buf)
than a filename, so it needs a really big buffer for no good reason
since we don't need the name anyway. So we just call the three info
classes necessary to get all information required by stat(2). */
FILE_BASIC_INFORMATION fbi;
union {
FILE_BASIC_INFORMATION fbi;
FILE_NETWORK_OPEN_INFORMATION fnoi;
} fi;
FILE_STANDARD_INFORMATION fsi;
FILE_INTERNAL_INFORMATION fii;
status = NtQueryInformationFile (get_handle (), &io, &fbi, sizeof fbi,
FileBasicInformation);
if (pc.has_buggy_basic_info ())
{
status = NtQueryInformationFile (get_handle (), &io, &fi, sizeof fi,
FileNetworkOpenInformation);
/* The timestamps are in the same relative memory location, only
the DOS attributes have to be moved. */
fi.fbi.FileAttributes = fi.fnoi.FileAttributes;
}
else
status = NtQueryInformationFile (get_handle (), &io, &fi.fbi, sizeof fi.fbi,
FileBasicInformation);
if (!NT_SUCCESS (status))
{
debug_printf ("%p = NtQueryInformationFile(%S, FileBasicInformation)",
@ -369,20 +382,20 @@ fhandler_base::fstat_by_handle (struct __stat64 *buf)
support a change timestamp. In that case use the LastWriteTime
entry, as in other calls to fstat_helper. */
if (pc.is_rep_symlink ())
fbi.FileAttributes &= ~FILE_ATTRIBUTE_DIRECTORY;
pc.file_attributes (fbi.FileAttributes);
fi.fbi.FileAttributes &= ~FILE_ATTRIBUTE_DIRECTORY;
pc.file_attributes (fi.fbi.FileAttributes);
return fstat_helper (buf,
fbi.ChangeTime.QuadPart ? &fbi.ChangeTime
: &fbi.LastWriteTime,
&fbi.LastAccessTime,
&fbi.LastWriteTime,
&fbi.CreationTime,
get_dev (),
fsi.EndOfFile.QuadPart,
fsi.AllocationSize.QuadPart,
fii.FileId.QuadPart,
fsi.NumberOfLinks,
fbi.FileAttributes);
fi.fbi.ChangeTime.QuadPart ? &fi.fbi.ChangeTime
: &fi.fbi.LastWriteTime,
&fi.fbi.LastAccessTime,
&fi.fbi.LastWriteTime,
&fi.fbi.CreationTime,
get_dev (),
fsi.EndOfFile.QuadPart,
fsi.AllocationSize.QuadPart,
fii.FileId.QuadPart,
fsi.NumberOfLinks,
fi.fbi.FileAttributes);
}
int __stdcall

View File

@ -1,7 +1,7 @@
/* globals.cc - Define global variables here.
Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
2006, 2007, 2008, 2009 Red Hat, Inc.
2006, 2007, 2008, 2009, 2010 Red Hat, Inc.
This file is part of Cygwin.
@ -106,6 +106,7 @@ 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");
UNICODE_STRING _RDATA ro_u_nwfs = _ROU (L"NWFS");
UNICODE_STRING _RDATA ro_u_volume = _ROU (L"\\??\\Volume{");
#undef _ROU

View File

@ -1,7 +1,7 @@
/* mount.cc: mount handling.
Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
2006, 2007, 2008, 2009 Red Hat, Inc.
2006, 2007, 2008, 2009, 2010 Red Hat, Inc.
This file is part of Cygwin.
@ -289,6 +289,7 @@ fs_info::update (PUNICODE_STRING upath, HANDLE in_vol)
&& !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_nwfs (RtlEqualUnicodeString (&fsname, &ro_u_nwfs, FALSE))
&& is_cdrom (ffdi.DeviceType == FILE_DEVICE_CD_ROM))
is_udf (RtlEqualUnicodeString (&fsname, &ro_u_udf, FALSE));
if (!got_fs ())
@ -300,8 +301,14 @@ fs_info::update (PUNICODE_STRING upath, HANDLE in_vol)
strlwr (fsn);
}
has_acls (flags () & FS_PERSISTENT_ACLS);
/* Netapp inodes numbers are fly-by-night. */
/* Netapp inode numbers are fly-by-night. */
hasgood_inode ((has_acls () && !is_netapp ()) || is_nfs ());
/* NWFS is known to have a broken FileBasicInformation info class. It
can't be used to fetch information, only to set information. Therefore,
for NWFS we have to fallback to the FileNetworkOpenInformation info
class. Unfortunately we can't use FileNetworkOpenInformation all the
time since that fails on other filesystems like NFS. */
has_buggy_basic_info (is_nwfs ());
/* Case sensitivity is supported if FILE_CASE_SENSITIVE_SEARCH is set,
except on Samba which handles Windows clients case insensitive.
@ -1443,7 +1450,8 @@ fillout_mntent (const char *native_path, const char *posix_path, unsigned flags)
"sunwnfs",
"unixfs",
"mvfs",
"cifs"
"cifs",
"nwfs"
};
if (mntinfo.what_fs () > 0 && mntinfo.what_fs () < max_fs_type)

View File

@ -1,7 +1,7 @@
/* mount.h: mount definitions.
Copyright 1996, 1997, 1998, 2000, 2001, 2002, 2003, 2004, 2005,
2006, 2007, 2008, 2009 Red Hat, Inc.
2006, 2007, 2008, 2009, 2010 Red Hat, Inc.
This file is part of Cygwin.
@ -27,6 +27,7 @@ enum fs_info_type
unixfs,
mvfs,
cifs,
nwfs,
/* Always last. */
max_fs_type
};
@ -49,6 +50,7 @@ class fs_info
unsigned caseinsensitive : 1;
unsigned has_buggy_open : 1;
unsigned has_buggy_fileid_dirinfo : 1;
unsigned has_buggy_basic_info : 1;
} status;
ULONG sernum; /* Volume Serial Number */
char fsn[80]; /* Windows filesystem name */
@ -72,6 +74,7 @@ class fs_info
IMPLEMENT_STATUS_FLAG (bool, caseinsensitive)
IMPLEMENT_STATUS_FLAG (bool, has_buggy_open)
IMPLEMENT_STATUS_FLAG (bool, has_buggy_fileid_dirinfo)
IMPLEMENT_STATUS_FLAG (bool, has_buggy_basic_info)
IMPLEMENT_FS_FLAG (is_fat, fat)
IMPLEMENT_FS_FLAG (is_ntfs, ntfs)
IMPLEMENT_FS_FLAG (is_samba, samba)
@ -84,6 +87,7 @@ class fs_info
IMPLEMENT_FS_FLAG (is_unixfs, unixfs)
IMPLEMENT_FS_FLAG (is_mvfs, mvfs)
IMPLEMENT_FS_FLAG (is_cifs, cifs)
IMPLEMENT_FS_FLAG (is_nwfs, nwfs)
fs_info_type what_fs () const { return status.fs_type; }
ULONG serial_number () const { return sernum; }

View File

@ -2260,9 +2260,16 @@ symlink_info::check (char *path, const suffix_info *suffixes, unsigned opt,
}
}
}
/* Check file system while we're having the file open anyway.
This speeds up path_conv noticably (~10%). */
if (!fs_update_called)
fs.update (&upath, h);
if (NT_SUCCESS (status)
&& NT_SUCCESS (status
= NtQueryInformationFile (h, &io, &fbi, sizeof fbi,
&& NT_SUCCESS (status = fs.has_buggy_basic_info ()
? NtQueryAttributesFile (&attr, &fbi)
: NtQueryInformationFile (h, &io, &fbi, sizeof fbi,
FileBasicInformation)))
fileattr = fbi.FileAttributes;
else
@ -2359,11 +2366,6 @@ symlink_info::check (char *path, const suffix_info *suffixes, unsigned opt,
continue;
}
/* Check file system while we're having the file open anyway.
This speeds up path_conv noticably (~10%). */
if (!fs_update_called)
fs.update (&upath, h);
ext_tacked_on = !!*ext_here;
res = -1;

View File

@ -111,6 +111,7 @@ class path_conv
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 has_buggy_basic_info () const {return fs.has_buggy_basic_info ();}
int binmode () const
{
if (path_flags & PATH_BINARY)