* 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.
This commit is contained in:
		| @@ -1,3 +1,14 @@ | |||||||
|  | 2009-07-17  Corinna Vinschen  <corinna@vinschen.de> | ||||||
|  |  | ||||||
|  | 	* 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  <corinna@vinschen.de> | 2009-07-16  Corinna Vinschen  <corinna@vinschen.de> | ||||||
|  |  | ||||||
| 	* syscalls.cc (unlink_nt): First remove the R/O DOS attribute with | 	* syscalls.cc (unlink_nt): First remove the R/O DOS attribute with | ||||||
|   | |||||||
| @@ -72,7 +72,13 @@ char NO_COPY almost_null[1]; | |||||||
|  |  | ||||||
| char *old_title; | 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) \ | #define _ROU(_s) \ | ||||||
|         { Length: sizeof (_s) - sizeof (WCHAR), \ |         { Length: sizeof (_s) - sizeof (WCHAR), \ | ||||||
|           MaximumLength: sizeof (_s), \ |           MaximumLength: sizeof (_s), \ | ||||||
|   | |||||||
| @@ -240,6 +240,10 @@ fs_info::update (PUNICODE_STRING upath, HANDLE in_vol) | |||||||
| 			 && FS_IS_NETAPP_DATAONTAP) | 			 && FS_IS_NETAPP_DATAONTAP) | ||||||
| 	  /* 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 | ||||||
|  | 	     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 | 	  /* Known remote file system which can't handle calls to | ||||||
| 	     NtQueryDirectoryFile(FileIdBothDirectoryInformation) */ | 	     NtQueryDirectoryFile(FileIdBothDirectoryInformation) */ | ||||||
| 	  && !is_unixfs (RtlEqualUnicodeString (&fsname, &ro_u_unixfs, FALSE))) | 	  && !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"\\"); |     RtlAppendUnicodeToString (&unat, L"\\"); | ||||||
|   mntinfo.update (&unat, NULL); |   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"); |     strcpy (_my_tls.locals.mnt_type, (char *) "smbfs"); | ||||||
|   else if (mntinfo.is_nfs ()) |   else if (mntinfo.is_nfs ()) | ||||||
|     strcpy (_my_tls.locals.mnt_type, (char *) "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 ()) |   else if (mntinfo.is_udf ()) | ||||||
|     strcpy (_my_tls.locals.mnt_type, (char *) "udf"); |     strcpy (_my_tls.locals.mnt_type, (char *) "udf"); | ||||||
|   else if (mntinfo.is_cdrom ()) |   else if (mntinfo.is_cdrom ()) | ||||||
|     strcpy (_my_tls.locals.mnt_type, (char *) "iso9660"); |     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 ()) |   else if (mntinfo.is_csc_cache ()) | ||||||
|     strcpy (_my_tls.locals.mnt_type, (char *) "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 |   else | ||||||
|     strcpy (_my_tls.locals.mnt_type, (char *) "unknown"); |     strcpy (_my_tls.locals.mnt_type, (char *) "unknown"); | ||||||
|  |  | ||||||
|   | |||||||
| @@ -37,6 +37,7 @@ class fs_info | |||||||
| 	unsigned is_csc_cache		: 1; | 	unsigned is_csc_cache		: 1; | ||||||
| 	unsigned is_sunwnfs		: 1; | 	unsigned is_sunwnfs		: 1; | ||||||
| 	unsigned is_unixfs		: 1; | 	unsigned is_unixfs		: 1; | ||||||
|  | 	unsigned is_mvfs		: 1; | ||||||
|       }; |       }; | ||||||
|       unsigned long fs_flags; |       unsigned long fs_flags; | ||||||
|     }; |     }; | ||||||
| @@ -65,6 +66,7 @@ class fs_info | |||||||
|   IMPLEMENT_STATUS_FLAG (bool, is_csc_cache) |   IMPLEMENT_STATUS_FLAG (bool, is_csc_cache) | ||||||
|   IMPLEMENT_STATUS_FLAG (bool, is_sunwnfs) |   IMPLEMENT_STATUS_FLAG (bool, is_sunwnfs) | ||||||
|   IMPLEMENT_STATUS_FLAG (bool, is_unixfs) |   IMPLEMENT_STATUS_FLAG (bool, is_unixfs) | ||||||
|  |   IMPLEMENT_STATUS_FLAG (bool, is_mvfs) | ||||||
|   ULONG serial_number () const { return sernum; } |   ULONG serial_number () const { return sernum; } | ||||||
|  |  | ||||||
|   int has_buggy_open () const {return is_sunwnfs ();} |   int has_buggy_open () const {return is_sunwnfs ();} | ||||||
|   | |||||||
| @@ -1367,6 +1367,7 @@ symlink_worker (const char *oldpath, const char *newpath, bool use_winsym, | |||||||
|   HANDLE fh; |   HANDLE fh; | ||||||
|   tmp_pathbuf tp; |   tmp_pathbuf tp; | ||||||
|   unsigned check_opt; |   unsigned check_opt; | ||||||
|  |   bool mk_winsym = use_winsym; | ||||||
|  |  | ||||||
|   /* POSIX says that empty 'newpath' is invalid input while empty |   /* POSIX says that empty 'newpath' is invalid input while empty | ||||||
|      'oldpath' is valid -- it's symlink resolver job to verify if |      '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); |   check_opt = PC_SYM_NOFOLLOW | PC_POSIX | (isdevice ? PC_NOWARN : 0); | ||||||
|   /* We need the normalized full path below. */ |   /* We need the normalized full path below. */ | ||||||
|   win32_newpath.check (newpath, check_opt, stat_suffixes); |   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 ())) |       && (isdevice || !win32_newpath.fs_is_nfs ())) | ||||||
|     { |     { | ||||||
|       char *newplnk = tp.c_get (); |       char *newplnk = tp.c_get (); | ||||||
| @@ -1449,7 +1454,7 @@ symlink_worker (const char *oldpath, const char *newpath, bool use_winsym, | |||||||
|       goto done; |       goto done; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|   if (use_winsym) |   if (mk_winsym) | ||||||
|     { |     { | ||||||
|       ITEMIDLIST *pidl = NULL; |       ITEMIDLIST *pidl = NULL; | ||||||
|       size_t full_len = 0; |       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); |   status = NtWriteFile (fh, NULL, NULL, NULL, &io, buf, cp - buf, NULL, NULL); | ||||||
|   if (NT_SUCCESS (status) && io.Information == (ULONG) (cp - buf)) |   if (NT_SUCCESS (status) && io.Information == (ULONG) (cp - buf)) | ||||||
|     { |     { | ||||||
|       status = NtSetAttributesFile (fh, use_winsym ? FILE_ATTRIBUTE_READONLY |       status = NtSetAttributesFile (fh, mk_winsym ? FILE_ATTRIBUTE_READONLY | ||||||
| 						   : FILE_ATTRIBUTE_SYSTEM); | 						  : FILE_ATTRIBUTE_SYSTEM); | ||||||
|       if (!NT_SUCCESS (status)) |       if (!NT_SUCCESS (status)) | ||||||
| 	debug_printf ("Setting attributes failed, status = %p", status); | 	debug_printf ("Setting attributes failed, status = %p", status); | ||||||
|       res = 0; |       res = 0; | ||||||
| @@ -1653,7 +1658,7 @@ symlink_worker (const char *oldpath, const char *newpath, bool use_winsym, | |||||||
|  |  | ||||||
| done: | done: | ||||||
|   syscall_printf ("%d = symlink_worker (%s, %s, %d, %d)", res, oldpath, |   syscall_printf ("%d = symlink_worker (%s, %s, %d, %d)", res, oldpath, | ||||||
| 		  newpath, use_winsym, isdevice); | 		  newpath, mk_winsym, isdevice); | ||||||
|   return res; |   return res; | ||||||
| } | } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -231,6 +231,7 @@ class path_conv | |||||||
|   bool fs_is_nfs () const {return fs.is_nfs ();} |   bool fs_is_nfs () const {return fs.is_nfs ();} | ||||||
|   bool fs_is_netapp () const {return fs.is_netapp ();} |   bool fs_is_netapp () const {return fs.is_netapp ();} | ||||||
|   bool fs_is_cdrom () const {return fs.is_cdrom ();} |   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 ();} |   ULONG fs_serial_number () const {return fs.serial_number ();} | ||||||
|   void set_path (const char *p) {strcpy (path, p);} |   void set_path (const char *p) {strcpy (path, p);} | ||||||
|   void fillin (HANDLE h); |   void fillin (HANDLE h); | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user