From 0fb0fb8391f2e78177585c8e4842d0fce79e4408 Mon Sep 17 00:00:00 2001 From: Corinna Vinschen Date: Fri, 17 Jul 2009 09:00:19 +0000 Subject: [PATCH] * globals.cc: Improve comment on R/O UNICODE_STRINGs. * mount.h (class fs_info): Add is_mvfs bit. * mount.cc (fs_info::update): Recognize MVFS remote filesystem. (fillout_mntent): Reorder filesystem checks for speed. Add mvfs, unixfs, and sunwnfs filesystem types. * path.h (class path_conv): Add fs_is_mvfs method. * path.cc (symlink_worker): On MVFS, always create symlinks as Windows shortcuts. Explain why. --- winsup/cygwin/ChangeLog | 11 +++++++++++ winsup/cygwin/globals.cc | 8 +++++++- winsup/cygwin/mount.cc | 24 +++++++++++++++++------- winsup/cygwin/mount.h | 2 ++ winsup/cygwin/path.cc | 15 ++++++++++----- winsup/cygwin/path.h | 1 + 6 files changed, 48 insertions(+), 13 deletions(-) diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog index 3fd808ea8..7f4abc994 100644 --- a/winsup/cygwin/ChangeLog +++ b/winsup/cygwin/ChangeLog @@ -1,3 +1,14 @@ +2009-07-17 Corinna Vinschen + + * globals.cc: Improve comment on R/O UNICODE_STRINGs. + * mount.h (class fs_info): Add is_mvfs bit. + * mount.cc (fs_info::update): Recognize MVFS remote filesystem. + (fillout_mntent): Reorder filesystem checks for speed. Add + mvfs, unixfs, and sunwnfs filesystem types. + * path.h (class path_conv): Add fs_is_mvfs method. + * path.cc (symlink_worker): On MVFS, always create symlinks as + Windows shortcuts. Explain why. + 2009-07-16 Corinna Vinschen * syscalls.cc (unlink_nt): First remove the R/O DOS attribute with diff --git a/winsup/cygwin/globals.cc b/winsup/cygwin/globals.cc index ef1753425..ccfc20830 100644 --- a/winsup/cygwin/globals.cc +++ b/winsup/cygwin/globals.cc @@ -72,7 +72,13 @@ char NO_COPY almost_null[1]; char *old_title; -/* Heavily-used const UNICODE_STRINGs are defined here once. */ +/* Heavily-used const UNICODE_STRINGs are defined here once. The idea is a + speed improvement by not having to initialize a UNICODE_STRING every time + we make a string comparison. The strings are not defined as const, + because the respective NT functions are not taking const arguments + and doing so here results in lots of extra casts for no good reason. + Rather, the strings are placed in the R/O section .rdata, so we get + a SEGV if some code erroneously tries to overwrite these strings. */ #define _ROU(_s) \ { Length: sizeof (_s) - sizeof (WCHAR), \ MaximumLength: sizeof (_s), \ diff --git a/winsup/cygwin/mount.cc b/winsup/cygwin/mount.cc index 02c60deec..0717f8eb6 100644 --- a/winsup/cygwin/mount.cc +++ b/winsup/cygwin/mount.cc @@ -240,6 +240,10 @@ fs_info::update (PUNICODE_STRING upath, HANDLE in_vol) && FS_IS_NETAPP_DATAONTAP) /* 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 + drawbacks, like not supporting DOS attributes other than R/O + and stuff like that. */ + && !is_mvfs (RtlEqualUnicodePathPrefix (&fsname, &ro_u_mvfs, FALSE)) /* Known remote file system which can't handle calls to NtQueryDirectoryFile(FileIdBothDirectoryInformation) */ && !is_unixfs (RtlEqualUnicodeString (&fsname, &ro_u_unixfs, FALSE))) @@ -1386,22 +1390,28 @@ fillout_mntent (const char *native_path, const char *posix_path, unsigned flags) RtlAppendUnicodeToString (&unat, L"\\"); mntinfo.update (&unat, NULL); - if (mntinfo.is_samba()) + 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_fat ()) - strcpy (_my_tls.locals.mnt_type, (char *) "vfat"); - else if (mntinfo.is_ntfs ()) - strcpy (_my_tls.locals.mnt_type, (char *) "ntfs"); - else if (mntinfo.is_netapp ()) - strcpy (_my_tls.locals.mnt_type, (char *) "netapp"); 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"); else strcpy (_my_tls.locals.mnt_type, (char *) "unknown"); diff --git a/winsup/cygwin/mount.h b/winsup/cygwin/mount.h index bc6de12b0..c169ca33b 100644 --- a/winsup/cygwin/mount.h +++ b/winsup/cygwin/mount.h @@ -37,6 +37,7 @@ class fs_info unsigned is_csc_cache : 1; unsigned is_sunwnfs : 1; unsigned is_unixfs : 1; + unsigned is_mvfs : 1; }; unsigned long fs_flags; }; @@ -65,6 +66,7 @@ class fs_info 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) ULONG serial_number () const { return sernum; } int has_buggy_open () const {return is_sunwnfs ();} diff --git a/winsup/cygwin/path.cc b/winsup/cygwin/path.cc index 20d750303..bd9b90ae9 100644 --- a/winsup/cygwin/path.cc +++ b/winsup/cygwin/path.cc @@ -1367,6 +1367,7 @@ symlink_worker (const char *oldpath, const char *newpath, bool use_winsym, HANDLE fh; tmp_pathbuf tp; unsigned check_opt; + bool mk_winsym = use_winsym; /* POSIX says that empty 'newpath' is invalid input while empty 'oldpath' is valid -- it's symlink resolver job to verify if @@ -1397,7 +1398,11 @@ symlink_worker (const char *oldpath, const char *newpath, bool use_winsym, check_opt = PC_SYM_NOFOLLOW | PC_POSIX | (isdevice ? PC_NOWARN : 0); /* We need the normalized full path below. */ win32_newpath.check (newpath, check_opt, stat_suffixes); - if (use_winsym && !win32_newpath.exists () + /* MVFS doesn't handle the SYSTEM DOS attribute, but it handles the R/O + attribute. Therefore we create symlinks on MVFS always as shortcuts. */ + mk_winsym |= win32_newpath.fs_is_mvfs (); + + if (mk_winsym && !win32_newpath.exists () && (isdevice || !win32_newpath.fs_is_nfs ())) { char *newplnk = tp.c_get (); @@ -1449,7 +1454,7 @@ symlink_worker (const char *oldpath, const char *newpath, bool use_winsym, goto done; } - if (use_winsym) + if (mk_winsym) { ITEMIDLIST *pidl = NULL; size_t full_len = 0; @@ -1634,8 +1639,8 @@ symlink_worker (const char *oldpath, const char *newpath, bool use_winsym, status = NtWriteFile (fh, NULL, NULL, NULL, &io, buf, cp - buf, NULL, NULL); if (NT_SUCCESS (status) && io.Information == (ULONG) (cp - buf)) { - status = NtSetAttributesFile (fh, use_winsym ? FILE_ATTRIBUTE_READONLY - : FILE_ATTRIBUTE_SYSTEM); + status = NtSetAttributesFile (fh, mk_winsym ? FILE_ATTRIBUTE_READONLY + : FILE_ATTRIBUTE_SYSTEM); if (!NT_SUCCESS (status)) debug_printf ("Setting attributes failed, status = %p", status); res = 0; @@ -1653,7 +1658,7 @@ symlink_worker (const char *oldpath, const char *newpath, bool use_winsym, done: syscall_printf ("%d = symlink_worker (%s, %s, %d, %d)", res, oldpath, - newpath, use_winsym, isdevice); + newpath, mk_winsym, isdevice); return res; } diff --git a/winsup/cygwin/path.h b/winsup/cygwin/path.h index 1159ba8d4..952e0584a 100644 --- a/winsup/cygwin/path.h +++ b/winsup/cygwin/path.h @@ -231,6 +231,7 @@ class path_conv bool fs_is_nfs () const {return fs.is_nfs ();} bool fs_is_netapp () const {return fs.is_netapp ();} bool fs_is_cdrom () const {return fs.is_cdrom ();} + bool fs_is_mvfs () const {return fs.is_mvfs ();} ULONG fs_serial_number () const {return fs.serial_number ();} void set_path (const char *p) {strcpy (path, p);} void fillin (HANDLE h);