* 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:
		| @@ -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 | ||||||
|   | |||||||
| @@ -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); | ||||||
|   | |||||||
| @@ -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"); | ||||||
|  |  | ||||||
|   | |||||||
| @@ -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; | ||||||
| 		    } | 		    } | ||||||
|   | |||||||
| @@ -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 ();} | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user