* mount.h (enum fs_info_type): New type.
(IMPLEMENT_FS_FLAG): New define. (class fs_info): Convert filesystem type status flags into an enum fs_info_type. Add cifs FS. Revert change to has_buggy_open and has_buggy_fileid_dirinfo. Make them normal; status flags again. Implement is_FS functions using IMPLEMENT_FS_FLAG. * mount.cc (fs_info::update): Define MINIMAL_WIN_NTFS_FLAGS and FS_IS_WINDOWS_NTFS. Add comment. Only test remote filesystems for "NTFS" once. Add is_cifs check using FS_IS_WINDOWS_NTFS. Set has_buggy_open flag for SUNWNFS. Set has_buggy_fileid_dirinfo flag for UNIXFS and all cifs type filesystems. Only check for caseinsensitivity once. (fillout_mntent): Create locale fs_names array. Use for setting _my_tls.locals.mnt_type.
This commit is contained in:
parent
d826cbf322
commit
8d641a5b46
|
@ -1,3 +1,20 @@
|
|||
2009-07-27 Corinna Vinschen <corinna@vinschen.de>
|
||||
|
||||
* mount.h (enum fs_info_type): New type.
|
||||
(IMPLEMENT_FS_FLAG): New define.
|
||||
(class fs_info): Convert filesystem type status flags into an enum
|
||||
fs_info_type. Add cifs FS. Revert change to has_buggy_open and
|
||||
has_buggy_fileid_dirinfo. Make them normal; status flags again.
|
||||
Implement is_FS functions using IMPLEMENT_FS_FLAG.
|
||||
* mount.cc (fs_info::update): Define MINIMAL_WIN_NTFS_FLAGS and
|
||||
FS_IS_WINDOWS_NTFS. Add comment. Only test remote filesystems
|
||||
for "NTFS" once. Add is_cifs check using FS_IS_WINDOWS_NTFS.
|
||||
Set has_buggy_open flag for SUNWNFS. Set has_buggy_fileid_dirinfo
|
||||
flag for UNIXFS and all cifs type filesystems. Only check for
|
||||
caseinsensitivity once.
|
||||
(fillout_mntent): Create locale fs_names array. Use for setting
|
||||
_my_tls.locals.mnt_type.
|
||||
|
||||
2009-07-27 Yaakov Selkowitz <yselkowitz@users.sourceforge.net>
|
||||
|
||||
* posix.sgml (std-notes): Remove obsolete reference to CYGWIN=server.
|
||||
|
|
|
@ -198,6 +198,10 @@ fs_info::update (PUNICODE_STRING upath, HANDLE in_vol)
|
|||
}
|
||||
flags (ffai_buf.ffai.FileSystemAttributes);
|
||||
name_len (ffai_buf.ffai.MaximumComponentNameLength);
|
||||
RtlInitCountedUnicodeString (&fsname, ffai_buf.ffai.FileSystemName,
|
||||
ffai_buf.ffai.FileSystemNameLength);
|
||||
if (is_remote_drive ())
|
||||
{
|
||||
/* 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
|
||||
|
@ -215,16 +219,23 @@ fs_info::update (PUNICODE_STRING upath, HANDLE in_vol)
|
|||
FILE_CASE_SENSITIVE_SEARCH \
|
||||
| FILE_CASE_PRESERVED_NAMES \
|
||||
| FILE_PERSISTENT_ACLS)
|
||||
/* Netapp DataOnTap. TODO: Find out if that's the only flag combination. */
|
||||
#define FS_IS_NETAPP_DATAONTAP TEST_GVI(flags (), \
|
||||
FILE_CASE_SENSITIVE_SEARCH \
|
||||
| FILE_CASE_PRESERVED_NAMES \
|
||||
| FILE_UNICODE_ON_DISK \
|
||||
| FILE_PERSISTENT_ACLS \
|
||||
| FILE_NAMED_STREAMS)
|
||||
RtlInitCountedUnicodeString (&fsname, ffai_buf.ffai.FileSystemName,
|
||||
ffai_buf.ffai.FileSystemNameLength);
|
||||
if (is_remote_drive ())
|
||||
{
|
||||
/* These are the minimal flags supported by NTFS since NT4. Every filesystem
|
||||
not supporting these flags is not a native NTFS. We subsume them under
|
||||
the filesystem type "cifs". */
|
||||
#define MINIMAL_WIN_NTFS_FLAGS (FILE_CASE_SENSITIVE_SEARCH \
|
||||
| FILE_CASE_PRESERVED_NAMES \
|
||||
| FILE_UNICODE_ON_DISK \
|
||||
| FILE_PERSISTENT_ACLS \
|
||||
| FILE_FILE_COMPRESSION)
|
||||
#define FS_IS_WINDOWS_NTFS TEST_GVI(flags () & MINIMAL_WIN_NTFS_FLAGS, \
|
||||
MINIMAL_WIN_NTFS_FLAGS)
|
||||
/* This always fails on NT4. */
|
||||
status = NtQueryVolumeInformationFile (vol, &io, &ffoi, sizeof ffoi,
|
||||
FileFsObjectIdInformation);
|
||||
|
@ -238,14 +249,17 @@ fs_info::update (PUNICODE_STRING upath, HANDLE in_vol)
|
|||
samba_version (extended_info->samba_version);
|
||||
}
|
||||
}
|
||||
if (!got_fs ()
|
||||
/* First check the remote filesystems faking to be NTFS. */
|
||||
if (!got_fs () && RtlEqualUnicodeString (&fsname, &ro_u_ntfs, FALSE)
|
||||
/* Test for Samba on NT4 or for older Samba releases not supporting
|
||||
extended info. */
|
||||
&& !is_samba (RtlEqualUnicodeString (&fsname, &ro_u_ntfs, FALSE)
|
||||
&& FS_IS_SAMBA)
|
||||
&& !is_samba (FS_IS_SAMBA)
|
||||
/* Netapp inode info is unusable. */
|
||||
&& !is_netapp (RtlEqualUnicodeString (&fsname, &ro_u_ntfs, FALSE)
|
||||
&& FS_IS_NETAPP_DATAONTAP)
|
||||
&& !is_netapp (FS_IS_NETAPP_DATAONTAP))
|
||||
/* Any other remote FS faking to be NTFS. */
|
||||
is_cifs (!FS_IS_WINDOWS_NTFS);
|
||||
/* Then check remote filesystems honest about their name. */
|
||||
if (!got_fs ()
|
||||
/* Microsoft NFS needs distinct access methods for metadata. */
|
||||
&& !is_nfs (RtlEqualUnicodeString (&fsname, &ro_u_nfs, FALSE))
|
||||
/* MVFS == Rational ClearCase remote filesystem. Has a couple of
|
||||
|
@ -257,25 +271,23 @@ fs_info::update (PUNICODE_STRING upath, HANDLE in_vol)
|
|||
&& !is_unixfs (RtlEqualUnicodeString (&fsname, &ro_u_unixfs, FALSE)))
|
||||
/* Known remote file system with buggy open calls. Further
|
||||
explanation in fhandler.cc (fhandler_disk_file::open). */
|
||||
is_sunwnfs (RtlEqualUnicodeString (&fsname, &ro_u_sunwnfs, FALSE));
|
||||
{
|
||||
is_sunwnfs (RtlEqualUnicodeString (&fsname, &ro_u_sunwnfs, FALSE));
|
||||
has_buggy_open (is_sunwnfs ());
|
||||
}
|
||||
/* Not only UNIXFS is known to choke on FileIdBothDirectoryInformation.
|
||||
Some other CIFS servers have problems with this call as well.
|
||||
Know example: EMC NS-702. We just don't use that info class on
|
||||
any remote CIFS. */
|
||||
if (got_fs ())
|
||||
has_buggy_fileid_dirinfo (is_cifs () || is_unixfs ());
|
||||
}
|
||||
if (!got_fs ()
|
||||
&& !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_cdrom (ffdi.DeviceType == FILE_DEVICE_CD_ROM))
|
||||
{
|
||||
is_udf (RtlEqualUnicodeString (&fsname, &ro_u_udf, FALSE));
|
||||
/* UDF on NT 5.x is broken (at least) in terms of case sensitivity.
|
||||
The UDF driver reports the FILE_CASE_SENSITIVE_SEARCH capability
|
||||
but:
|
||||
- Opening the root directory for query seems to work at first,
|
||||
but the filenames in the directory listing are mutilated.
|
||||
- When trying to open a file or directory case sensitive, the file
|
||||
appears to be non-existant. */
|
||||
if (is_udf () && wincap.has_broken_udf ())
|
||||
caseinsensitive (true);
|
||||
}
|
||||
is_udf (RtlEqualUnicodeString (&fsname, &ro_u_udf, FALSE));
|
||||
if (!got_fs ())
|
||||
{
|
||||
/* The filesystem name is only used in fillout_mntent and only if
|
||||
|
@ -289,10 +301,20 @@ fs_info::update (PUNICODE_STRING upath, HANDLE in_vol)
|
|||
hasgood_inode ((has_acls () && !is_netapp ()) || is_nfs ());
|
||||
/* Case sensitivity is supported if FILE_CASE_SENSITIVE_SEARCH is set,
|
||||
except on Samba which handles Windows clients case insensitive.
|
||||
|
||||
NFS doesn't set the FILE_CASE_SENSITIVE_SEARCH flag but is case
|
||||
sensitive. */
|
||||
caseinsensitive ((!(flags () & FILE_CASE_SENSITIVE_SEARCH) || is_samba ())
|
||||
&& !is_nfs ());
|
||||
sensitive.
|
||||
|
||||
UDF on NT 5.x is broken (at least) in terms of case sensitivity.
|
||||
The UDF driver reports the FILE_CASE_SENSITIVE_SEARCH capability
|
||||
but:
|
||||
- Opening the root directory for query seems to work at first,
|
||||
but the filenames in the directory listing are mutilated.
|
||||
- When trying to open a file or directory case sensitive, the file
|
||||
appears to be non-existant. */
|
||||
caseinsensitive (((!(flags () & FILE_CASE_SENSITIVE_SEARCH) || is_samba ())
|
||||
&& !is_nfs ())
|
||||
|| (is_udf () && wincap.has_broken_udf ()));
|
||||
|
||||
if (!in_vol)
|
||||
NtClose (vol);
|
||||
|
@ -1405,28 +1427,25 @@ fillout_mntent (const char *native_path, const char *posix_path, unsigned flags)
|
|||
RtlAppendUnicodeToString (&unat, L"\\");
|
||||
mntinfo.update (&unat, NULL);
|
||||
|
||||
if (mntinfo.is_ntfs ())
|
||||
strcpy (_my_tls.locals.mnt_type, (char *) "ntfs");
|
||||
else if (mntinfo.is_fat ())
|
||||
strcpy (_my_tls.locals.mnt_type, (char *) "vfat");
|
||||
else if (mntinfo.is_samba())
|
||||
strcpy (_my_tls.locals.mnt_type, (char *) "smbfs");
|
||||
else if (mntinfo.is_nfs ())
|
||||
strcpy (_my_tls.locals.mnt_type, (char *) "nfs");
|
||||
else if (mntinfo.is_udf ())
|
||||
strcpy (_my_tls.locals.mnt_type, (char *) "udf");
|
||||
else if (mntinfo.is_cdrom ())
|
||||
strcpy (_my_tls.locals.mnt_type, (char *) "iso9660");
|
||||
else if (mntinfo.is_netapp ())
|
||||
strcpy (_my_tls.locals.mnt_type, (char *) "netapp");
|
||||
else if (mntinfo.is_csc_cache ())
|
||||
strcpy (_my_tls.locals.mnt_type, (char *) "csc-cache");
|
||||
else if (mntinfo.is_mvfs ())
|
||||
strcpy (_my_tls.locals.mnt_type, (char *) "mvfs");
|
||||
else if (mntinfo.is_unixfs ())
|
||||
strcpy (_my_tls.locals.mnt_type, (char *) "unixfs");
|
||||
else if (mntinfo.is_sunwnfs ())
|
||||
strcpy (_my_tls.locals.mnt_type, (char *) "sunwnfs");
|
||||
/* Order must be identical to mount.h, enum fs_info_type. */
|
||||
const char *fs_names[] = {
|
||||
"none",
|
||||
"vfat",
|
||||
"ntfs",
|
||||
"smbfs",
|
||||
"nfs",
|
||||
"netapp",
|
||||
"iso9660",
|
||||
"udf",
|
||||
"csc-cache",
|
||||
"sunwnfs",
|
||||
"unixfs",
|
||||
"mvfs",
|
||||
"cifs"
|
||||
};
|
||||
|
||||
if (mntinfo.what_fs () > 0 && mntinfo.what_fs () < max_fs_type)
|
||||
strcpy (_my_tls.locals.mnt_type, fs_names[mntinfo.what_fs ()]);
|
||||
else
|
||||
strcpy (_my_tls.locals.mnt_type, mntinfo.fsname ());
|
||||
|
||||
|
|
|
@ -12,39 +12,47 @@ details. */
|
|||
#ifndef _MOUNT_H
|
||||
#define _MOUNT_H
|
||||
|
||||
enum fs_info_type
|
||||
{
|
||||
none = 0,
|
||||
fat,
|
||||
ntfs,
|
||||
samba,
|
||||
nfs,
|
||||
netapp,
|
||||
cdrom,
|
||||
udf,
|
||||
csc_cache,
|
||||
sunwnfs,
|
||||
unixfs,
|
||||
mvfs,
|
||||
cifs,
|
||||
/* Always last. */
|
||||
max_fs_type
|
||||
};
|
||||
|
||||
#define IMPLEMENT_FS_FLAG(func, flag) \
|
||||
bool func (bool val) { if (val) status.fs_type = flag; return val; } \
|
||||
bool func () const { return status.fs_type == flag; }
|
||||
|
||||
class fs_info
|
||||
{
|
||||
struct status_flags
|
||||
{
|
||||
ULONG flags; /* Volume flags */
|
||||
ULONG samba_version; /* Samba version if available */
|
||||
ULONG name_len; /* MaximumComponentNameLength */
|
||||
ULONG flags; /* Volume flags */
|
||||
ULONG samba_version; /* Samba version if available */
|
||||
ULONG name_len; /* MaximumComponentNameLength */
|
||||
fs_info_type fs_type; /* Filesystem type */
|
||||
unsigned is_remote_drive : 1;
|
||||
unsigned has_acls : 1;
|
||||
unsigned hasgood_inode : 1;
|
||||
unsigned caseinsensitive : 1;
|
||||
union
|
||||
{
|
||||
struct
|
||||
{
|
||||
unsigned is_fat : 1;
|
||||
unsigned is_ntfs : 1;
|
||||
unsigned is_samba : 1;
|
||||
unsigned is_nfs : 1;
|
||||
unsigned is_netapp : 1;
|
||||
unsigned is_cdrom : 1;
|
||||
unsigned is_udf : 1;
|
||||
unsigned is_csc_cache : 1;
|
||||
unsigned is_sunwnfs : 1;
|
||||
unsigned is_unixfs : 1;
|
||||
unsigned is_mvfs : 1;
|
||||
};
|
||||
unsigned long fs_flags;
|
||||
};
|
||||
unsigned has_buggy_open : 1;
|
||||
unsigned has_buggy_fileid_dirinfo : 1;
|
||||
} status;
|
||||
ULONG sernum;
|
||||
char fsn[80];
|
||||
unsigned long got_fs () { return status.fs_flags; }
|
||||
ULONG sernum; /* Volume Serial Number */
|
||||
char fsn[80]; /* Windows filesystem name */
|
||||
unsigned long got_fs () const { return status.fs_type != none; }
|
||||
|
||||
public:
|
||||
void clear ()
|
||||
|
@ -62,21 +70,24 @@ class fs_info
|
|||
IMPLEMENT_STATUS_FLAG (bool, has_acls)
|
||||
IMPLEMENT_STATUS_FLAG (bool, hasgood_inode)
|
||||
IMPLEMENT_STATUS_FLAG (bool, caseinsensitive)
|
||||
IMPLEMENT_STATUS_FLAG (bool, is_fat)
|
||||
IMPLEMENT_STATUS_FLAG (bool, is_ntfs)
|
||||
IMPLEMENT_STATUS_FLAG (bool, is_samba)
|
||||
IMPLEMENT_STATUS_FLAG (bool, is_nfs)
|
||||
IMPLEMENT_STATUS_FLAG (bool, is_netapp)
|
||||
IMPLEMENT_STATUS_FLAG (bool, is_cdrom)
|
||||
IMPLEMENT_STATUS_FLAG (bool, is_udf)
|
||||
IMPLEMENT_STATUS_FLAG (bool, is_csc_cache)
|
||||
IMPLEMENT_STATUS_FLAG (bool, is_sunwnfs)
|
||||
IMPLEMENT_STATUS_FLAG (bool, is_unixfs)
|
||||
IMPLEMENT_STATUS_FLAG (bool, is_mvfs)
|
||||
IMPLEMENT_STATUS_FLAG (bool, has_buggy_open)
|
||||
IMPLEMENT_STATUS_FLAG (bool, has_buggy_fileid_dirinfo)
|
||||
IMPLEMENT_FS_FLAG (is_fat, fat)
|
||||
IMPLEMENT_FS_FLAG (is_ntfs, ntfs)
|
||||
IMPLEMENT_FS_FLAG (is_samba, samba)
|
||||
IMPLEMENT_FS_FLAG (is_nfs, nfs)
|
||||
IMPLEMENT_FS_FLAG (is_netapp, netapp)
|
||||
IMPLEMENT_FS_FLAG (is_cdrom, cdrom)
|
||||
IMPLEMENT_FS_FLAG (is_udf, udf)
|
||||
IMPLEMENT_FS_FLAG (is_csc_cache, csc_cache)
|
||||
IMPLEMENT_FS_FLAG (is_sunwnfs, sunwnfs)
|
||||
IMPLEMENT_FS_FLAG (is_unixfs, unixfs)
|
||||
IMPLEMENT_FS_FLAG (is_mvfs, mvfs)
|
||||
IMPLEMENT_FS_FLAG (is_cifs, cifs)
|
||||
fs_info_type what_fs () const { return status.fs_type; }
|
||||
|
||||
ULONG serial_number () const { return sernum; }
|
||||
|
||||
int has_buggy_open () const {return is_sunwnfs ();}
|
||||
int has_buggy_fileid_dirinfo () const {return is_unixfs ();}
|
||||
const char *fsname () const { return fsn[0] ? fsn : "unknown"; }
|
||||
|
||||
bool update (PUNICODE_STRING, HANDLE) __attribute__ ((regparm (3)));
|
||||
|
|
Loading…
Reference in New Issue