* fhandler_disk_file.cc (path_conv::hasgood_inode): Make inline.

Drop remote fs handling entirely since unreliable inode numbers
	are now recognized differently.
	(path_conv::is_samba): Make inline.
	(fhandler_disk_file::opendir): Reformat comment.
	(fhandler_base::fstat_helper): Special case remote file systems
	returning (unreliable) 32 bit inode numbers.
	(fhandler_base::readdir): Ditto.
	* fhandler_netdrive.cc (fhandler_netdrive::readdir): Ditto.
This commit is contained in:
Corinna Vinschen 2006-04-14 14:20:58 +00:00
parent 04cbcde8d9
commit 5b9262e797
3 changed files with 42 additions and 32 deletions

View File

@ -1,3 +1,15 @@
2006-04-14 Corinna Vinschen <corinna@vinschen.de>
* fhandler_disk_file.cc (path_conv::hasgood_inode): Make inline.
Drop remote fs handling entirely since unreliable inode numbers
are now recognized differently.
(path_conv::is_samba): Make inline.
(fhandler_disk_file::opendir): Reformat comment.
(fhandler_base::fstat_helper): Special case remote file systems
returning (unreliable) 32 bit inode numbers.
(fhandler_base::readdir): Ditto.
* fhandler_netdrive.cc (fhandler_netdrive::readdir): Ditto.
2006-04-13 Christopher Faylor <cgf@timesys.com> 2006-04-13 Christopher Faylor <cgf@timesys.com>
* spawn.cc (spawn_guts): Move ch.set() call back to where it was * spawn.cc (spawn_guts): Move ch.set() call back to where it was

View File

@ -206,37 +206,17 @@ path_conv::ndisk_links (DWORD nNumberOfLinks)
| FILE_PERSISTENT_ACLS \ | FILE_PERSISTENT_ACLS \
| FILE_VOLUME_QUOTAS) | FILE_VOLUME_QUOTAS)
bool inline bool
path_conv::hasgood_inode () path_conv::hasgood_inode ()
{ {
/* Assume that if a drive has ACL support it MAY have valid "inodes". /* Assume that if a drive has ACL support it MAY have valid "inodes".
It definitely does not have valid inodes if it does not have ACL It definitely does not have valid inodes if it does not have ACL
support. Decouple from has_acls() which follows smbntsec setting. */ support. Decouple from has_acls() which follows smbntsec setting. */
if (!(fs_flags () & FILE_PERSISTENT_ACLS) || drive_type () == DRIVE_UNKNOWN) return ((fs_flags () & FILE_PERSISTENT_ACLS)
return false; && drive_type () != DRIVE_UNKNOWN);
if (drive_type () == DRIVE_REMOTE)
{
/* From own experiments and replies from the Cygwin mailing list,
we're now trying to figure out how to determine remote file
systems which are capable of returning persistent inode
numbers. It seems that NT4 NTFS, when accessed remotly, and
some other remote file systems return unreliable values in
nFileIndex. The common factor of these unreliable remote FS
seem to be that FILE_SUPPORTS_OBJECT_IDS isn't set, even though
this should have nothing to do with inode numbers.
An exception is Samba, which seems to return valid inode numbers
without having the FILE_SUPPORTS_OBJECT_IDS flag set. So we're
testing for the flag values returned by a 3.x Samba explicitely
for now. But note the comment in the below "is_samba" function. */
if (!(fs_flags () & FILE_SUPPORTS_OBJECT_IDS)
&& fs_flags () != FS_IS_SAMBA
&& fs_flags () != FS_IS_SAMBA_WITH_QUOTA)
return false;
}
return true;
} }
bool inline bool
path_conv::is_samba () path_conv::is_samba ()
{ {
/* Something weird happens on Samba up to version 3.0.21c, which is /* Something weird happens on Samba up to version 3.0.21c, which is
@ -477,7 +457,10 @@ fhandler_base::fstat_helper (struct __stat64 *buf,
let's try it with `1' as link count. */ let's try it with `1' as link count. */
buf->st_nlink = pc.ndisk_links (nNumberOfLinks); buf->st_nlink = pc.ndisk_links (nNumberOfLinks);
if (pc.hasgood_inode ()) /* We can't trust remote inode numbers of only 32 bit. That means,
all remote inode numbers when running under NT4, as well as remote NT4
NTFS, as well as shares of Samba version < 3.0. */
if (pc.hasgood_inode () && (nFileIndexHigh || !pc.isremote ()))
buf->st_ino = (((__ino64_t) nFileIndexHigh) << 32) buf->st_ino = (((__ino64_t) nFileIndexHigh) << 32)
| (__ino64_t) nFileIndexLow; | (__ino64_t) nFileIndexLow;
else else
@ -1592,12 +1575,12 @@ fhandler_disk_file::opendir ()
goto free_mounts; goto free_mounts;
} }
/* FileIdBothDirectoryInformation is apparently unsupported on XP /* FileIdBothDirectoryInformation is apparently unsupported on
when accessing directories on UDF. When trying to use it so, XP when accessing directories on UDF. When trying to use it
NtQueryDirectoryFile returns with STATUS_ACCESS_VIOLATION. It's so, NtQueryDirectoryFile returns with STATUS_ACCESS_VIOLATION.
not clear if the call isn't also unsupported on other OS/FS It's not clear if the call isn't also unsupported on other
combinations (say, Win2K/CDFS or so). Instead of testing in OS/FS combinations (say, Win2K/CDFS or so). Instead of
readdir for yet another error code, let's use testing in readdir for yet another error code, let's use
FileIdBothDirectoryInformation only on filesystems supporting FileIdBothDirectoryInformation only on filesystems supporting
persistent ACLs, FileBothDirectoryInformation otherwise. */ persistent ACLs, FileBothDirectoryInformation otherwise. */
if (pc.hasgood_inode ()) if (pc.hasgood_inode ())
@ -1805,6 +1788,14 @@ fhandler_disk_file::readdir (DIR *dir, dirent *de)
CloseHandle (hdl); CloseHandle (hdl);
} }
} }
/* We can't trust remote inode numbers of only 32 bit. That means,
all remote inode numbers when running under NT4, as well as
remote NT4 NTFS, as well as shares of Samba version < 3.0. */
if (de->d_ino <= UINT_MAX && pc.isremote ())
{
dir->__flags &= ~dirent_set_d_ino;
de->d_ino = 0;
}
} }
} }

View File

@ -209,7 +209,14 @@ fhandler_netdrive::readdir (DIR *dir, dirent *de)
if (strlen (get_name ()) == 2) if (strlen (get_name ()) == 2)
de->d_ino = hash_path_name (get_namehash (), de->d_name); de->d_ino = hash_path_name (get_namehash (), de->d_name);
else else
de->d_ino = readdir_get_ino (dir, nro->lpRemoteName, false); {
de->d_ino = readdir_get_ino (dir, nro->lpRemoteName, false);
/* We can't trust remote inode numbers of only 32 bit. That means,
all remote inode numbers when running under NT4, as well as
remote NT4 NTFS, as well as shares of Samba version < 3.0. */
if (de->d_ino <= UINT_MAX)
de->d_ino = hash_path_name (0, nro->lpRemoteName);
}
res = 0; res = 0;
} }