* fhandler_disk_file.cc (FS_IS_SAMBA): Move out of

path_conv::hasgood_inode.
	(path_conv::is_samba): New method.
	(fhandler_base::fstat_by_handle): Don't even try to use
	FileIdBothDirectoryInformation on Samba.
	* path.h (class path_conv): Declare is_samba method.
This commit is contained in:
Corinna Vinschen 2006-02-18 10:46:53 +00:00
parent 753702223c
commit 408b92dbb5
3 changed files with 35 additions and 5 deletions

View File

@ -1,3 +1,12 @@
2006-02-18 Corinna Vinschen <corinna@vinschen.de>
* fhandler_disk_file.cc (FS_IS_SAMBA): Move out of
path_conv::hasgood_inode.
(path_conv::is_samba): New method.
(fhandler_base::fstat_by_handle): Don't even try to use
FileIdBothDirectoryInformation on Samba.
* path.h (class path_conv): Declare is_samba method.
2006-02-17 Christopher Faylor <cgf@timesys.com> 2006-02-17 Christopher Faylor <cgf@timesys.com>
* path.cc (conv_path_list): Eat empty paths when converting to POSIX. * path.cc (conv_path_list): Eat empty paths when converting to POSIX.

View File

@ -96,6 +96,10 @@ path_conv::ndisk_links (DWORD nNumberOfLinks)
return count + saw_dot; return count + saw_dot;
} }
#define FS_IS_SAMBA (FILE_CASE_SENSITIVE_SEARCH \
| FILE_CASE_PRESERVED_NAMES \
| FILE_PERSISTENT_ACLS)
bool bool
path_conv::hasgood_inode () path_conv::hasgood_inode ()
{ {
@ -117,10 +121,7 @@ path_conv::hasgood_inode ()
An exception is Samba, which seems to return valid 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 without having the FILE_SUPPORTS_OBJECT_IDS flag set. So we're
testing for the flag values returned by a 3.x Samba explicitely testing for the flag values returned by a 3.x Samba explicitely
for now. */ for now. But note the comment in the below "is_samba" function. */
#define FS_IS_SAMBA (FILE_CASE_SENSITIVE_SEARCH \
| FILE_CASE_PRESERVED_NAMES \
| FILE_PERSISTENT_ACLS)
if (!(fs_flags () & FILE_SUPPORTS_OBJECT_IDS) if (!(fs_flags () & FILE_SUPPORTS_OBJECT_IDS)
&& fs_flags () != FS_IS_SAMBA) && fs_flags () != FS_IS_SAMBA)
return false; return false;
@ -128,6 +129,25 @@ path_conv::hasgood_inode ()
return true; return true;
} }
bool
path_conv::is_samba ()
{
/* Something weird happens on Samba. FileIdBothDirectoryInformation
seems to work nicely, but only up to the 128th entry in the
directory. After reaching this entry, the next call to
NtQueryDirectoryFile(FileIdBothDirectoryInformation) returns
STATUS_INVAILD_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. In that case we
can read the whole directory unmolested. So we have to excempt
Samba from the usage of FileIdBothDirectoryInformation entirely,
even though Samba returns valid File IDs. */
return drive_type () == DRIVE_REMOTE && fs_flags () == FS_IS_SAMBA;
}
int __stdcall int __stdcall
fhandler_base::fstat_by_handle (struct __stat64 *buf) fhandler_base::fstat_by_handle (struct __stat64 *buf)
{ {
@ -1461,7 +1481,7 @@ fhandler_disk_file::opendir ()
if (pc.hasgood_inode ()) if (pc.hasgood_inode ())
{ {
dir->__flags |= dirent_set_d_ino; dir->__flags |= dirent_set_d_ino;
if (wincap.has_fileid_dirinfo ()) if (wincap.has_fileid_dirinfo () && !pc.is_samba ())
dir->__flags |= dirent_get_d_ino; dir->__flags |= dirent_get_d_ino;
} }
} }

View File

@ -137,6 +137,7 @@ class path_conv
int has_acls () const {return fs.has_acls (); } int has_acls () const {return fs.has_acls (); }
int has_symlinks () const {return path_flags & PATH_HAS_SYMLINKS;} int has_symlinks () const {return path_flags & PATH_HAS_SYMLINKS;}
bool hasgood_inode (); /* Implemented in fhandler_disk_file.cc */ bool hasgood_inode (); /* Implemented in fhandler_disk_file.cc */
bool is_samba (); /* Implemented in fhandler_disk_file.cc */
int has_buggy_open () const {return fs.has_buggy_open ();} int has_buggy_open () const {return fs.has_buggy_open ();}
bool isencoded () {return path_flags & PATH_ENC;} bool isencoded () {return path_flags & PATH_ENC;}
int binmode () const int binmode () const