* fhandler_disk_file.cc (fhandler_disk_file::readdir_helper): Remove
ill-advised attempt to optimize "." and ".." handling by checking for specific position in directory listing. Explain why. (fhandler_disk_file.cc (fhandler_disk_file::readdir): Ditto. Special-case opening file on NFS to fetch inode number and add longish comment to explain why.
This commit is contained in:
parent
c1999c4b0c
commit
e575678945
|
@ -1,3 +1,12 @@
|
||||||
|
2009-08-14 Corinna Vinschen <corinna@vinschen.de>
|
||||||
|
|
||||||
|
* fhandler_disk_file.cc (fhandler_disk_file::readdir_helper): Remove
|
||||||
|
ill-advised attempt to optimize "." and ".." handling by checking for
|
||||||
|
specific position in directory listing. Explain why.
|
||||||
|
(fhandler_disk_file.cc (fhandler_disk_file::readdir): Ditto.
|
||||||
|
Special-case opening file on NFS to fetch inode number and add longish
|
||||||
|
comment to explain why.
|
||||||
|
|
||||||
2009-08-14 Corinna Vinschen <corinna@vinschen.de>
|
2009-08-14 Corinna Vinschen <corinna@vinschen.de>
|
||||||
|
|
||||||
* (fhandler_socket::getsockname): Fix length returned for unbound
|
* (fhandler_socket::getsockname): Fix length returned for unbound
|
||||||
|
|
|
@ -1828,10 +1828,16 @@ fhandler_disk_file::readdir_helper (DIR *dir, dirent *de, DWORD w32_err,
|
||||||
sys_wcstombs (de->d_name, NAME_MAX + 1, fname->Buffer,
|
sys_wcstombs (de->d_name, NAME_MAX + 1, fname->Buffer,
|
||||||
fname->Length / sizeof (WCHAR));
|
fname->Length / sizeof (WCHAR));
|
||||||
|
|
||||||
if (dir->__d_position == 0 && !strcmp (de->d_name, "."))
|
/* Don't try to optimize relative to dir->__d_position. On several
|
||||||
dir->__flags |= dirent_saw_dot;
|
filesystems it's no safe bet that "." and ".." entries always
|
||||||
else if (dir->__d_position == 1 && !strcmp (de->d_name, ".."))
|
come first. */
|
||||||
dir->__flags |= dirent_saw_dot_dot;
|
if (de->d_name[0] == '.')
|
||||||
|
{
|
||||||
|
if (de->d_name[1] == '\0')
|
||||||
|
dir->__flags |= dirent_saw_dot;
|
||||||
|
else if (de->d_name[1] == '.' && de->d_name[2] == '\0')
|
||||||
|
dir->__flags |= dirent_saw_dot_dot;
|
||||||
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1960,28 +1966,51 @@ go_ahead:
|
||||||
de->d_ino = d_mounts (dir)->check_mount (&fname, de->d_ino);
|
de->d_ino = d_mounts (dir)->check_mount (&fname, de->d_ino);
|
||||||
if (de->d_ino == 0 && (dir->__flags & dirent_set_d_ino))
|
if (de->d_ino == 0 && (dir->__flags & dirent_set_d_ino))
|
||||||
{
|
{
|
||||||
OBJECT_ATTRIBUTES attr;
|
/* Don't try to optimize relative to dir->__d_position. On several
|
||||||
|
filesystems it's no safe bet that "." and ".." entries always
|
||||||
if (dir->__d_position == 0 && FileNameLength == 2
|
come first. */
|
||||||
&& FileName[0] == '.')
|
if (FileNameLength == sizeof (WCHAR) && FileName[0] == '.')
|
||||||
de->d_ino = get_ino_by_handle (pc, get_handle ());
|
de->d_ino = get_ino_by_handle (pc, get_handle ());
|
||||||
else if (dir->__d_position == 1 && FileNameLength == 4
|
else if (FileNameLength == sizeof (WCHAR)
|
||||||
&& FileName[0] == L'.' && FileName[1] == L'.')
|
&& FileName[0] == L'.' && FileName[1] == L'.')
|
||||||
if (!(dir->__flags & dirent_isroot))
|
{
|
||||||
de->d_ino = readdir_get_ino (get_name (), true);
|
if (!(dir->__flags & dirent_isroot))
|
||||||
else
|
de->d_ino = readdir_get_ino (get_name (), true);
|
||||||
de->d_ino = get_ino_by_handle (pc, get_handle ());
|
else
|
||||||
|
de->d_ino = get_ino_by_handle (pc, get_handle ());
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
OBJECT_ATTRIBUTES attr;
|
||||||
HANDLE hdl;
|
HANDLE hdl;
|
||||||
|
NTSTATUS f_status;
|
||||||
|
|
||||||
InitializeObjectAttributes (&attr, &fname,
|
InitializeObjectAttributes (&attr, &fname,
|
||||||
pc.objcaseinsensitive (),
|
pc.objcaseinsensitive (),
|
||||||
get_handle (), NULL);
|
get_handle (), NULL);
|
||||||
if (NT_SUCCESS (NtOpenFile (&hdl, READ_CONTROL, &attr, &io,
|
/* FILE_OPEN_REPARSE_POINT on NFS is a no-op, so the normal
|
||||||
FILE_SHARE_VALID_FLAGS,
|
NtOpenFile here returns the inode number of the symlink target,
|
||||||
FILE_OPEN_FOR_BACKUP_INTENT
|
rather than the inode number of the symlink itself.
|
||||||
| FILE_OPEN_REPARSE_POINT)))
|
|
||||||
|
Worse, trying to open a symlink without setting the special
|
||||||
|
"ActOnSymlink" EA triggers a bug in Windows 7 which results
|
||||||
|
in a timeout of about 20 seconds, followed by two exceptions
|
||||||
|
in the NT kernel.
|
||||||
|
|
||||||
|
Since both results are far from desirable, we open symlinks
|
||||||
|
on NFS so that we get the right inode and a happy W7.
|
||||||
|
And, since some filesystems choke on the EAs, we don't
|
||||||
|
use them unconditionally. */
|
||||||
|
f_status = (dir->__flags & dirent_nfs_d_ino)
|
||||||
|
? NtCreateFile (&hdl, READ_CONTROL, &attr, &io,
|
||||||
|
NULL, 0, FILE_SHARE_VALID_FLAGS,
|
||||||
|
FILE_OPEN, FILE_OPEN_FOR_BACKUP_INTENT,
|
||||||
|
&nfs_aol_ffei, sizeof nfs_aol_ffei)
|
||||||
|
: NtOpenFile (&hdl, READ_CONTROL, &attr, &io,
|
||||||
|
FILE_SHARE_VALID_FLAGS,
|
||||||
|
FILE_OPEN_FOR_BACKUP_INTENT
|
||||||
|
| FILE_OPEN_REPARSE_POINT);
|
||||||
|
if (NT_SUCCESS (f_status))
|
||||||
{
|
{
|
||||||
de->d_ino = get_ino_by_handle (pc, hdl);
|
de->d_ino = get_ino_by_handle (pc, hdl);
|
||||||
NtClose (hdl);
|
NtClose (hdl);
|
||||||
|
|
Loading…
Reference in New Issue