* mount.cc (struct opt): Add "dos" and "ihash" options.

(fillout_mntent): Ditto.
	* path.cc (path_conv::get_nt_native_path): Use path_conv's
	has_dos_filenames_only method.
	(path_conv::check): Add PATH_IHASH flag if FS has unreliable inode
	numbers.
	(symlink_info::check_shortcut): Or symlink flags to pflags.
	(symlink_info::check_sysfile): Ditto.  Change test accordingly.
	(symlink_info::check_reparse_point): Ditto.
	(symlink_info::check_nfs_symlink): Ditto.
	(symlink_info::check): Check PATH_DOS flag in call to get_nt_native_path
	to utilize mount flag.  Ditto in test for potential restarting.  Set
	PATH_DOS if FS only allows DOS filename rules.
	* path.h (enum path_types): Add PATH_DOS and PATH_IHASH.
	(path_conv::hasgood_inode): Check PATH_IHASH instead of
	fs.hasgood_inode.
	(path_conv::has_dos_filenames_only): New method.
	* include/sys/mount.h (MOUNT_DOS): New mount flag.
	(MOUNT_IHASH): Ditto.
This commit is contained in:
Corinna Vinschen 2010-04-29 10:38:05 +00:00
parent a82a8dcb4e
commit 5b4c992bf6
5 changed files with 52 additions and 12 deletions

View File

@ -1,3 +1,25 @@
2010-04-29 Corinna Vinschen <corinna@vinschen.de>
* mount.cc (struct opt): Add "dos" and "ihash" options.
(fillout_mntent): Ditto.
* path.cc (path_conv::get_nt_native_path): Use path_conv's
has_dos_filenames_only method.
(path_conv::check): Add PATH_IHASH flag if FS has unreliable inode
numbers.
(symlink_info::check_shortcut): Or symlink flags to pflags.
(symlink_info::check_sysfile): Ditto. Change test accordingly.
(symlink_info::check_reparse_point): Ditto.
(symlink_info::check_nfs_symlink): Ditto.
(symlink_info::check): Check PATH_DOS flag in call to get_nt_native_path
to utilize mount flag. Ditto in test for potential restarting. Set
PATH_DOS if FS only allows DOS filename rules.
* path.h (enum path_types): Add PATH_DOS and PATH_IHASH.
(path_conv::hasgood_inode): Check PATH_IHASH instead of
fs.hasgood_inode.
(path_conv::has_dos_filenames_only): New method.
* include/sys/mount.h (MOUNT_DOS): New mount flag.
(MOUNT_IHASH): Ditto.
2010-04-29 Corinna Vinschen <corinna@vinschen.de> 2010-04-29 Corinna Vinschen <corinna@vinschen.de>
* external.cc (cygwin_internal): Add CW_CVT_MNT_OPTS to allow mount * external.cc (cygwin_internal): Add CW_CVT_MNT_OPTS to allow mount

View File

@ -36,7 +36,10 @@ enum
MOUNT_NOPOSIX = 0x04000, /* Case insensitve path handling */ MOUNT_NOPOSIX = 0x04000, /* Case insensitve path handling */
MOUNT_OVERRIDE = 0x08000, /* Allow overriding of root */ MOUNT_OVERRIDE = 0x08000, /* Allow overriding of root */
MOUNT_IMMUTABLE = 0x10000, /* Mount point can't be changed */ MOUNT_IMMUTABLE = 0x10000, /* Mount point can't be changed */
MOUNT_AUTOMATIC = 0x20000 /* Mount point was added automatically */ MOUNT_AUTOMATIC = 0x20000, /* Mount point was added automatically */
MOUNT_DOS = 0x40000, /* convert leading spaces and trailing
dots and spaces to private use area */
MOUNT_IHASH = 0x80000 /* Enforce hash values for inode numbers */
}; };
int mount (const char *, const char *, unsigned __flags); int mount (const char *, const char *, unsigned __flags);

View File

@ -932,7 +932,9 @@ struct opt
{"auto", 0, 0}, {"auto", 0, 0},
{"binary", MOUNT_BINARY, 0}, {"binary", MOUNT_BINARY, 0},
{"cygexec", MOUNT_CYGWIN_EXEC, 0}, {"cygexec", MOUNT_CYGWIN_EXEC, 0},
{"dos", MOUNT_DOS, 0},
{"exec", MOUNT_EXEC, 0}, {"exec", MOUNT_EXEC, 0},
{"ihash", MOUNT_IHASH, 0},
{"noacl", MOUNT_NOACL, 0}, {"noacl", MOUNT_NOACL, 0},
{"nosuid", 0, 0}, {"nosuid", 0, 0},
{"notexec", MOUNT_NOTEXEC, 0}, {"notexec", MOUNT_NOTEXEC, 0},
@ -1553,6 +1555,12 @@ fillout_mntent (const char *native_path, const char *posix_path, unsigned flags)
if (flags & MOUNT_NOACL) if (flags & MOUNT_NOACL)
strcat (_my_tls.locals.mnt_opts, (char *) ",noacl"); strcat (_my_tls.locals.mnt_opts, (char *) ",noacl");
if (flags & MOUNT_DOS)
strcat (_my_tls.locals.mnt_opts, (char *) ",dos");
if (flags & MOUNT_IHASH)
strcat (_my_tls.locals.mnt_opts, (char *) ",ihash");
if (flags & MOUNT_NOPOSIX) if (flags & MOUNT_NOPOSIX)
strcat (_my_tls.locals.mnt_opts, (char *) ",posix=0"); strcat (_my_tls.locals.mnt_opts, (char *) ",posix=0");

