* 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>
|
2009-07-27 Yaakov Selkowitz <yselkowitz@users.sourceforge.net>
|
||||||
|
|
||||||
* posix.sgml (std-notes): Remove obsolete reference to CYGWIN=server.
|
* 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);
|
flags (ffai_buf.ffai.FileSystemAttributes);
|
||||||
name_len (ffai_buf.ffai.MaximumComponentNameLength);
|
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
|
/* 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
|
to Vista. The important point here is to test only flags indicating
|
||||||
capabilities and to ignore flags indicating a specific state of this
|
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_SENSITIVE_SEARCH \
|
||||||
| FILE_CASE_PRESERVED_NAMES \
|
| FILE_CASE_PRESERVED_NAMES \
|
||||||
| FILE_PERSISTENT_ACLS)
|
| FILE_PERSISTENT_ACLS)
|
||||||
|
/* Netapp DataOnTap. TODO: Find out if that's the only flag combination. */
|
||||||
#define FS_IS_NETAPP_DATAONTAP TEST_GVI(flags (), \
|
#define FS_IS_NETAPP_DATAONTAP TEST_GVI(flags (), \
|
||||||
FILE_CASE_SENSITIVE_SEARCH \
|
FILE_CASE_SENSITIVE_SEARCH \
|
||||||
| FILE_CASE_PRESERVED_NAMES \
|
| FILE_CASE_PRESERVED_NAMES \
|
||||||
| FILE_UNICODE_ON_DISK \
|
| FILE_UNICODE_ON_DISK \
|
||||||
| FILE_PERSISTENT_ACLS \
|
| FILE_PERSISTENT_ACLS \
|
||||||
| FILE_NAMED_STREAMS)
|
| FILE_NAMED_STREAMS)
|
||||||
RtlInitCountedUnicodeString (&fsname, ffai_buf.ffai.FileSystemName,
|
/* These are the minimal flags supported by NTFS since NT4. Every filesystem
|
||||||
ffai_buf.ffai.FileSystemNameLength);
|
not supporting these flags is not a native NTFS. We subsume them under
|
||||||
if (is_remote_drive ())
|
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. */
|
/* This always fails on NT4. */
|
||||||
status = NtQueryVolumeInformationFile (vol, &io, &ffoi, sizeof ffoi,
|
status = NtQueryVolumeInformationFile (vol, &io, &ffoi, sizeof ffoi,
|
||||||
FileFsObjectIdInformation);
|
FileFsObjectIdInformation);
|
||||||
|
@ -238,14 +249,17 @@ fs_info::update (PUNICODE_STRING upath, HANDLE in_vol)
|
||||||
samba_version (extended_info->samba_version);
|
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
|
/* Test for Samba on NT4 or for older Samba releases not supporting
|
||||||
extended info. */
|
extended info. */
|
||||||
&& !is_samba (RtlEqualUnicodeString (&fsname, &ro_u_ntfs, FALSE)
|
&& !is_samba (FS_IS_SAMBA)
|
||||||
&& FS_IS_SAMBA)
|
|
||||||
/* Netapp inode info is unusable. */
|
/* Netapp inode info is unusable. */
|
||||||
&& !is_netapp (RtlEqualUnicodeString (&fsname, &ro_u_ntfs, FALSE)
|
&& !is_netapp (FS_IS_NETAPP_DATAONTAP))
|
||||||
&& 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. */
|
/* Microsoft NFS needs distinct access methods for metadata. */
|
||||||
&& !is_nfs (RtlEqualUnicodeString (&fsname, &ro_u_nfs, FALSE))
|
&& !is_nfs (RtlEqualUnicodeString (&fsname, &ro_u_nfs, FALSE))
|
||||||
/* MVFS == Rational ClearCase remote filesystem. Has a couple of
|
/* 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)))
|
&& !is_unixfs (RtlEqualUnicodeString (&fsname, &ro_u_unixfs, FALSE)))
|
||||||
/* Known remote file system with buggy open calls. Further
|
/* Known remote file system with buggy open calls. Further
|
||||||
explanation in fhandler.cc (fhandler_disk_file::open). */
|
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 ()
|
if (!got_fs ()
|
||||||
&& !is_ntfs (RtlEqualUnicodeString (&fsname, &ro_u_ntfs, FALSE))
|
&& !is_ntfs (RtlEqualUnicodeString (&fsname, &ro_u_ntfs, FALSE))
|
||||||
&& !is_fat (RtlEqualUnicodePathPrefix (&fsname, &ro_u_fat, TRUE))
|
&& !is_fat (RtlEqualUnicodePathPrefix (&fsname, &ro_u_fat, TRUE))
|
||||||
&& !is_csc_cache (RtlEqualUnicodeString (&fsname, &ro_u_csc, FALSE))
|
&& !is_csc_cache (RtlEqualUnicodeString (&fsname, &ro_u_csc, FALSE))
|
||||||
&& is_cdrom (ffdi.DeviceType == FILE_DEVICE_CD_ROM))
|
&& is_cdrom (ffdi.DeviceType == FILE_DEVICE_CD_ROM))
|
||||||
{
|
|
||||||
is_udf (RtlEqualUnicodeString (&fsname, &ro_u_udf, FALSE));
|
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);
|
|
||||||
}
|
|
||||||
if (!got_fs ())
|
if (!got_fs ())
|
||||||
{
|
{
|
||||||
/* The filesystem name is only used in fillout_mntent and only if
|
/* 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 ());
|
hasgood_inode ((has_acls () && !is_netapp ()) || is_nfs ());
|
||||||
/* Case sensitivity is supported if FILE_CASE_SENSITIVE_SEARCH is set,
|
/* Case sensitivity is supported if FILE_CASE_SENSITIVE_SEARCH is set,
|
||||||
except on Samba which handles Windows clients case insensitive.
|
except on Samba which handles Windows clients case insensitive.
|
||||||
|
|
||||||
NFS doesn't set the FILE_CASE_SENSITIVE_SEARCH flag but is case
|
NFS doesn't set the FILE_CASE_SENSITIVE_SEARCH flag but is case
|
||||||
sensitive. */
|
sensitive.
|
||||||
caseinsensitive ((!(flags () & FILE_CASE_SENSITIVE_SEARCH) || is_samba ())
|
|
||||||
&& !is_nfs ());
|
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)
|
if (!in_vol)
|
||||||
NtClose (vol);
|
NtClose (vol);
|
||||||
|
@ -1405,28 +1427,25 @@ fillout_mntent (const char *native_path, const char *posix_path, unsigned flags)
|
||||||
RtlAppendUnicodeToString (&unat, L"\\");
|
RtlAppendUnicodeToString (&unat, L"\\");
|
||||||
mntinfo.update (&unat, NULL);
|
mntinfo.update (&unat, NULL);
|
||||||
|
|
||||||
if (mntinfo.is_ntfs ())
|
/* Order must be identical to mount.h, enum fs_info_type. */
|
||||||
strcpy (_my_tls.locals.mnt_type, (char *) "ntfs");
|
const char *fs_names[] = {
|
||||||
else if (mntinfo.is_fat ())
|
"none",
|
||||||
strcpy (_my_tls.locals.mnt_type, (char *) "vfat");
|
"vfat",
|
||||||
else if (mntinfo.is_samba())
|
"ntfs",
|
||||||
strcpy (_my_tls.locals.mnt_type, (char *) "smbfs");
|
"smbfs",
|
||||||
else if (mntinfo.is_nfs ())
|
"nfs",
|
||||||
strcpy (_my_tls.locals.mnt_type, (char *) "nfs");
|
"netapp",
|
||||||
else if (mntinfo.is_udf ())
|
"iso9660",
|
||||||
strcpy (_my_tls.locals.mnt_type, (char *) "udf");
|
"udf",
|
||||||
else if (mntinfo.is_cdrom ())
|
"csc-cache",
|
||||||
strcpy (_my_tls.locals.mnt_type, (char *) "iso9660");
|
"sunwnfs",
|
||||||
else if (mntinfo.is_netapp ())
|
"unixfs",
|
||||||
strcpy (_my_tls.locals.mnt_type, (char *) "netapp");
|
"mvfs",
|
||||||
else if (mntinfo.is_csc_cache ())
|
"cifs"
|
||||||
strcpy (_my_tls.locals.mnt_type, (char *) "csc-cache");
|
};
|
||||||
else if (mntinfo.is_mvfs ())
|
|
||||||
strcpy (_my_tls.locals.mnt_type, (char *) "mvfs");
|
if (mntinfo.what_fs () > 0 && mntinfo.what_fs () < max_fs_type)
|
||||||
else if (mntinfo.is_unixfs ())
|
strcpy (_my_tls.locals.mnt_type, fs_names[mntinfo.what_fs ()]);
|
||||||
strcpy (_my_tls.locals.mnt_type, (char *) "unixfs");
|
|
||||||
else if (mntinfo.is_sunwnfs ())
|
|
||||||
strcpy (_my_tls.locals.mnt_type, (char *) "sunwnfs");
|
|
||||||
else
|
else
|
||||||
strcpy (_my_tls.locals.mnt_type, mntinfo.fsname ());
|
strcpy (_my_tls.locals.mnt_type, mntinfo.fsname ());
|
||||||
|
|
||||||
|
|
|
@ -12,6 +12,29 @@ details. */
|
||||||
#ifndef _MOUNT_H
|
#ifndef _MOUNT_H
|
||||||
#define _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
|
class fs_info
|
||||||
{
|
{
|
||||||
struct status_flags
|
struct status_flags
|
||||||
|
@ -19,32 +42,17 @@ class fs_info
|
||||||
ULONG flags; /* Volume flags */
|
ULONG flags; /* Volume flags */
|
||||||
ULONG samba_version; /* Samba version if available */
|
ULONG samba_version; /* Samba version if available */
|
||||||
ULONG name_len; /* MaximumComponentNameLength */
|
ULONG name_len; /* MaximumComponentNameLength */
|
||||||
|
fs_info_type fs_type; /* Filesystem type */
|
||||||
unsigned is_remote_drive : 1;
|
unsigned is_remote_drive : 1;
|
||||||
unsigned has_acls : 1;
|
unsigned has_acls : 1;
|
||||||
unsigned hasgood_inode : 1;
|
unsigned hasgood_inode : 1;
|
||||||
unsigned caseinsensitive : 1;
|
unsigned caseinsensitive : 1;
|
||||||
union
|
unsigned has_buggy_open : 1;
|
||||||
{
|
unsigned has_buggy_fileid_dirinfo : 1;
|
||||||
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;
|
|
||||||
};
|
|
||||||
} status;
|
} status;
|
||||||
ULONG sernum;
|
ULONG sernum; /* Volume Serial Number */
|
||||||
char fsn[80];
|
char fsn[80]; /* Windows filesystem name */
|
||||||
unsigned long got_fs () { return status.fs_flags; }
|
unsigned long got_fs () const { return status.fs_type != none; }
|
||||||
|
|
||||||
public:
|
public:
|
||||||
void clear ()
|
void clear ()
|
||||||
|
@ -62,21 +70,24 @@ class fs_info
|
||||||
IMPLEMENT_STATUS_FLAG (bool, has_acls)
|
IMPLEMENT_STATUS_FLAG (bool, has_acls)
|
||||||
IMPLEMENT_STATUS_FLAG (bool, hasgood_inode)
|
IMPLEMENT_STATUS_FLAG (bool, hasgood_inode)
|
||||||
IMPLEMENT_STATUS_FLAG (bool, caseinsensitive)
|
IMPLEMENT_STATUS_FLAG (bool, caseinsensitive)
|
||||||
IMPLEMENT_STATUS_FLAG (bool, is_fat)
|
IMPLEMENT_STATUS_FLAG (bool, has_buggy_open)
|
||||||
IMPLEMENT_STATUS_FLAG (bool, is_ntfs)
|
IMPLEMENT_STATUS_FLAG (bool, has_buggy_fileid_dirinfo)
|
||||||
IMPLEMENT_STATUS_FLAG (bool, is_samba)
|
IMPLEMENT_FS_FLAG (is_fat, fat)
|
||||||
IMPLEMENT_STATUS_FLAG (bool, is_nfs)
|
IMPLEMENT_FS_FLAG (is_ntfs, ntfs)
|
||||||
IMPLEMENT_STATUS_FLAG (bool, is_netapp)
|
IMPLEMENT_FS_FLAG (is_samba, samba)
|
||||||
IMPLEMENT_STATUS_FLAG (bool, is_cdrom)
|
IMPLEMENT_FS_FLAG (is_nfs, nfs)
|
||||||
IMPLEMENT_STATUS_FLAG (bool, is_udf)
|
IMPLEMENT_FS_FLAG (is_netapp, netapp)
|
||||||
IMPLEMENT_STATUS_FLAG (bool, is_csc_cache)
|
IMPLEMENT_FS_FLAG (is_cdrom, cdrom)
|
||||||
IMPLEMENT_STATUS_FLAG (bool, is_sunwnfs)
|
IMPLEMENT_FS_FLAG (is_udf, udf)
|
||||||
IMPLEMENT_STATUS_FLAG (bool, is_unixfs)
|
IMPLEMENT_FS_FLAG (is_csc_cache, csc_cache)
|
||||||
IMPLEMENT_STATUS_FLAG (bool, is_mvfs)
|
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; }
|
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"; }
|
const char *fsname () const { return fsn[0] ? fsn : "unknown"; }
|
||||||
|
|
||||||
bool update (PUNICODE_STRING, HANDLE) __attribute__ ((regparm (3)));
|
bool update (PUNICODE_STRING, HANDLE) __attribute__ ((regparm (3)));
|
||||||
|
|
Loading…
Reference in New Issue