summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorCorinna Vinschen <corinna@vinschen.de>2008-05-21 10:23:19 +0000
committerCorinna Vinschen <corinna@vinschen.de>2008-05-21 10:23:19 +0000
commit380b8bac123f819fb24eccbea12c23b88a5d12b7 (patch)
tree5ed18999a0278e5a38fbcdd7cb52856037706eae
parent0d3f3658816a3759e608d6b944bb22ad194f389c (diff)
downloadcygnal-380b8bac123f819fb24eccbea12c23b88a5d12b7.tar.gz
cygnal-380b8bac123f819fb24eccbea12c23b88a5d12b7.tar.bz2
cygnal-380b8bac123f819fb24eccbea12c23b88a5d12b7.zip
* fhandler_disk_file.cc (get_ino_by_handle): Rename pfai to fai.
(fhandler_base::fstat_by_handle): Drop fai_size and pfai in favor of static struct fai_buf. Restructure. (fhandler_base::fstat_by_name): Drop fvi_size and pfvi. Drop fdi_size and pfdi in favor of static struct fdi_buf. Drop redundant test for existance. Use FileDirectoryInformation class instead of FileBothDirectoryInformation. Drop call to NtQueryVolumeInformationFile in favor of using pc.fs_serial_number (). Fix FileId information given to fstat_helper. (fhandler_disk_file::fstatvfs): Drop fvi_size, pfvi, fai_size and pfai. Drop getting FileFsVolumeInformation and FileFsAttributeInformation in favor of using the related path_conv info. (fhandler_disk_file::opendir): Fix comment. (fhandler_disk_file::readdir): Ditto. Use FileDirectoryInformation class instead of FileBothDirectoryInformation. * path.cc (fs_info::update): Store MaximumComponentNameLength in new member name_len. * path.h (struct fs_info): Use ULONG rather than DWORD. Add member name_len to store MaximumComponentNameLength. Add accessor methods. (path_conv::fs_name_len): New method.
-rw-r--r--winsup/cygwin/ChangeLog23
-rw-r--r--winsup/cygwin/fhandler_disk_file.cc185
-rw-r--r--winsup/cygwin/path.cc1
-rw-r--r--winsup/cygwin/path.h11
4 files changed, 103 insertions, 117 deletions
diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog
index 499495e78..98d189d52 100644
--- a/winsup/cygwin/ChangeLog
+++ b/winsup/cygwin/ChangeLog
@@ -1,5 +1,28 @@
2008-05-21 Corinna Vinschen <corinna@vinschen.de>
+ * fhandler_disk_file.cc (get_ino_by_handle): Rename pfai to fai.
+ (fhandler_base::fstat_by_handle): Drop fai_size and pfai in favor of
+ static struct fai_buf. Restructure.
+ (fhandler_base::fstat_by_name): Drop fvi_size and pfvi. Drop fdi_size
+ and pfdi in favor of static struct fdi_buf. Drop redundant test for
+ existance. Use FileDirectoryInformation class instead of
+ FileBothDirectoryInformation. Drop call to NtQueryVolumeInformationFile
+ in favor of using pc.fs_serial_number (). Fix FileId information given
+ to fstat_helper.
+ (fhandler_disk_file::fstatvfs): Drop fvi_size, pfvi, fai_size and pfai.
+ Drop getting FileFsVolumeInformation and FileFsAttributeInformation in
+ favor of using the related path_conv info.
+ (fhandler_disk_file::opendir): Fix comment.
+ (fhandler_disk_file::readdir): Ditto. Use FileDirectoryInformation
+ class instead of FileBothDirectoryInformation.
+ * path.cc (fs_info::update): Store MaximumComponentNameLength in new
+ member name_len.
+ * path.h (struct fs_info): Use ULONG rather than DWORD. Add member
+ name_len to store MaximumComponentNameLength. Add accessor methods.
+ (path_conv::fs_name_len): New method.
+
+2008-05-21 Corinna Vinschen <corinna@vinschen.de>
+
* fhandler.h (dirent_states): Add dirent_nfs_d_ino state and add it to
dirent_info_mask.
* fhandler_disk_file.cc (fhandler_disk_file::opendir): Set
diff --git a/winsup/cygwin/fhandler_disk_file.cc b/winsup/cygwin/fhandler_disk_file.cc
index a8558a700..56f6809b9 100644
--- a/winsup/cygwin/fhandler_disk_file.cc
+++ b/winsup/cygwin/fhandler_disk_file.cc
@@ -168,11 +168,11 @@ static inline __ino64_t
get_ino_by_handle (HANDLE hdl)
{
IO_STATUS_BLOCK io;
- FILE_INTERNAL_INFORMATION pfai;
+ FILE_INTERNAL_INFORMATION fai;
- if (NT_SUCCESS (NtQueryInformationFile (hdl, &io, &pfai, sizeof pfai,
+ if (NT_SUCCESS (NtQueryInformationFile (hdl, &io, &fai, sizeof fai,
FileInternalInformation)))
- return pfai.FileId.QuadPart;
+ return fai.FileId.QuadPart;
return 0;
}
@@ -329,38 +329,38 @@ fhandler_base::fstat_by_handle (struct __stat64 *buf)
if (pc.fs_is_nfs ())
return fstat_by_nfs_ea (buf);
- /* The entries potentially contain a name of MAX_PATH wide characters. */
- const DWORD fai_size = (NAME_MAX + 1) * sizeof (WCHAR)
- + sizeof (FILE_ALL_INFORMATION);
- PFILE_ALL_INFORMATION pfai = (PFILE_ALL_INFORMATION) alloca (fai_size);
+ struct {
+ FILE_ALL_INFORMATION fai;
+ WCHAR buf[NAME_MAX + 1];
+ } fai_buf;
- status = NtQueryInformationFile (get_handle (), &io, pfai, fai_size,
- FileAllInformation);
- if (NT_SUCCESS (status))
+ status = NtQueryInformationFile (get_handle (), &io, &fai_buf.fai,
+ sizeof fai_buf, FileAllInformation);
+ if (!NT_SUCCESS (status))
{
- /* If the change time is 0, it's a file system which doesn't
- support a change timestamp. In that case use the LastWriteTime
- entry, as in other calls to fstat_helper. */
- if (pc.is_rep_symlink ())
- pfai->BasicInformation.FileAttributes &= ~FILE_ATTRIBUTE_DIRECTORY;
- pc.file_attributes (pfai->BasicInformation.FileAttributes);
- return fstat_helper (buf,
- pfai->BasicInformation.ChangeTime.QuadPart
- ? *(FILETIME *) &pfai->BasicInformation.ChangeTime
- : *(FILETIME *) &pfai->BasicInformation.LastWriteTime,
- *(FILETIME *) &pfai->BasicInformation.LastAccessTime,
- *(FILETIME *) &pfai->BasicInformation.LastWriteTime,
- *(FILETIME *) &pfai->BasicInformation.CreationTime,
- get_dev (),
- pfai->StandardInformation.EndOfFile.QuadPart,
- pfai->StandardInformation.AllocationSize.QuadPart,
- pfai->InternalInformation.FileId.QuadPart,
- pfai->StandardInformation.NumberOfLinks,
- pfai->BasicInformation.FileAttributes);
- }
- debug_printf ("%p = NtQueryInformationFile(%S)",
- status, pc.get_nt_native_path ());
- return -1;
+ debug_printf ("%p = NtQueryInformationFile(%S)",
+ status, pc.get_nt_native_path ());
+ return -1;
+ }
+ /* If the change time is 0, it's a file system which doesn't
+ support a change timestamp. In that case use the LastWriteTime
+ entry, as in other calls to fstat_helper. */
+ if (pc.is_rep_symlink ())
+ fai_buf.fai.BasicInformation.FileAttributes &= ~FILE_ATTRIBUTE_DIRECTORY;
+ pc.file_attributes (fai_buf.fai.BasicInformation.FileAttributes);
+ return fstat_helper (buf,
+ fai_buf.fai.BasicInformation.ChangeTime.QuadPart
+ ? *(FILETIME *) &fai_buf.fai.BasicInformation.ChangeTime
+ : *(FILETIME *) &fai_buf.fai.BasicInformation.LastWriteTime,
+ *(FILETIME *) &fai_buf.fai.BasicInformation.LastAccessTime,
+ *(FILETIME *) &fai_buf.fai.BasicInformation.LastWriteTime,
+ *(FILETIME *) &fai_buf.fai.BasicInformation.CreationTime,
+ get_dev (),
+ fai_buf.fai.StandardInformation.EndOfFile.QuadPart,
+ fai_buf.fai.StandardInformation.AllocationSize.QuadPart,
+ fai_buf.fai.InternalInformation.FileId.QuadPart,
+ fai_buf.fai.StandardInformation.NumberOfLinks,
+ fai_buf.fai.BasicInformation.FileAttributes);
}
int __stdcall
@@ -372,22 +372,12 @@ fhandler_base::fstat_by_name (struct __stat64 *buf)
UNICODE_STRING dirname;
UNICODE_STRING basename;
HANDLE dir;
- const DWORD fdi_size = (NAME_MAX + 1) * sizeof (WCHAR)
- + sizeof (FILE_ID_BOTH_DIR_INFORMATION);
- const DWORD fvi_size = (NAME_MAX + 1) * sizeof (WCHAR)
- + sizeof (FILE_FS_VOLUME_INFORMATION);
- PFILE_ID_BOTH_DIR_INFORMATION pfdi = (PFILE_ID_BOTH_DIR_INFORMATION)
- alloca (fdi_size);
- PFILE_FS_VOLUME_INFORMATION pfvi = (PFILE_FS_VOLUME_INFORMATION)
- alloca (fvi_size);
+ struct {
+ FILE_ID_BOTH_DIR_INFORMATION fdi;
+ WCHAR buf[NAME_MAX + 1];
+ } fdi_buf;
LARGE_INTEGER FileId;
- if (!pc.exists ())
- {
- debug_printf ("already determined that pc does not exist");
- set_errno (ENOENT);
- return -1;
- }
RtlSplitUnicodePath (pc.get_nt_native_path (), &dirname, &basename);
InitializeObjectAttributes (&attr, &dirname, OBJ_CASE_INSENSITIVE,
NULL, NULL);
@@ -402,13 +392,13 @@ fhandler_base::fstat_by_name (struct __stat64 *buf)
}
if (wincap.has_fileid_dirinfo ()
&& NT_SUCCESS (status = NtQueryDirectoryFile (dir, NULL, NULL, 0, &io,
- pfdi, fdi_size,
+ &fdi_buf.fdi, sizeof fdi_buf,
FileIdBothDirectoryInformation,
TRUE, &basename, TRUE)))
- FileId = pfdi->FileId;
+ FileId = fdi_buf.fdi.FileId;
else if (NT_SUCCESS (status = NtQueryDirectoryFile (dir, NULL, NULL, 0, &io,
- pfdi, fdi_size,
- FileBothDirectoryInformation,
+ &fdi_buf.fdi, sizeof fdi_buf,
+ FileDirectoryInformation,
TRUE, &basename, TRUE)))
FileId.QuadPart = 0; /* get_ino is called in fstat_helper. */
if (!NT_SUCCESS (status))
@@ -418,34 +408,26 @@ fhandler_base::fstat_by_name (struct __stat64 *buf)
NtClose (dir);
goto too_bad;
}
- status = NtQueryVolumeInformationFile (dir, &io, pfvi, fvi_size,
- FileFsVolumeInformation);
- if (!NT_SUCCESS (status))
- {
- debug_printf ("%p = NtQueryVolumeInformationFile(%S)",
- status, pc.get_nt_native_path ());
- pfvi->VolumeSerialNumber = 0;
- }
NtClose (dir);
/* If the change time is 0, it's a file system which doesn't
support a change timestamp. In that case use the LastWriteTime
entry, as in other calls to fstat_helper. */
if (pc.is_rep_symlink ())
- pfdi->FileAttributes &= ~FILE_ATTRIBUTE_DIRECTORY;
- pc.file_attributes (pfdi->FileAttributes);
+ fdi_buf.fdi.FileAttributes &= ~FILE_ATTRIBUTE_DIRECTORY;
+ pc.file_attributes (fdi_buf.fdi.FileAttributes);
return fstat_helper (buf,
- pfdi->ChangeTime.QuadPart ?
- *(FILETIME *) &pfdi->ChangeTime :
- *(FILETIME *) &pfdi->LastWriteTime,
- *(FILETIME *) &pfdi->LastAccessTime,
- *(FILETIME *) &pfdi->LastWriteTime,
- *(FILETIME *) &pfdi->CreationTime,
- pfvi->VolumeSerialNumber,
- pfdi->EndOfFile.QuadPart,
- pfdi->AllocationSize.QuadPart,
- pfdi->FileId.QuadPart,
+ fdi_buf.fdi.ChangeTime.QuadPart ?
+ *(FILETIME *) &fdi_buf.fdi.ChangeTime :
+ *(FILETIME *) &fdi_buf.fdi.LastWriteTime,
+ *(FILETIME *) &fdi_buf.fdi.LastAccessTime,
+ *(FILETIME *) &fdi_buf.fdi.LastWriteTime,
+ *(FILETIME *) &fdi_buf.fdi.CreationTime,
+ pc.fs_serial_number (),
+ fdi_buf.fdi.EndOfFile.QuadPart,
+ fdi_buf.fdi.AllocationSize.QuadPart,
+ FileId.QuadPart,
1,
- pfdi->FileAttributes);
+ fdi_buf.fdi.FileAttributes);
too_bad:
LARGE_INTEGER ft;
@@ -679,14 +661,6 @@ fhandler_disk_file::fstatvfs (struct statvfs *sfs)
int ret = -1, opened = 0;
NTSTATUS status;
IO_STATUS_BLOCK io;
- const size_t fvi_size = sizeof (FILE_FS_VOLUME_INFORMATION)
- + (NAME_MAX + 1) * sizeof (WCHAR);
- PFILE_FS_VOLUME_INFORMATION pfvi = (PFILE_FS_VOLUME_INFORMATION)
- alloca (fvi_size);
- const size_t fai_size = sizeof (FILE_FS_ATTRIBUTE_INFORMATION)
- + (NAME_MAX + 1) * sizeof (WCHAR);
- PFILE_FS_ATTRIBUTE_INFORMATION pfai = (PFILE_FS_ATTRIBUTE_INFORMATION)
- alloca (fai_size);
FILE_FS_FULL_SIZE_INFORMATION full_fsi;
FILE_FS_SIZE_INFORMATION fsi;
HANDLE fh = get_handle ();
@@ -712,27 +686,12 @@ fhandler_disk_file::fstatvfs (struct statvfs *sfs)
}
}
- /* Get basic volume information. */
- status = NtQueryVolumeInformationFile (fh, &io, pfvi, fvi_size,
- FileFsVolumeInformation);
- if (!NT_SUCCESS (status))
- {
- __seterrno_from_nt_status (status);
- goto out;
- }
- status = NtQueryVolumeInformationFile (fh, &io, pfai, fai_size,
- FileFsAttributeInformation);
- if (!NT_SUCCESS (status))
- {
- __seterrno_from_nt_status (status);
- goto out;
- }
sfs->f_files = ULONG_MAX;
sfs->f_ffree = ULONG_MAX;
sfs->f_favail = ULONG_MAX;
- sfs->f_fsid = pfvi->VolumeSerialNumber;
- sfs->f_flag = pfai->FileSystemAttributes;
- sfs->f_namemax = pfai->MaximumComponentNameLength;
+ sfs->f_fsid = pc.fs_serial_number ();
+ sfs->f_flag = pc.fs_flags ();
+ sfs->f_namemax = pc.fs_name_len ();
/* Get allocation related information. Try to get "full" information
first, which is only available since W2K. If that fails, try to
retrieve normal allocation information. */
@@ -1608,7 +1567,7 @@ fhandler_disk_file::opendir (int fd)
OS/FS combinations (say, Win2K/CDFS or so). Instead of
testing in readdir for yet another error code, let's use
FileIdBothDirectoryInformation only on filesystems supporting
- persistent ACLs, FileBothDirectoryInformation otherwise.
+ persistent ACLs, FileDirectoryInformation otherwise.
On older NFS clients (up to SFU 3.5), dangling symlinks
are hidden from directory queries, unless you use the
@@ -1825,20 +1784,20 @@ fhandler_disk_file::readdir (DIR *dir, dirent *de)
nicely, but only up to the 128th entry in the directory. After
reaching this entry, the next call to NtQueryDirectoryFile
(FileIdBothDirectoryInformation) returns STATUS_INVALID_LEVEL.
- Why should we care, we can just switch to
- FileBothDirectoryInformation, isn't it? Nope! The next call to
- NtQueryDirectoryFile(FileBothDirectoryInformation) actually
- returns STATUS_NO_MORE_FILES, regardless how many files are left
- unread in the directory. This does not happen when using
- FileBothDirectoryInformation right from the start, but since
+ Why should we care, we can just switch to FileDirectoryInformation,
+ isn't it? Nope! The next call to
+ NtQueryDirectoryFile(FileDirectoryInformation)
+ actually returns STATUS_NO_MORE_FILES, regardless how many files
+ are left unread in the directory. This does not happen when using
+ FileDirectoryInformation right from the start, but since
we can't decide whether the server we're talking with has this
bug or not, we end up serving Samba shares always in the slow
- mode using FileBothDirectoryInformation. So, what we do here is
+ mode using FileDirectoryInformation. So, what we do here is
to implement the solution suggested by Andrew Tridgell, we just
reread all entries up to dir->d_position using
- FileBothDirectoryInformation.
+ FileDirectoryInformation.
However, We do *not* mark this server as broken and fall back to
- using FileBothDirectoryInformation further on. This would slow
+ using FileDirectoryInformation further on. This would slow
down every access to such a server, even for directories under
128 entries. Also, bigger dirs only suffer from one additional
call per full directory scan, which shouldn't be too big a hit.
@@ -1852,7 +1811,7 @@ fhandler_disk_file::readdir (DIR *dir, dirent *de)
{
status = NtQueryDirectoryFile (get_handle (), NULL, NULL,
0, &io, d_cache (dir), DIR_BUF_SIZE,
- FileBothDirectoryInformation,
+ FileDirectoryInformation,
FALSE, NULL, cnt == 0);
if (!NT_SUCCESS (status))
goto go_ahead;
@@ -1872,7 +1831,7 @@ fhandler_disk_file::readdir (DIR *dir, dirent *de)
d_cache (dir), DIR_BUF_SIZE,
(dir->__flags & dirent_nfs_d_ino)
? FileNamesInformation
- : FileBothDirectoryInformation,
+ : FileDirectoryInformation,
FALSE, NULL, dir->__d_position == 0);
}
@@ -1904,9 +1863,9 @@ go_ahead:
}
else
{
- FileName = ((PFILE_BOTH_DIR_INFORMATION) buf)->FileName;
- FileNameLength = ((PFILE_BOTH_DIR_INFORMATION) buf)->FileNameLength;
- FileAttributes = ((PFILE_BOTH_DIR_INFORMATION) buf)->FileAttributes;
+ FileName = ((PFILE_DIRECTORY_INFORMATION) buf)->FileName;
+ FileNameLength = ((PFILE_DIRECTORY_INFORMATION) buf)->FileNameLength;
+ FileAttributes = ((PFILE_DIRECTORY_INFORMATION) buf)->FileAttributes;
}
RtlInitCountedUnicodeString (&fname, FileName, FileNameLength);
de->d_ino = d_mounts (dir)->check_mount (&fname, de->d_ino);
diff --git a/winsup/cygwin/path.cc b/winsup/cygwin/path.cc
index 92994d1b1..58f0afde7 100644
--- a/winsup/cygwin/path.cc
+++ b/winsup/cygwin/path.cc
@@ -457,6 +457,7 @@ fs_info::update (PUNICODE_STRING upath, HANDLE in_vol)
return false;
}
flags (ffai_buf.ffai.FileSystemAttributes);
+ name_len (ffai_buf.ffai.MaximumComponentNameLength);
/* Should be reevaluated for each new OS. Right now this mask is valid up
to Vista. The important point here is to test only flags indicating
capabilities and to ignore flags indicating a specific state of this
diff --git a/winsup/cygwin/path.h b/winsup/cygwin/path.h
index fc0d28b60..513d7e80d 100644
--- a/winsup/cygwin/path.h
+++ b/winsup/cygwin/path.h
@@ -95,8 +95,9 @@ struct fs_info
private:
struct status_flags
{
- DWORD flags; /* Volume flags */
- DWORD samba_version; /* Samba version if available */
+ 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;
@@ -113,8 +114,9 @@ struct fs_info
void clear () { memset (&status, 0 , sizeof status); sernum = 0UL; }
fs_info () { clear (); }
- IMPLEMENT_STATUS_FLAG (DWORD, flags)
- IMPLEMENT_STATUS_FLAG (DWORD, samba_version)
+ IMPLEMENT_STATUS_FLAG (ULONG, flags)
+ 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_acls)
@@ -269,6 +271,7 @@ class path_conv
DWORD file_attributes () const {return fileattr;}
void file_attributes (DWORD new_attr) {fileattr = new_attr;}
DWORD fs_flags () {return fs.flags ();}
+ DWORD fs_name_len () {return fs.name_len ();}
bool fs_is_fat () const {return fs.is_fat ();}
bool fs_is_ntfs () const {return fs.is_ntfs ();}
bool fs_is_samba () const {return fs.is_samba ();}