View File

@ -457,7 +457,7 @@ path_conv::get_nt_native_path ()
uni_path.MaximumLength = (strlen (path) + 10) * sizeof (WCHAR); uni_path.MaximumLength = (strlen (path) + 10) * sizeof (WCHAR);
wide_path = (PWCHAR) cmalloc_abort (HEAP_STR, uni_path.MaximumLength); wide_path = (PWCHAR) cmalloc_abort (HEAP_STR, uni_path.MaximumLength);
uni_path.Buffer = wide_path; uni_path.Buffer = wide_path;
::get_nt_native_path (path, uni_path, fs.has_dos_filenames_only ()); ::get_nt_native_path (path, uni_path, has_dos_filenames_only ());
} }
return &uni_path; return &uni_path;
} }
@ -848,6 +848,10 @@ is_virtual_symlink:
{ {
fileattr = sym.fileattr; fileattr = sym.fileattr;
path_flags = sym.pflags; path_flags = sym.pflags;
/* If the FS has been found to have unrelibale inodes, note
that in path_flags. */
if (!fs.hasgood_inode ())
path_flags |= PATH_IHASH;
/* If the OS is caseinsensitive or the FS is caseinsensitive, /* If the OS is caseinsensitive or the FS is caseinsensitive,
don't handle path casesensitive. */ don't handle path casesensitive. */
if (cygwin_shared->obcaseinsensitive || fs.caseinsensitive ()) if (cygwin_shared->obcaseinsensitive || fs.caseinsensitive ())
@ -1754,7 +1758,7 @@ symlink_info::check_shortcut (HANDLE in_h)
} }
} }
if (res) /* It's a symlink. */ if (res) /* It's a symlink. */
pflags = PATH_SYMLINK | PATH_LNK; pflags |= PATH_SYMLINK | PATH_LNK;
out: out:
NtClose (h); NtClose (h);
@ -1794,7 +1798,7 @@ symlink_info::check_sysfile (HANDLE in_h)
&& memcmp (cookie_buf, SYMLINK_COOKIE, sizeof (cookie_buf)) == 0) && memcmp (cookie_buf, SYMLINK_COOKIE, sizeof (cookie_buf)) == 0)
{ {
/* It's a symlink. */ /* It's a symlink. */
pflags = PATH_SYMLINK; pflags |= PATH_SYMLINK;
} }
else if (io.Information == sizeof (cookie_buf) else if (io.Information == sizeof (cookie_buf)
&& memcmp (cookie_buf, SOCKET_COOKIE, sizeof (cookie_buf)) == 0) && memcmp (cookie_buf, SOCKET_COOKIE, sizeof (cookie_buf)) == 0)
@ -1804,7 +1808,7 @@ symlink_info::check_sysfile (HANDLE in_h)
sizeof (INTERIX_SYMLINK_COOKIE) - 1) == 0) sizeof (INTERIX_SYMLINK_COOKIE) - 1) == 0)
{ {
/* It's an Interix symlink. */ /* It's an Interix symlink. */
pflags = PATH_SYMLINK; pflags |= PATH_SYMLINK;
interix_symlink = true; interix_symlink = true;
/* Interix symlink cookies are shorter than Cygwin symlink cookies, so /* Interix symlink cookies are shorter than Cygwin symlink cookies, so
in case of an Interix symlink cooky we have read too far into the in case of an Interix symlink cooky we have read too far into the
@ -1813,7 +1817,7 @@ symlink_info::check_sysfile (HANDLE in_h)
fpi.CurrentByteOffset.QuadPart = sizeof (INTERIX_SYMLINK_COOKIE) - 1; fpi.CurrentByteOffset.QuadPart = sizeof (INTERIX_SYMLINK_COOKIE) - 1;
NtSetInformationFile (h, &io, &fpi, sizeof fpi, FilePositionInformation); NtSetInformationFile (h, &io, &fpi, sizeof fpi, FilePositionInformation);
} }
if (pflags == PATH_SYMLINK) if (pflags & PATH_SYMLINK)
{ {
status = NtReadFile (h, NULL, NULL, NULL, &io, srcbuf, status = NtReadFile (h, NULL, NULL, NULL, &io, srcbuf,
NT_MAX_PATH, NULL, NULL); NT_MAX_PATH, NULL, NULL);
@ -1898,7 +1902,7 @@ symlink_info::check_reparse_point (HANDLE h)
} }
sys_wcstombs (srcbuf, SYMLINK_MAX + 7, subst.Buffer, sys_wcstombs (srcbuf, SYMLINK_MAX + 7, subst.Buffer,
subst.Length / sizeof (WCHAR)); subst.Length / sizeof (WCHAR));
pflags = PATH_SYMLINK | PATH_REP; pflags |= PATH_SYMLINK | PATH_REP;
fileattr &= ~FILE_ATTRIBUTE_DIRECTORY; fileattr &= ~FILE_ATTRIBUTE_DIRECTORY;
return posixify (srcbuf); return posixify (srcbuf);
} }
@ -1937,7 +1941,7 @@ symlink_info::check_nfs_symlink (HANDLE h)
(pffei->EaName + pffei->EaNameLength + 1); (pffei->EaName + pffei->EaNameLength + 1);
res = sys_wcstombs (contents, SYMLINK_MAX + 1, res = sys_wcstombs (contents, SYMLINK_MAX + 1,
spath, pffei->EaValueLength); spath, pffei->EaValueLength);
pflags = PATH_SYMLINK; pflags |= PATH_SYMLINK;
} }
return res; return res;
} }
@ -2236,7 +2240,7 @@ restart:
bool no_ea = false; bool no_ea = false;
error = 0; error = 0;
get_nt_native_path (suffix.path, upath, fs.has_dos_filenames_only ()); get_nt_native_path (suffix.path, upath, pflags & PATH_DOS);
if (h) if (h)
{ {
NtClose (h); NtClose (h);
@ -2316,8 +2320,7 @@ restart:
we encountered a STATUS_OBJECT_NAME_NOT_FOUND *and* we didn't we encountered a STATUS_OBJECT_NAME_NOT_FOUND *and* we didn't
already attach a suffix *and* the above special case for UDF already attach a suffix *and* the above special case for UDF
on XP didn't succeeed. */ on XP didn't succeeed. */
if (!restarted && !*ext_here if (!restarted && !*ext_here && !(pflags & PATH_DOS) && !fs.inited ())
&& (!fs.inited () || fs.has_dos_filenames_only ()))
{ {
/* Check for trailing dot or space or leading space in /* Check for trailing dot or space or leading space in
last component. */ last component. */
@ -2340,6 +2343,7 @@ restart:
/* If so, try again. Since we now know the FS, the /* If so, try again. Since we now know the FS, the
filenames will be tweaked to follow DOS rules via the filenames will be tweaked to follow DOS rules via the
third parameter in the call to get_nt_native_path. */ third parameter in the call to get_nt_native_path. */
pflags |= PATH_DOS;
restarted = true; restarted = true;
goto restart; goto restart;
} }

View File

@ -75,6 +75,8 @@ enum path_types
PATH_RO = MOUNT_RO, PATH_RO = MOUNT_RO,
PATH_NOACL = MOUNT_NOACL, PATH_NOACL = MOUNT_NOACL,
PATH_NOPOSIX = MOUNT_NOPOSIX, PATH_NOPOSIX = MOUNT_NOPOSIX,
PATH_DOS = MOUNT_DOS,
PATH_IHASH = MOUNT_IHASH,
PATH_ALL_EXEC = (PATH_CYGWIN_EXEC | PATH_EXEC), PATH_ALL_EXEC = (PATH_CYGWIN_EXEC | PATH_EXEC),
PATH_NO_ACCESS_CHECK = PC_NO_ACCESS_CHECK, PATH_NO_ACCESS_CHECK = PC_NO_ACCESS_CHECK,
PATH_LNK = 0x01000000, PATH_LNK = 0x01000000,
@ -106,9 +108,10 @@ class path_conv
bool isremote () const {return fs.is_remote_drive ();} bool isremote () const {return fs.is_remote_drive ();}
ULONG objcaseinsensitive () const {return caseinsensitive;} ULONG objcaseinsensitive () const {return caseinsensitive;}
bool has_acls () const {return !(path_flags & PATH_NOACL) && fs.has_acls (); } bool has_acls () const {return !(path_flags & PATH_NOACL) && fs.has_acls (); }
bool hasgood_inode () const {return fs.hasgood_inode (); } bool hasgood_inode () const {return !(path_flags & PATH_IHASH); }
bool isgood_inode (__ino64_t ino) const; bool isgood_inode (__ino64_t ino) const;
int has_symlinks () const {return path_flags & PATH_HAS_SYMLINKS;} int has_symlinks () const {return path_flags & PATH_HAS_SYMLINKS;}
int has_dos_filenames_only () const {return path_flags & PATH_DOS;}
int has_buggy_open () const {return fs.has_buggy_open ();} int has_buggy_open () const {return fs.has_buggy_open ();}
int has_buggy_fileid_dirinfo () const {return fs.has_buggy_fileid_dirinfo ();} int has_buggy_fileid_dirinfo () const {return fs.has_buggy_fileid_dirinfo ();}
int has_buggy_basic_info () const {return fs.has_buggy_basic_info ();} int has_buggy_basic_info () const {return fs.has_buggy_basic_info ();}