Browse Source

[PATCH] cifs: character mapping of special characters (part 3 of 3)

Signed-off-by: Steve French (sfrench@us.ibm.com)
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Steve French 20 years ago
parent
commit
737b758c96
14 changed files with 337 additions and 332 deletions
  1. 1 1
      fs/cifs/CHANGES
  2. 2 2
      fs/cifs/README
  3. 3 0
      fs/cifs/TODO
  4. 2 2
      fs/cifs/cifsfs.c
  5. 61 42
      fs/cifs/cifsproto.h
  6. 108 118
      fs/cifs/cifssmb.c
  7. 13 12
      fs/cifs/connect.c
  8. 17 91
      fs/cifs/dir.c
  9. 2 1
      fs/cifs/fcntl.c
  10. 7 3
      fs/cifs/file.c
  11. 78 28
      fs/cifs/inode.c
  12. 14 4
      fs/cifs/link.c
  13. 4 18
      fs/cifs/readdir.c
  14. 25 10
      fs/cifs/xattr.c

+ 1 - 1
fs/cifs/CHANGES

@@ -9,7 +9,7 @@ POSIX ACL capability bit. Fix packet signing when multiuser mounting with
 different users from the same client to the same server. Fix oops in
 different users from the same client to the same server. Fix oops in
 cifs_close. Add mount option for remapping reserved characters in
 cifs_close. Add mount option for remapping reserved characters in
 filenames (also allow recognizing files with created by SFU which have any
 filenames (also allow recognizing files with created by SFU which have any
-of these seven reserved characters to be recognized).
+of these seven reserved characters, except backslash, to be recognized).
 
 
 Version 1.31
 Version 1.31
 ------------
 ------------

+ 2 - 2
fs/cifs/README

@@ -376,8 +376,8 @@ A partial list of the supported mount options follows:
 		attributes) to the server (default) e.g. via setfattr 
 		attributes) to the server (default) e.g. via setfattr 
 		and getfattr utilities. 
 		and getfattr utilities. 
   nouser_xattr  Do not allow getfattr/setfattr to get/set xattrs 
   nouser_xattr  Do not allow getfattr/setfattr to get/set xattrs 
-  mapchars      Translate the seven reserved characters 
-			*?<>|:\	
+  mapchars      Translate six of the seven reserved characters (not backslash)
+			*?<>|:
 		to the remap range (above 0xF000), which also
 		to the remap range (above 0xF000), which also
 		allows the CIFS client to recognize files created with
 		allows the CIFS client to recognize files created with
 		such characters by Windows's POSIX emulation. This can
 		such characters by Windows's POSIX emulation. This can

+ 3 - 0
fs/cifs/TODO

@@ -67,6 +67,9 @@ q) implement support for security and trusted categories of xattrs
 
 
 r) Implement O_DIRECT flag on open (already supported on mount)
 r) Implement O_DIRECT flag on open (already supported on mount)
 
 
+s) Allow remapping of last remaining character (\) to +0xF000 which
+(this character is valid for POSIX but not for Windows)
+
 KNOWN BUGS (updated April 3, 2005)
 KNOWN BUGS (updated April 3, 2005)
 ====================================
 ====================================
 See http://bugzilla.samba.org - search on product "CifsVFS" for
 See http://bugzilla.samba.org - search on product "CifsVFS" for

+ 2 - 2
fs/cifs/cifsfs.c

@@ -191,13 +191,13 @@ cifs_statfs(struct super_block *sb, struct kstatfs *buf)
 #ifdef CONFIG_CIFS_EXPERIMENTAL
 #ifdef CONFIG_CIFS_EXPERIMENTAL
 /* BB we could add a second check for a QFS Unix capability bit */
 /* BB we could add a second check for a QFS Unix capability bit */
     if (pTcon->ses->capabilities & CAP_UNIX)
     if (pTcon->ses->capabilities & CAP_UNIX)
-	    rc = CIFSSMBQFSPosixInfo(xid, pTcon, buf, cifs_sb->local_nls);
+	    rc = CIFSSMBQFSPosixInfo(xid, pTcon, buf);
 
 
     /* Only need to call the old QFSInfo if failed
     /* Only need to call the old QFSInfo if failed
     on newer one */
     on newer one */
     if(rc)
     if(rc)
 #endif /* CIFS_EXPERIMENTAL */
 #endif /* CIFS_EXPERIMENTAL */
-	rc = CIFSSMBQFSInfo(xid, pTcon, buf, cifs_sb->local_nls);
+	rc = CIFSSMBQFSInfo(xid, pTcon, buf);
 
 
 	/*     
 	/*     
 	   int f_type;
 	   int f_type;

+ 61 - 42
fs/cifs/cifsproto.h

@@ -57,10 +57,11 @@ extern int decode_negTokenInit(unsigned char *security_blob, int length,
 extern int cifs_inet_pton(int, char * source, void *dst);
 extern int cifs_inet_pton(int, char * source, void *dst);
 extern int map_smb_to_linux_error(struct smb_hdr *smb);
 extern int map_smb_to_linux_error(struct smb_hdr *smb);
 extern void header_assemble(struct smb_hdr *, char /* command */ ,
 extern void header_assemble(struct smb_hdr *, char /* command */ ,
-			const struct cifsTconInfo *, int
-			/* length of fixed section (word count) in two byte units  */
+			const struct cifsTconInfo *, int /* specifies length
+			    of fixed section (word count) in two byte units */
 			);
 			);
-extern struct oplock_q_entry * AllocOplockQEntry(struct inode *, u16, struct cifsTconInfo *);
+extern struct oplock_q_entry * AllocOplockQEntry(struct inode *, u16, 
+						 struct cifsTconInfo *);
 extern void DeleteOplockQEntry(struct oplock_q_entry *);
 extern void DeleteOplockQEntry(struct oplock_q_entry *);
 extern struct timespec cifs_NTtimeToUnix(u64 /* utc nanoseconds since 1601 */ );
 extern struct timespec cifs_NTtimeToUnix(u64 /* utc nanoseconds since 1601 */ );
 extern u64 cifs_UnixTimeToNT(struct timespec);
 extern u64 cifs_UnixTimeToNT(struct timespec);
@@ -88,7 +89,7 @@ extern int CIFSTCon(unsigned int xid, struct cifsSesInfo *ses,
 
 
 extern int CIFSFindFirst(const int xid, struct cifsTconInfo *tcon,
 extern int CIFSFindFirst(const int xid, struct cifsTconInfo *tcon,
             const char *searchName, const struct nls_table *nls_codepage,
             const char *searchName, const struct nls_table *nls_codepage,
-            __u16 *searchHandle, struct cifs_search_info * psrch_inf);
+            __u16 *searchHandle, struct cifs_search_info * psrch_inf, int map);
 
 
 extern int CIFSFindNext(const int xid, struct cifsTconInfo *tcon,
 extern int CIFSFindNext(const int xid, struct cifsTconInfo *tcon,
             __u16 searchHandle, struct cifs_search_info * psrch_inf);
             __u16 searchHandle, struct cifs_search_info * psrch_inf);
@@ -99,42 +100,42 @@ extern int CIFSFindClose(const int, struct cifsTconInfo *tcon,
 extern int CIFSSMBQPathInfo(const int xid, struct cifsTconInfo *tcon,
 extern int CIFSSMBQPathInfo(const int xid, struct cifsTconInfo *tcon,
 			const unsigned char *searchName,
 			const unsigned char *searchName,
 			FILE_ALL_INFO * findData,
 			FILE_ALL_INFO * findData,
-			const struct nls_table *nls_codepage);
+			const struct nls_table *nls_codepage, int remap);
 
 
 extern int CIFSSMBUnixQPathInfo(const int xid,
 extern int CIFSSMBUnixQPathInfo(const int xid,
 			struct cifsTconInfo *tcon,
 			struct cifsTconInfo *tcon,
 			const unsigned char *searchName,
 			const unsigned char *searchName,
 			FILE_UNIX_BASIC_INFO * pFindData,
 			FILE_UNIX_BASIC_INFO * pFindData,
-			const struct nls_table *nls_codepage);
+			const struct nls_table *nls_codepage, int remap);
 
 
 extern int CIFSGetDFSRefer(const int xid, struct cifsSesInfo *ses,
 extern int CIFSGetDFSRefer(const int xid, struct cifsSesInfo *ses,
 			const unsigned char *searchName,
 			const unsigned char *searchName,
 			unsigned char **targetUNCs,
 			unsigned char **targetUNCs,
 			unsigned int *number_of_UNC_in_array,
 			unsigned int *number_of_UNC_in_array,
-			const struct nls_table *nls_codepage);
+			const struct nls_table *nls_codepage, int remap);
 
 
 extern int connect_to_dfs_path(int xid, struct cifsSesInfo *pSesInfo,
 extern int connect_to_dfs_path(int xid, struct cifsSesInfo *pSesInfo,
 			const char *old_path,
 			const char *old_path,
-			const struct nls_table *nls_codepage);
+			const struct nls_table *nls_codepage, int remap);
 extern int get_dfs_path(int xid, struct cifsSesInfo *pSesInfo,
 extern int get_dfs_path(int xid, struct cifsSesInfo *pSesInfo,
-			const char *old_path, const struct nls_table *nls_codepage, 
-			unsigned int *pnum_referrals, unsigned char ** preferrals);
+			const char *old_path, 
+			const struct nls_table *nls_codepage,
+			unsigned int *pnum_referrals, 
+			unsigned char ** preferrals,
+			int remap);
 extern int CIFSSMBQFSInfo(const int xid, struct cifsTconInfo *tcon,
 extern int CIFSSMBQFSInfo(const int xid, struct cifsTconInfo *tcon,
-			struct kstatfs *FSData,
-			const struct nls_table *nls_codepage);
+			struct kstatfs *FSData);
 extern int CIFSSMBQFSAttributeInfo(const int xid,
 extern int CIFSSMBQFSAttributeInfo(const int xid,
-			struct cifsTconInfo *tcon,
-			const struct nls_table *nls_codepage);
-extern int CIFSSMBQFSDeviceInfo(const int xid, struct cifsTconInfo *tcon,
-			const struct nls_table *nls_codepage);
-extern int CIFSSMBQFSUnixInfo(const int xid, struct cifsTconInfo *tcon,
-			const struct nls_table *nls_codepage);
+			struct cifsTconInfo *tcon);
+extern int CIFSSMBQFSDeviceInfo(const int xid, struct cifsTconInfo *tcon);
+extern int CIFSSMBQFSUnixInfo(const int xid, struct cifsTconInfo *tcon);
 extern int CIFSSMBQFSPosixInfo(const int xid, struct cifsTconInfo *tcon,
 extern int CIFSSMBQFSPosixInfo(const int xid, struct cifsTconInfo *tcon,
-			struct kstatfs *FSData, const struct nls_table *nls_codepage);
+			struct kstatfs *FSData);
 
 
 extern int CIFSSMBSetTimes(const int xid, struct cifsTconInfo *tcon,
 extern int CIFSSMBSetTimes(const int xid, struct cifsTconInfo *tcon,
 			const char *fileName, const FILE_BASIC_INFO * data,
 			const char *fileName, const FILE_BASIC_INFO * data,
-			const struct nls_table *nls_codepage);
+			const struct nls_table *nls_codepage,
+			int remap_special_chars);
 extern int CIFSSMBSetFileTimes(const int xid, struct cifsTconInfo *tcon,
 extern int CIFSSMBSetFileTimes(const int xid, struct cifsTconInfo *tcon,
 			const FILE_BASIC_INFO * data, __u16 fid);
 			const FILE_BASIC_INFO * data, __u16 fid);
 #if 0
 #if 0
@@ -143,36 +144,49 @@ extern int CIFSSMBSetAttrLegacy(int xid, struct cifsTconInfo *tcon,
 			const struct nls_table *nls_codepage);
 			const struct nls_table *nls_codepage);
 #endif /* possibly unneeded function */
 #endif /* possibly unneeded function */
 extern int CIFSSMBSetEOF(const int xid, struct cifsTconInfo *tcon,
 extern int CIFSSMBSetEOF(const int xid, struct cifsTconInfo *tcon,
-			const char *fileName, __u64 size,int setAllocationSizeFlag,
-			const struct nls_table *nls_codepage);
+			const char *fileName, __u64 size,
+			int setAllocationSizeFlag,
+			const struct nls_table *nls_codepage,
+			int remap_special_chars);
 extern int CIFSSMBSetFileSize(const int xid, struct cifsTconInfo *tcon,
 extern int CIFSSMBSetFileSize(const int xid, struct cifsTconInfo *tcon,
-			 __u64 size, __u16 fileHandle,__u32 opener_pid, int AllocSizeFlag);
+			 __u64 size, __u16 fileHandle,__u32 opener_pid, 
+			int AllocSizeFlag);
 extern int CIFSSMBUnixSetPerms(const int xid, struct cifsTconInfo *pTcon,
 extern int CIFSSMBUnixSetPerms(const int xid, struct cifsTconInfo *pTcon,
 			char *full_path, __u64 mode, __u64 uid,
 			char *full_path, __u64 mode, __u64 uid,
-			__u64 gid, dev_t dev, const struct nls_table *nls_codepage);
+			__u64 gid, dev_t dev, 
+			const struct nls_table *nls_codepage,
+			int remap_special_chars);
 
 
 extern int CIFSSMBMkDir(const int xid, struct cifsTconInfo *tcon,
 extern int CIFSSMBMkDir(const int xid, struct cifsTconInfo *tcon,
 			const char *newName,
 			const char *newName,
-			const struct nls_table *nls_codepage);
+			const struct nls_table *nls_codepage,
+			int remap_special_chars);
 extern int CIFSSMBRmDir(const int xid, struct cifsTconInfo *tcon,
 extern int CIFSSMBRmDir(const int xid, struct cifsTconInfo *tcon,
-			const char *name, const struct nls_table *nls_codepage);
+			const char *name, const struct nls_table *nls_codepage,
+			int remap_special_chars);
 
 
 extern int CIFSSMBDelFile(const int xid, struct cifsTconInfo *tcon,
 extern int CIFSSMBDelFile(const int xid, struct cifsTconInfo *tcon,
 			const char *name,
 			const char *name,
-			const struct nls_table *nls_codepage);
+			const struct nls_table *nls_codepage,
+			int remap_special_chars);
 extern int CIFSSMBRename(const int xid, struct cifsTconInfo *tcon,
 extern int CIFSSMBRename(const int xid, struct cifsTconInfo *tcon,
 			const char *fromName, const char *toName,
 			const char *fromName, const char *toName,
-			const struct nls_table *nls_codepage);
+			const struct nls_table *nls_codepage,
+			int remap_special_chars);
 extern int CIFSSMBRenameOpenFile(const int xid,struct cifsTconInfo *pTcon,
 extern int CIFSSMBRenameOpenFile(const int xid,struct cifsTconInfo *pTcon,
-			int netfid, char * target_name, const struct nls_table *nls_codepage);
+			int netfid, char * target_name, 
+			const struct nls_table *nls_codepage,
+			int remap_special_chars);
 extern int CIFSCreateHardLink(const int xid,
 extern int CIFSCreateHardLink(const int xid,
 			struct cifsTconInfo *tcon,
 			struct cifsTconInfo *tcon,
 			const char *fromName, const char *toName,
 			const char *fromName, const char *toName,
-			const struct nls_table *nls_codepage);
+			const struct nls_table *nls_codepage,
+			int remap_special_chars);
 extern int CIFSUnixCreateHardLink(const int xid,
 extern int CIFSUnixCreateHardLink(const int xid,
 			struct cifsTconInfo *tcon,
 			struct cifsTconInfo *tcon,
 			const char *fromName, const char *toName,
 			const char *fromName, const char *toName,
-			const struct nls_table *nls_codepage);
+			const struct nls_table *nls_codepage, 
+			int remap_special_chars);
 extern int CIFSUnixCreateSymLink(const int xid,
 extern int CIFSUnixCreateSymLink(const int xid,
 			struct cifsTconInfo *tcon,
 			struct cifsTconInfo *tcon,
 			const char *fromName, const char *toName,
 			const char *fromName, const char *toName,
@@ -192,7 +206,7 @@ extern int CIFSSMBOpen(const int xid, struct cifsTconInfo *tcon,
 			const char *fileName, const int disposition,
 			const char *fileName, const int disposition,
 			const int access_flags, const int omode,
 			const int access_flags, const int omode,
 			__u16 * netfid, int *pOplock, FILE_ALL_INFO *,
 			__u16 * netfid, int *pOplock, FILE_ALL_INFO *,
-			const struct nls_table *nls_codepage);
+			const struct nls_table *nls_codepage, int remap);
 extern int CIFSSMBClose(const int xid, struct cifsTconInfo *tcon,
 extern int CIFSSMBClose(const int xid, struct cifsTconInfo *tcon,
 			const int smb_file_id);
 			const int smb_file_id);
 
 
@@ -211,10 +225,13 @@ extern int CIFSSMBWrite2(const int xid, struct cifsTconInfo *tcon,
 			const char __user *buf,const int long_op);
 			const char __user *buf,const int long_op);
 extern int CIFSGetSrvInodeNumber(const int xid, struct cifsTconInfo *tcon,
 extern int CIFSGetSrvInodeNumber(const int xid, struct cifsTconInfo *tcon,
 			const unsigned char *searchName, __u64 * inode_number,
 			const unsigned char *searchName, __u64 * inode_number,
-			const struct nls_table *nls_codepage);
+			const struct nls_table *nls_codepage, 
+			int remap_special_chars);
+#endif /* CONFIG_CIFS_EXPERIMENTAL */
 extern int cifs_convertUCSpath(char *target, const __u16 *source, int maxlen,
 extern int cifs_convertUCSpath(char *target, const __u16 *source, int maxlen,
 			const struct nls_table * codepage);
 			const struct nls_table * codepage);
-#endif /* CONFIG_CIFS_EXPERIMENTAL */
+extern int cifsConvertToUCS(__le16 * target, const char *source, int maxlen,
+			const struct nls_table * cp, int mapChars);
 
 
 extern int CIFSSMBLock(const int xid, struct cifsTconInfo *tcon,
 extern int CIFSSMBLock(const int xid, struct cifsTconInfo *tcon,
 			const __u16 netfid, const __u64 len,
 			const __u16 netfid, const __u64 len,
@@ -243,29 +260,31 @@ extern int CIFSSMBCopy(int xid,
 			const char *fromName,
 			const char *fromName,
 			const __u16 target_tid,
 			const __u16 target_tid,
 			const char *toName, const int flags,
 			const char *toName, const int flags,
-			const struct nls_table *nls_codepage);
+			const struct nls_table *nls_codepage, 
+			int remap_special_chars);
 extern int CIFSSMBNotify(const int xid, struct cifsTconInfo *tcon, 
 extern int CIFSSMBNotify(const int xid, struct cifsTconInfo *tcon, 
-			const int notify_subdirs,const __u16 netfid,__u32 filter,
-			const struct nls_table *nls_codepage);
+			const int notify_subdirs,const __u16 netfid,
+			__u32 filter, const struct nls_table *nls_codepage);
 extern ssize_t CIFSSMBQAllEAs(const int xid, struct cifsTconInfo *tcon,
 extern ssize_t CIFSSMBQAllEAs(const int xid, struct cifsTconInfo *tcon,
 			const unsigned char *searchName, char * EAData,
 			const unsigned char *searchName, char * EAData,
-			size_t bufsize, const struct nls_table *nls_codepage);
+			size_t bufsize, const struct nls_table *nls_codepage,
+			int remap_special_chars);
 extern ssize_t CIFSSMBQueryEA(const int xid,struct cifsTconInfo * tcon,
 extern ssize_t CIFSSMBQueryEA(const int xid,struct cifsTconInfo * tcon,
 		const unsigned char * searchName,const unsigned char * ea_name,
 		const unsigned char * searchName,const unsigned char * ea_name,
 		unsigned char * ea_value, size_t buf_size, 
 		unsigned char * ea_value, size_t buf_size, 
-		const struct nls_table *nls_codepage);
+		const struct nls_table *nls_codepage, int remap_special_chars);
 extern int CIFSSMBSetEA(const int xid, struct cifsTconInfo *tcon, 
 extern int CIFSSMBSetEA(const int xid, struct cifsTconInfo *tcon, 
 		const char *fileName, const char * ea_name, 
 		const char *fileName, const char * ea_name, 
 		const void * ea_value, const __u16 ea_value_len, 
 		const void * ea_value, const __u16 ea_value_len, 
-		const struct nls_table *nls_codepage);
+		const struct nls_table *nls_codepage, int remap_special_chars);
 extern int CIFSSMBGetPosixACL(const int xid, struct cifsTconInfo *tcon,
 extern int CIFSSMBGetPosixACL(const int xid, struct cifsTconInfo *tcon,
 		const unsigned char *searchName,
 		const unsigned char *searchName,
 		char *acl_inf, const int buflen,const int acl_type,
 		char *acl_inf, const int buflen,const int acl_type,
-		const struct nls_table *nls_codepage);
+		const struct nls_table *nls_codepage, int remap_special_chars);
 extern int CIFSSMBSetPosixACL(const int xid, struct cifsTconInfo *tcon,
 extern int CIFSSMBSetPosixACL(const int xid, struct cifsTconInfo *tcon,
 		const unsigned char *fileName,
 		const unsigned char *fileName,
 		const char *local_acl, const int buflen, const int acl_type,
 		const char *local_acl, const int buflen, const int acl_type,
-		const struct nls_table *nls_codepage);
+		const struct nls_table *nls_codepage, int remap_special_chars);
 extern int CIFSGetExtAttr(const int xid, struct cifsTconInfo *tcon,
 extern int CIFSGetExtAttr(const int xid, struct cifsTconInfo *tcon,
                 const int netfid, __u64 * pExtAttrBits, __u64 *pMask);
                 const int netfid, __u64 * pExtAttrBits, __u64 *pMask);
 #endif			/* _CIFSPROTO_H */
 #endif			/* _CIFSPROTO_H */

+ 108 - 118
fs/cifs/cifssmb.c

@@ -538,8 +538,8 @@ CIFSSMBLogoff(const int xid, struct cifsSesInfo *ses)
 }
 }
 
 
 int
 int
-CIFSSMBDelFile(const int xid, struct cifsTconInfo *tcon,
-	       const char *fileName, const struct nls_table *nls_codepage)
+CIFSSMBDelFile(const int xid, struct cifsTconInfo *tcon, const char *fileName,
+	       const struct nls_table *nls_codepage, int remap)
 {
 {
 	DELETE_FILE_REQ *pSMB = NULL;
 	DELETE_FILE_REQ *pSMB = NULL;
 	DELETE_FILE_RSP *pSMBr = NULL;
 	DELETE_FILE_RSP *pSMBr = NULL;
@@ -555,9 +555,8 @@ DelFileRetry:
 
 
 	if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
 	if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
 		name_len =
 		name_len =
-		    cifs_strtoUCS((wchar_t *) pSMB->fileName, fileName, PATH_MAX
-				  /* find define for this maxpathcomponent */
-				  , nls_codepage);
+		    cifsConvertToUCS((__u16 *) pSMB->fileName, fileName, 
+				     PATH_MAX, nls_codepage, remap);
 		name_len++;	/* trailing null */
 		name_len++;	/* trailing null */
 		name_len *= 2;
 		name_len *= 2;
 	} else {		/* BB improve the check for buffer overruns BB */
 	} else {		/* BB improve the check for buffer overruns BB */
@@ -589,8 +588,8 @@ DelFileRetry:
 }
 }
 
 
 int
 int
-CIFSSMBRmDir(const int xid, struct cifsTconInfo *tcon,
-	     const char *dirName, const struct nls_table *nls_codepage)
+CIFSSMBRmDir(const int xid, struct cifsTconInfo *tcon, const char *dirName, 
+	     const struct nls_table *nls_codepage, int remap)
 {
 {
 	DELETE_DIRECTORY_REQ *pSMB = NULL;
 	DELETE_DIRECTORY_REQ *pSMB = NULL;
 	DELETE_DIRECTORY_RSP *pSMBr = NULL;
 	DELETE_DIRECTORY_RSP *pSMBr = NULL;
@@ -606,9 +605,8 @@ RmDirRetry:
 		return rc;
 		return rc;
 
 
 	if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
 	if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
-		name_len = cifs_strtoUCS((wchar_t *) pSMB->DirName, dirName, PATH_MAX
-				/* find define for this maxpathcomponent */
-				, nls_codepage);
+		name_len = cifsConvertToUCS((__le16 *) pSMB->DirName, dirName,
+					 PATH_MAX, nls_codepage, remap);
 		name_len++;	/* trailing null */
 		name_len++;	/* trailing null */
 		name_len *= 2;
 		name_len *= 2;
 	} else {		/* BB improve the check for buffer overruns BB */
 	} else {		/* BB improve the check for buffer overruns BB */
@@ -639,7 +637,7 @@ RmDirRetry:
 
 
 int
 int
 CIFSSMBMkDir(const int xid, struct cifsTconInfo *tcon,
 CIFSSMBMkDir(const int xid, struct cifsTconInfo *tcon,
-	     const char *name, const struct nls_table *nls_codepage)
+	     const char *name, const struct nls_table *nls_codepage, int remap)
 {
 {
 	int rc = 0;
 	int rc = 0;
 	CREATE_DIRECTORY_REQ *pSMB = NULL;
 	CREATE_DIRECTORY_REQ *pSMB = NULL;
@@ -655,9 +653,8 @@ MkDirRetry:
 		return rc;
 		return rc;
 
 
 	if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
 	if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
-		name_len = cifs_strtoUCS((wchar_t *) pSMB->DirName, name, PATH_MAX
-					 /* find define for this maxpathcomponent */
-					 , nls_codepage);
+		name_len = cifsConvertToUCS((__u16 *) pSMB->DirName, name, 
+					    PATH_MAX, nls_codepage, remap);
 		name_len++;	/* trailing null */
 		name_len++;	/* trailing null */
 		name_len *= 2;
 		name_len *= 2;
 	} else {		/* BB improve the check for buffer overruns BB */
 	} else {		/* BB improve the check for buffer overruns BB */
@@ -690,7 +687,7 @@ CIFSSMBOpen(const int xid, struct cifsTconInfo *tcon,
 	    const char *fileName, const int openDisposition,
 	    const char *fileName, const int openDisposition,
 	    const int access_flags, const int create_options, __u16 * netfid,
 	    const int access_flags, const int create_options, __u16 * netfid,
 	    int *pOplock, FILE_ALL_INFO * pfile_info, 
 	    int *pOplock, FILE_ALL_INFO * pfile_info, 
-	    const struct nls_table *nls_codepage)
+	    const struct nls_table *nls_codepage, int remap)
 {
 {
 	int rc = -EACCES;
 	int rc = -EACCES;
 	OPEN_REQ *pSMB = NULL;
 	OPEN_REQ *pSMB = NULL;
@@ -710,10 +707,8 @@ openRetry:
 	if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
 	if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
 		count = 1;	/* account for one byte pad to word boundary */
 		count = 1;	/* account for one byte pad to word boundary */
 		name_len =
 		name_len =
-		    cifs_strtoUCS((wchar_t *) (pSMB->fileName + 1),
-				  fileName, PATH_MAX
-				  /* find define for this maxpathcomponent */
-				  , nls_codepage);
+		    cifsConvertToUCS((__u16 *) (pSMB->fileName + 1),
+				     fileName, PATH_MAX, nls_codepage, remap);
 		name_len++;	/* trailing null */
 		name_len++;	/* trailing null */
 		name_len *= 2;
 		name_len *= 2;
 		pSMB->NameLength = cpu_to_le16(name_len);
 		pSMB->NameLength = cpu_to_le16(name_len);
@@ -1108,7 +1103,7 @@ CIFSSMBClose(const int xid, struct cifsTconInfo *tcon, int smb_file_id)
 int
 int
 CIFSSMBRename(const int xid, struct cifsTconInfo *tcon,
 CIFSSMBRename(const int xid, struct cifsTconInfo *tcon,
 	      const char *fromName, const char *toName,
 	      const char *fromName, const char *toName,
-	      const struct nls_table *nls_codepage)
+	      const struct nls_table *nls_codepage, int remap)
 {
 {
 	int rc = 0;
 	int rc = 0;
 	RENAME_REQ *pSMB = NULL;
 	RENAME_REQ *pSMB = NULL;
@@ -1131,18 +1126,16 @@ renameRetry:
 
 
 	if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
 	if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
 		name_len =
 		name_len =
-		    cifs_strtoUCS((wchar_t *) pSMB->OldFileName, fromName, PATH_MAX
-				  /* find define for this maxpathcomponent */
-				  , nls_codepage);
+		    cifsConvertToUCS((__u16 *) pSMB->OldFileName, fromName, 
+				     PATH_MAX, nls_codepage, remap);
 		name_len++;	/* trailing null */
 		name_len++;	/* trailing null */
 		name_len *= 2;
 		name_len *= 2;
 		pSMB->OldFileName[name_len] = 0x04;	/* pad */
 		pSMB->OldFileName[name_len] = 0x04;	/* pad */
 	/* protocol requires ASCII signature byte on Unicode string */
 	/* protocol requires ASCII signature byte on Unicode string */
 		pSMB->OldFileName[name_len + 1] = 0x00;
 		pSMB->OldFileName[name_len + 1] = 0x00;
 		name_len2 =
 		name_len2 =
-		    cifs_strtoUCS((wchar_t *) & pSMB->
-				  OldFileName[name_len + 2], toName, PATH_MAX,
-				  nls_codepage);
+		    cifsConvertToUCS((__u16 *) &pSMB->OldFileName[name_len + 2],
+				     toName, PATH_MAX, nls_codepage, remap);
 		name_len2 += 1 /* trailing null */  + 1 /* Signature word */ ;
 		name_len2 += 1 /* trailing null */  + 1 /* Signature word */ ;
 		name_len2 *= 2;	/* convert to bytes */
 		name_len2 *= 2;	/* convert to bytes */
 	} else {		/* BB improve the check for buffer overruns BB */
 	} else {		/* BB improve the check for buffer overruns BB */
@@ -1182,7 +1175,8 @@ renameRetry:
 }
 }
 
 
 int CIFSSMBRenameOpenFile(const int xid,struct cifsTconInfo *pTcon, 
 int CIFSSMBRenameOpenFile(const int xid,struct cifsTconInfo *pTcon, 
-		int netfid, char * target_name, const struct nls_table * nls_codepage) 
+		int netfid, char * target_name, 
+		const struct nls_table * nls_codepage, int remap)
 {
 {
 	struct smb_com_transaction2_sfi_req *pSMB  = NULL;
 	struct smb_com_transaction2_sfi_req *pSMB  = NULL;
 	struct smb_com_transaction2_sfi_rsp *pSMBr = NULL;
 	struct smb_com_transaction2_sfi_rsp *pSMBr = NULL;
@@ -1227,9 +1221,11 @@ int CIFSSMBRenameOpenFile(const int xid,struct cifsTconInfo *pTcon,
 	/* unicode only call */
 	/* unicode only call */
 	if(target_name == NULL) {
 	if(target_name == NULL) {
 		sprintf(dummy_string,"cifs%x",pSMB->hdr.Mid);
 		sprintf(dummy_string,"cifs%x",pSMB->hdr.Mid);
-	        len_of_str = cifs_strtoUCS((wchar_t *) rename_info->target_name, dummy_string, 24, nls_codepage);
+	        len_of_str = cifsConvertToUCS((__u16 *)rename_info->target_name,
+					dummy_string, 24, nls_codepage, remap);
 	} else {
 	} else {
-		len_of_str = cifs_strtoUCS((wchar_t *) rename_info->target_name, target_name, PATH_MAX, nls_codepage);
+		len_of_str = cifsConvertToUCS((__u16 *)rename_info->target_name,
+					target_name, PATH_MAX, nls_codepage, remap);
 	}
 	}
 	rename_info->target_name_len = cpu_to_le32(2 * len_of_str);
 	rename_info->target_name_len = cpu_to_le32(2 * len_of_str);
 	count = 12 /* sizeof(struct set_file_rename) */ + (2 * len_of_str) + 2;
 	count = 12 /* sizeof(struct set_file_rename) */ + (2 * len_of_str) + 2;
@@ -1263,7 +1259,7 @@ int CIFSSMBRenameOpenFile(const int xid,struct cifsTconInfo *pTcon,
 int
 int
 CIFSSMBCopy(const int xid, struct cifsTconInfo *tcon, const char * fromName, 
 CIFSSMBCopy(const int xid, struct cifsTconInfo *tcon, const char * fromName, 
             const __u16 target_tid, const char *toName, const int flags,
             const __u16 target_tid, const char *toName, const int flags,
-            const struct nls_table *nls_codepage)
+            const struct nls_table *nls_codepage, int remap)
 {
 {
 	int rc = 0;
 	int rc = 0;
 	COPY_REQ *pSMB = NULL;
 	COPY_REQ *pSMB = NULL;
@@ -1285,18 +1281,16 @@ copyRetry:
 	pSMB->Flags = cpu_to_le16(flags & COPY_TREE);
 	pSMB->Flags = cpu_to_le16(flags & COPY_TREE);
 
 
 	if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
 	if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
-		name_len = cifs_strtoUCS((wchar_t *) pSMB->OldFileName, 
-				fromName, 
-				PATH_MAX /* find define for this maxpathcomponent */,
-				nls_codepage);
+		name_len = cifsConvertToUCS((__u16 *) pSMB->OldFileName, 
+					    fromName, PATH_MAX, nls_codepage,
+					    remap);
 		name_len++;     /* trailing null */
 		name_len++;     /* trailing null */
 		name_len *= 2;
 		name_len *= 2;
 		pSMB->OldFileName[name_len] = 0x04;     /* pad */
 		pSMB->OldFileName[name_len] = 0x04;     /* pad */
 		/* protocol requires ASCII signature byte on Unicode string */
 		/* protocol requires ASCII signature byte on Unicode string */
 		pSMB->OldFileName[name_len + 1] = 0x00;
 		pSMB->OldFileName[name_len + 1] = 0x00;
-		name_len2 = cifs_strtoUCS((wchar_t *) & pSMB->
-				OldFileName[name_len + 2], toName, PATH_MAX,
-				nls_codepage);
+		name_len2 = cifsConvertToUCS((__u16 *)&pSMB->OldFileName[name_len + 2], 
+				toName, PATH_MAX, nls_codepage, remap);
 		name_len2 += 1 /* trailing null */  + 1 /* Signature word */ ;
 		name_len2 += 1 /* trailing null */  + 1 /* Signature word */ ;
 		name_len2 *= 2; /* convert to bytes */
 		name_len2 *= 2; /* convert to bytes */
 	} else {                /* BB improve the check for buffer overruns BB */
 	} else {                /* BB improve the check for buffer overruns BB */
@@ -1425,7 +1419,7 @@ createSymLinkRetry:
 int
 int
 CIFSUnixCreateHardLink(const int xid, struct cifsTconInfo *tcon,
 CIFSUnixCreateHardLink(const int xid, struct cifsTconInfo *tcon,
 		       const char *fromName, const char *toName,
 		       const char *fromName, const char *toName,
-		       const struct nls_table *nls_codepage)
+		       const struct nls_table *nls_codepage, int remap)
 {
 {
 	TRANSACTION2_SPI_REQ *pSMB = NULL;
 	TRANSACTION2_SPI_REQ *pSMB = NULL;
 	TRANSACTION2_SPI_RSP *pSMBr = NULL;
 	TRANSACTION2_SPI_RSP *pSMBr = NULL;
@@ -1444,9 +1438,8 @@ createHardLinkRetry:
 		return rc;
 		return rc;
 
 
 	if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
 	if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
-		name_len = cifs_strtoUCS((wchar_t *) pSMB->FileName, toName, PATH_MAX
-					 /* find define for this maxpathcomponent */
-					 , nls_codepage);
+		name_len = cifsConvertToUCS((__u16 *) pSMB->FileName, toName,
+					    PATH_MAX, nls_codepage, remap);
 		name_len++;	/* trailing null */
 		name_len++;	/* trailing null */
 		name_len *= 2;
 		name_len *= 2;
 
 
@@ -1468,9 +1461,8 @@ createHardLinkRetry:
 	data_offset = (char *) (&pSMB->hdr.Protocol) + offset;
 	data_offset = (char *) (&pSMB->hdr.Protocol) + offset;
 	if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
 	if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
 		name_len_target =
 		name_len_target =
-		    cifs_strtoUCS((wchar_t *) data_offset, fromName, PATH_MAX
-				  /* find define for this maxpathcomponent */
-				  , nls_codepage);
+		    cifsConvertToUCS((__u16 *) data_offset, fromName, PATH_MAX,
+				     nls_codepage, remap);
 		name_len_target++;	/* trailing null */
 		name_len_target++;	/* trailing null */
 		name_len_target *= 2;
 		name_len_target *= 2;
 	} else {		/* BB improve the check for buffer overruns BB */
 	} else {		/* BB improve the check for buffer overruns BB */
@@ -1512,7 +1504,7 @@ createHardLinkRetry:
 int
 int
 CIFSCreateHardLink(const int xid, struct cifsTconInfo *tcon,
 CIFSCreateHardLink(const int xid, struct cifsTconInfo *tcon,
 		   const char *fromName, const char *toName,
 		   const char *fromName, const char *toName,
-		   const struct nls_table *nls_codepage)
+		   const struct nls_table *nls_codepage, int remap)
 {
 {
 	int rc = 0;
 	int rc = 0;
 	NT_RENAME_REQ *pSMB = NULL;
 	NT_RENAME_REQ *pSMB = NULL;
@@ -1539,17 +1531,15 @@ winCreateHardLinkRetry:
 
 
 	if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
 	if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
 		name_len =
 		name_len =
-		    cifs_strtoUCS((wchar_t *) pSMB->OldFileName, fromName, PATH_MAX
-				  /* find define for this maxpathcomponent */
-				  , nls_codepage);
+		    cifsConvertToUCS((__u16 *) pSMB->OldFileName, fromName,
+				     PATH_MAX, nls_codepage, remap);
 		name_len++;	/* trailing null */
 		name_len++;	/* trailing null */
 		name_len *= 2;
 		name_len *= 2;
 		pSMB->OldFileName[name_len] = 0;	/* pad */
 		pSMB->OldFileName[name_len] = 0;	/* pad */
 		pSMB->OldFileName[name_len + 1] = 0x04; 
 		pSMB->OldFileName[name_len + 1] = 0x04; 
 		name_len2 =
 		name_len2 =
-		    cifs_strtoUCS((wchar_t *) & pSMB->
-				  OldFileName[name_len + 2], toName, PATH_MAX,
-				  nls_codepage);
+		    cifsConvertToUCS((__u16 *)&pSMB->OldFileName[name_len + 2], 
+				     toName, PATH_MAX, nls_codepage, remap);
 		name_len2 += 1 /* trailing null */  + 1 /* Signature word */ ;
 		name_len2 += 1 /* trailing null */  + 1 /* Signature word */ ;
 		name_len2 *= 2;	/* convert to bytes */
 		name_len2 *= 2;	/* convert to bytes */
 	} else {		/* BB improve the check for buffer overruns BB */
 	} else {		/* BB improve the check for buffer overruns BB */
@@ -1659,6 +1649,7 @@ querySymLinkRetry:
 				name_len = UniStrnlen((wchar_t *) ((char *)
 				name_len = UniStrnlen((wchar_t *) ((char *)
 					&pSMBr->hdr.Protocol +data_offset),
 					&pSMBr->hdr.Protocol +data_offset),
 					min_t(const int, buflen,count) / 2);
 					min_t(const int, buflen,count) / 2);
+			/* BB FIXME investigate remapping reserved chars here */
 				cifs_strfromUCS_le(symlinkinfo,
 				cifs_strfromUCS_le(symlinkinfo,
 					(wchar_t *) ((char *)&pSMBr->hdr.Protocol +
 					(wchar_t *) ((char *)&pSMBr->hdr.Protocol +
 						data_offset),
 						data_offset),
@@ -1793,7 +1784,8 @@ static void cifs_convert_ace(posix_acl_xattr_entry * ace, struct cifs_posix_ace
 }
 }
 
 
 /* Convert ACL from CIFS POSIX wire format to local Linux POSIX ACL xattr */
 /* Convert ACL from CIFS POSIX wire format to local Linux POSIX ACL xattr */
-static int cifs_copy_posix_acl(char * trgt,char * src, const int buflen,const int acl_type,const int size_of_data_area)
+static int cifs_copy_posix_acl(char * trgt,char * src, const int buflen,
+				const int acl_type,const int size_of_data_area)
 {
 {
 	int size =  0;
 	int size =  0;
 	int i;
 	int i;
@@ -1912,7 +1904,7 @@ int
 CIFSSMBGetPosixACL(const int xid, struct cifsTconInfo *tcon,
 CIFSSMBGetPosixACL(const int xid, struct cifsTconInfo *tcon,
                         const unsigned char *searchName,
                         const unsigned char *searchName,
                         char *acl_inf, const int buflen, const int acl_type,
                         char *acl_inf, const int buflen, const int acl_type,
-                        const struct nls_table *nls_codepage)
+                        const struct nls_table *nls_codepage, int remap)
 {
 {
 /* SMB_QUERY_POSIX_ACL */
 /* SMB_QUERY_POSIX_ACL */
 	TRANSACTION2_QPI_REQ *pSMB = NULL;
 	TRANSACTION2_QPI_REQ *pSMB = NULL;
@@ -1932,8 +1924,8 @@ queryAclRetry:
                                                                                                                                              
                                                                                                                                              
 	if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
 	if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
 		name_len =
 		name_len =
-			cifs_strtoUCS((wchar_t *) pSMB->FileName, searchName, PATH_MAX
-				, nls_codepage);
+			cifsConvertToUCS((__u16 *) pSMB->FileName, searchName, 
+					 PATH_MAX, nls_codepage, remap);
 		name_len++;     /* trailing null */
 		name_len++;     /* trailing null */
 		name_len *= 2;
 		name_len *= 2;
 		pSMB->FileName[name_len] = 0;
 		pSMB->FileName[name_len] = 0;
@@ -1997,8 +1989,9 @@ queryAclRetry:
 int
 int
 CIFSSMBSetPosixACL(const int xid, struct cifsTconInfo *tcon,
 CIFSSMBSetPosixACL(const int xid, struct cifsTconInfo *tcon,
                         const unsigned char *fileName,
                         const unsigned char *fileName,
-                        const char *local_acl, const int buflen, const int acl_type,
-                        const struct nls_table *nls_codepage)
+                        const char *local_acl, const int buflen, 
+			const int acl_type,
+                        const struct nls_table *nls_codepage, int remap)
 {
 {
 	struct smb_com_transaction2_spi_req *pSMB = NULL;
 	struct smb_com_transaction2_spi_req *pSMB = NULL;
 	struct smb_com_transaction2_spi_rsp *pSMBr = NULL;
 	struct smb_com_transaction2_spi_rsp *pSMBr = NULL;
@@ -2016,8 +2009,8 @@ setAclRetry:
 		return rc;
 		return rc;
 	if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
 	if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
 		name_len =
 		name_len =
-			cifs_strtoUCS((wchar_t *) pSMB->FileName, fileName, PATH_MAX
-				, nls_codepage);
+			cifsConvertToUCS((__u16 *) pSMB->FileName, fileName, 
+				      PATH_MAX, nls_codepage, remap);
 		name_len++;     /* trailing null */
 		name_len++;     /* trailing null */
 		name_len *= 2;
 		name_len *= 2;
 	} else {                /* BB improve the check for buffer overruns BB */
 	} else {                /* BB improve the check for buffer overruns BB */
@@ -2161,7 +2154,7 @@ int
 CIFSSMBQPathInfo(const int xid, struct cifsTconInfo *tcon,
 CIFSSMBQPathInfo(const int xid, struct cifsTconInfo *tcon,
 		 const unsigned char *searchName,
 		 const unsigned char *searchName,
 		 FILE_ALL_INFO * pFindData,
 		 FILE_ALL_INFO * pFindData,
-		 const struct nls_table *nls_codepage)
+		 const struct nls_table *nls_codepage, int remap)
 {
 {
 /* level 263 SMB_QUERY_FILE_ALL_INFO */
 /* level 263 SMB_QUERY_FILE_ALL_INFO */
 	TRANSACTION2_QPI_REQ *pSMB = NULL;
 	TRANSACTION2_QPI_REQ *pSMB = NULL;
@@ -2180,9 +2173,8 @@ QPathInfoRetry:
 
 
 	if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
 	if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
 		name_len =
 		name_len =
-		    cifs_strtoUCS((wchar_t *) pSMB->FileName, searchName, PATH_MAX
-				  /* find define for this maxpathcomponent */
-				  , nls_codepage);
+		    cifsConvertToUCS((__u16 *) pSMB->FileName, searchName, 
+				     PATH_MAX, nls_codepage, remap);
 		name_len++;	/* trailing null */
 		name_len++;	/* trailing null */
 		name_len *= 2;
 		name_len *= 2;
 	} else {		/* BB improve the check for buffer overruns BB */
 	} else {		/* BB improve the check for buffer overruns BB */
@@ -2243,7 +2235,7 @@ int
 CIFSSMBUnixQPathInfo(const int xid, struct cifsTconInfo *tcon,
 CIFSSMBUnixQPathInfo(const int xid, struct cifsTconInfo *tcon,
 		     const unsigned char *searchName,
 		     const unsigned char *searchName,
 		     FILE_UNIX_BASIC_INFO * pFindData,
 		     FILE_UNIX_BASIC_INFO * pFindData,
-		     const struct nls_table *nls_codepage)
+		     const struct nls_table *nls_codepage, int remap)
 {
 {
 /* SMB_QUERY_FILE_UNIX_BASIC */
 /* SMB_QUERY_FILE_UNIX_BASIC */
 	TRANSACTION2_QPI_REQ *pSMB = NULL;
 	TRANSACTION2_QPI_REQ *pSMB = NULL;
@@ -2262,9 +2254,8 @@ UnixQPathInfoRetry:
 
 
 	if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
 	if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
 		name_len =
 		name_len =
-		    cifs_strtoUCS((wchar_t *) pSMB->FileName, searchName, PATH_MAX
-				  /* find define for this maxpathcomponent */
-				  , nls_codepage);
+		    cifsConvertToUCS((__u16 *) pSMB->FileName, searchName,
+				  PATH_MAX, nls_codepage, remap);
 		name_len++;	/* trailing null */
 		name_len++;	/* trailing null */
 		name_len *= 2;
 		name_len *= 2;
 	} else {		/* BB improve the check for buffer overruns BB */
 	} else {		/* BB improve the check for buffer overruns BB */
@@ -2344,7 +2335,7 @@ findUniqueRetry:
 
 
 	if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
 	if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
 		name_len =
 		name_len =
-		    cifs_strtoUCS((wchar_t *) pSMB->FileName, searchName, PATH_MAX
+		    cifsConvertToUCS((wchar_t *) pSMB->FileName, searchName, PATH_MAX
 				  /* find define for this maxpathcomponent */
 				  /* find define for this maxpathcomponent */
 				  , nls_codepage);
 				  , nls_codepage);
 		name_len++;	/* trailing null */
 		name_len++;	/* trailing null */
@@ -2408,7 +2399,7 @@ CIFSFindFirst(const int xid, struct cifsTconInfo *tcon,
 	      const char *searchName, 
 	      const char *searchName, 
 	      const struct nls_table *nls_codepage,
 	      const struct nls_table *nls_codepage,
 	      __u16 *	pnetfid,
 	      __u16 *	pnetfid,
-	      struct cifs_search_info * psrch_inf)
+	      struct cifs_search_info * psrch_inf, int remap)
 {
 {
 /* level 257 SMB_ */
 /* level 257 SMB_ */
 	TRANSACTION2_FFIRST_REQ *pSMB = NULL;
 	TRANSACTION2_FFIRST_REQ *pSMB = NULL;
@@ -2419,7 +2410,7 @@ CIFSFindFirst(const int xid, struct cifsTconInfo *tcon,
 	int name_len;
 	int name_len;
 	__u16 params, byte_count;
 	__u16 params, byte_count;
 
 
-	cFYI(1, ("In FindFirst"));
+	cFYI(1, ("In FindFirst for %s",searchName));
 
 
 findFirstRetry:
 findFirstRetry:
 	rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
 	rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
@@ -2429,12 +2420,20 @@ findFirstRetry:
 
 
 	if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
 	if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
 		name_len =
 		name_len =
-		    cifs_strtoUCS((wchar_t *) pSMB->FileName,searchName,
-				 PATH_MAX, nls_codepage);
-		name_len++;	/* trailing null */
+		    cifsConvertToUCS((__u16 *) pSMB->FileName,searchName,
+				 PATH_MAX, nls_codepage, remap);
+		/* We can not add the asterik earlier in case
+		it got remapped to 0xF03A as if it were part of the
+		directory name instead of a wildcard */
 		name_len *= 2;
 		name_len *= 2;
+		pSMB->FileName[name_len] = '\\';
+		pSMB->FileName[name_len+1] = 0;
+		pSMB->FileName[name_len+2] = '*';
+		pSMB->FileName[name_len+3] = 0;
+		name_len += 4; /* now the trailing null */
 		pSMB->FileName[name_len] = 0; /* null terminate just in case */
 		pSMB->FileName[name_len] = 0; /* null terminate just in case */
 		pSMB->FileName[name_len+1] = 0;
 		pSMB->FileName[name_len+1] = 0;
+		name_len += 2;
 	} else {	/* BB add check for overrun of SMB buf BB */
 	} else {	/* BB add check for overrun of SMB buf BB */
 		name_len = strnlen(searchName, PATH_MAX);
 		name_len = strnlen(searchName, PATH_MAX);
 		name_len++;	/* trailing null */
 		name_len++;	/* trailing null */
@@ -2691,7 +2690,7 @@ int
 CIFSGetSrvInodeNumber(const int xid, struct cifsTconInfo *tcon,
 CIFSGetSrvInodeNumber(const int xid, struct cifsTconInfo *tcon,
                 const unsigned char *searchName,
                 const unsigned char *searchName,
                 __u64 * inode_number,
                 __u64 * inode_number,
-                const struct nls_table *nls_codepage)
+                const struct nls_table *nls_codepage, int remap)
 {
 {
 	int rc = 0;
 	int rc = 0;
 	TRANSACTION2_QPI_REQ *pSMB = NULL;
 	TRANSACTION2_QPI_REQ *pSMB = NULL;
@@ -2712,8 +2711,8 @@ GetInodeNumberRetry:
 
 
 	if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
 	if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
 		name_len =
 		name_len =
-			cifs_strtoUCS((wchar_t *) pSMB->FileName, searchName, 
-				PATH_MAX,nls_codepage);
+			cifsConvertToUCS((__u16 *) pSMB->FileName, searchName,
+				PATH_MAX,nls_codepage, remap);
 		name_len++;     /* trailing null */
 		name_len++;     /* trailing null */
 		name_len *= 2;
 		name_len *= 2;
 	} else {                /* BB improve the check for buffer overruns BB */
 	} else {                /* BB improve the check for buffer overruns BB */
@@ -2787,7 +2786,7 @@ CIFSGetDFSRefer(const int xid, struct cifsSesInfo *ses,
 		const unsigned char *searchName,
 		const unsigned char *searchName,
 		unsigned char **targetUNCs,
 		unsigned char **targetUNCs,
 		unsigned int *number_of_UNC_in_array,
 		unsigned int *number_of_UNC_in_array,
-		const struct nls_table *nls_codepage)
+		const struct nls_table *nls_codepage, int remap)
 {
 {
 /* TRANS2_GET_DFS_REFERRAL */
 /* TRANS2_GET_DFS_REFERRAL */
 	TRANSACTION2_GET_DFS_REFER_REQ *pSMB = NULL;
 	TRANSACTION2_GET_DFS_REFER_REQ *pSMB = NULL;
@@ -2823,10 +2822,8 @@ getDFSRetry:
 	if (ses->capabilities & CAP_UNICODE) {
 	if (ses->capabilities & CAP_UNICODE) {
 		pSMB->hdr.Flags2 |= SMBFLG2_UNICODE;
 		pSMB->hdr.Flags2 |= SMBFLG2_UNICODE;
 		name_len =
 		name_len =
-		    cifs_strtoUCS((wchar_t *) pSMB->RequestFileName,
-				  searchName, PATH_MAX
-				  /* find define for this maxpathcomponent */
-				  , nls_codepage);
+		    cifsConvertToUCS((__u16 *) pSMB->RequestFileName,
+				     searchName, PATH_MAX, nls_codepage, remap);
 		name_len++;	/* trailing null */
 		name_len++;	/* trailing null */
 		name_len *= 2;
 		name_len *= 2;
 	} else {		/* BB improve the check for buffer overruns BB */
 	} else {		/* BB improve the check for buffer overruns BB */
@@ -2954,8 +2951,7 @@ GetDFSRefExit:
 }
 }
 
 
 int
 int
-CIFSSMBQFSInfo(const int xid, struct cifsTconInfo *tcon,
-	       struct kstatfs *FSData, const struct nls_table *nls_codepage)
+CIFSSMBQFSInfo(const int xid, struct cifsTconInfo *tcon, struct kstatfs *FSData)
 {
 {
 /* level 0x103 SMB_QUERY_FILE_SYSTEM_INFO */
 /* level 0x103 SMB_QUERY_FILE_SYSTEM_INFO */
 	TRANSACTION2_QFSI_REQ *pSMB = NULL;
 	TRANSACTION2_QFSI_REQ *pSMB = NULL;
@@ -3038,8 +3034,7 @@ QFSInfoRetry:
 }
 }
 
 
 int
 int
-CIFSSMBQFSAttributeInfo(const int xid, struct cifsTconInfo *tcon,
-			const struct nls_table *nls_codepage)
+CIFSSMBQFSAttributeInfo(const int xid, struct cifsTconInfo *tcon)
 {
 {
 /* level 0x105  SMB_QUERY_FILE_SYSTEM_INFO */
 /* level 0x105  SMB_QUERY_FILE_SYSTEM_INFO */
 	TRANSACTION2_QFSI_REQ *pSMB = NULL;
 	TRANSACTION2_QFSI_REQ *pSMB = NULL;
@@ -3107,8 +3102,7 @@ QFSAttributeRetry:
 }
 }
 
 
 int
 int
-CIFSSMBQFSDeviceInfo(const int xid, struct cifsTconInfo *tcon,
-		     const struct nls_table *nls_codepage)
+CIFSSMBQFSDeviceInfo(const int xid, struct cifsTconInfo *tcon)
 {
 {
 /* level 0x104 SMB_QUERY_FILE_SYSTEM_INFO */
 /* level 0x104 SMB_QUERY_FILE_SYSTEM_INFO */
 	TRANSACTION2_QFSI_REQ *pSMB = NULL;
 	TRANSACTION2_QFSI_REQ *pSMB = NULL;
@@ -3161,8 +3155,8 @@ QFSDeviceRetry:
 		else {
 		else {
 			__u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
 			__u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
 			response_data =
 			response_data =
-			    (FILE_SYSTEM_DEVICE_INFO
-			     *) (((char *) &pSMBr->hdr.Protocol) +
+			    (FILE_SYSTEM_DEVICE_INFO *)
+				(((char *) &pSMBr->hdr.Protocol) +
 				 data_offset);
 				 data_offset);
 			memcpy(&tcon->fsDevInfo, response_data,
 			memcpy(&tcon->fsDevInfo, response_data,
 			       sizeof (FILE_SYSTEM_DEVICE_INFO));
 			       sizeof (FILE_SYSTEM_DEVICE_INFO));
@@ -3177,8 +3171,7 @@ QFSDeviceRetry:
 }
 }
 
 
 int
 int
-CIFSSMBQFSUnixInfo(const int xid, struct cifsTconInfo *tcon,
-		   const struct nls_table *nls_codepage)
+CIFSSMBQFSUnixInfo(const int xid, struct cifsTconInfo *tcon)
 {
 {
 /* level 0x200  SMB_QUERY_CIFS_UNIX_INFO */
 /* level 0x200  SMB_QUERY_CIFS_UNIX_INFO */
 	TRANSACTION2_QFSI_REQ *pSMB = NULL;
 	TRANSACTION2_QFSI_REQ *pSMB = NULL;
@@ -3249,7 +3242,7 @@ QFSUnixRetry:
 
 
 int
 int
 CIFSSMBQFSPosixInfo(const int xid, struct cifsTconInfo *tcon,
 CIFSSMBQFSPosixInfo(const int xid, struct cifsTconInfo *tcon,
-		   struct kstatfs *FSData, const struct nls_table *nls_codepage)
+		   struct kstatfs *FSData)
 {
 {
 /* level 0x201  SMB_QUERY_CIFS_POSIX_INFO */
 /* level 0x201  SMB_QUERY_CIFS_POSIX_INFO */
 	TRANSACTION2_QFSI_REQ *pSMB = NULL;
 	TRANSACTION2_QFSI_REQ *pSMB = NULL;
@@ -3341,7 +3334,8 @@ QFSPosixRetry:
 
 
 int
 int
 CIFSSMBSetEOF(const int xid, struct cifsTconInfo *tcon, const char *fileName,
 CIFSSMBSetEOF(const int xid, struct cifsTconInfo *tcon, const char *fileName,
-	      __u64 size, int SetAllocation, const struct nls_table *nls_codepage)
+	      __u64 size, int SetAllocation, 
+	      const struct nls_table *nls_codepage, int remap)
 {
 {
 	struct smb_com_transaction2_spi_req *pSMB = NULL;
 	struct smb_com_transaction2_spi_req *pSMB = NULL;
 	struct smb_com_transaction2_spi_rsp *pSMBr = NULL;
 	struct smb_com_transaction2_spi_rsp *pSMBr = NULL;
@@ -3360,9 +3354,8 @@ SetEOFRetry:
 
 
 	if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
 	if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
 		name_len =
 		name_len =
-		    cifs_strtoUCS((wchar_t *) pSMB->FileName, fileName, PATH_MAX
-				  /* find define for this maxpathcomponent */
-				  , nls_codepage);
+		    cifsConvertToUCS((__u16 *) pSMB->FileName, fileName,
+				     PATH_MAX, nls_codepage, remap);
 		name_len++;	/* trailing null */
 		name_len++;	/* trailing null */
 		name_len *= 2;
 		name_len *= 2;
 	} else {		/* BB improve the check for buffer overruns BB */
 	} else {		/* BB improve the check for buffer overruns BB */
@@ -3595,7 +3588,7 @@ CIFSSMBSetFileTimes(const int xid, struct cifsTconInfo *tcon, const FILE_BASIC_I
 int
 int
 CIFSSMBSetTimes(const int xid, struct cifsTconInfo *tcon, const char *fileName,
 CIFSSMBSetTimes(const int xid, struct cifsTconInfo *tcon, const char *fileName,
 		const FILE_BASIC_INFO * data, 
 		const FILE_BASIC_INFO * data, 
-		const struct nls_table *nls_codepage)
+		const struct nls_table *nls_codepage, int remap)
 {
 {
 	TRANSACTION2_SPI_REQ *pSMB = NULL;
 	TRANSACTION2_SPI_REQ *pSMB = NULL;
 	TRANSACTION2_SPI_RSP *pSMBr = NULL;
 	TRANSACTION2_SPI_RSP *pSMBr = NULL;
@@ -3615,9 +3608,8 @@ SetTimesRetry:
 
 
 	if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
 	if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
 		name_len =
 		name_len =
-		    cifs_strtoUCS((wchar_t *) pSMB->FileName, fileName, PATH_MAX
-				  /* find define for this maxpathcomponent */
-				  , nls_codepage);
+		    cifsConvertToUCS((__u16 *) pSMB->FileName, fileName,
+				     PATH_MAX, nls_codepage, remap);
 		name_len++;	/* trailing null */
 		name_len++;	/* trailing null */
 		name_len *= 2;
 		name_len *= 2;
 	} else {		/* BB improve the check for buffer overruns BB */
 	} else {		/* BB improve the check for buffer overruns BB */
@@ -3697,7 +3689,7 @@ SetAttrLgcyRetry:
 
 
 	if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
 	if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
 		name_len =
 		name_len =
-			cifs_strtoUCS((wchar_t *) pSMB->fileName, fileName, 
+			ConvertToUCS((wchar_t *) pSMB->fileName, fileName, 
 				PATH_MAX, nls_codepage);
 				PATH_MAX, nls_codepage);
 		name_len++;     /* trailing null */
 		name_len++;     /* trailing null */
 		name_len *= 2;
 		name_len *= 2;
@@ -3727,8 +3719,9 @@ SetAttrLgcyRetry:
 
 
 int
 int
 CIFSSMBUnixSetPerms(const int xid, struct cifsTconInfo *tcon,
 CIFSSMBUnixSetPerms(const int xid, struct cifsTconInfo *tcon,
-		    char *fileName, __u64 mode, __u64 uid, __u64 gid,
-		    dev_t device, const struct nls_table *nls_codepage)
+		    char *fileName, __u64 mode, __u64 uid, __u64 gid, 
+		    dev_t device, const struct nls_table *nls_codepage, 
+		    int remap)
 {
 {
 	TRANSACTION2_SPI_REQ *pSMB = NULL;
 	TRANSACTION2_SPI_REQ *pSMB = NULL;
 	TRANSACTION2_SPI_RSP *pSMBr = NULL;
 	TRANSACTION2_SPI_RSP *pSMBr = NULL;
@@ -3747,9 +3740,8 @@ setPermsRetry:
 
 
 	if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
 	if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
 		name_len =
 		name_len =
-		    cifs_strtoUCS((wchar_t *) pSMB->FileName, fileName, PATH_MAX
-				  /* find define for this maxpathcomponent */
-				  , nls_codepage);
+		    cifsConvertToUCS((__u16 *) pSMB->FileName, fileName, 
+				     PATH_MAX, nls_codepage, remap);
 		name_len++;	/* trailing null */
 		name_len++;	/* trailing null */
 		name_len *= 2;
 		name_len *= 2;
 	} else {		/* BB improve the check for buffer overruns BB */
 	} else {		/* BB improve the check for buffer overruns BB */
@@ -3872,7 +3864,7 @@ ssize_t
 CIFSSMBQAllEAs(const int xid, struct cifsTconInfo *tcon,
 CIFSSMBQAllEAs(const int xid, struct cifsTconInfo *tcon,
 		 const unsigned char *searchName,
 		 const unsigned char *searchName,
 		 char * EAData, size_t buf_size,
 		 char * EAData, size_t buf_size,
-		 const struct nls_table *nls_codepage)
+		 const struct nls_table *nls_codepage, int remap)
 {
 {
 		/* BB assumes one setup word */
 		/* BB assumes one setup word */
 	TRANSACTION2_QPI_REQ *pSMB = NULL;
 	TRANSACTION2_QPI_REQ *pSMB = NULL;
@@ -3893,9 +3885,8 @@ QAllEAsRetry:
 
 
 	if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
 	if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
 		name_len =
 		name_len =
-		    cifs_strtoUCS((wchar_t *) pSMB->FileName, searchName, PATH_MAX
-				  /* find define for this maxpathcomponent */
-				  , nls_codepage);
+		    cifsConvertToUCS((wchar_t *) pSMB->FileName, searchName, 
+				     PATH_MAX, nls_codepage, remap);
 		name_len++;	/* trailing null */
 		name_len++;	/* trailing null */
 		name_len *= 2;
 		name_len *= 2;
 	} else {	/* BB improve the check for buffer overruns BB */
 	} else {	/* BB improve the check for buffer overruns BB */
@@ -4017,7 +4008,7 @@ QAllEAsRetry:
 ssize_t CIFSSMBQueryEA(const int xid,struct cifsTconInfo * tcon,
 ssize_t CIFSSMBQueryEA(const int xid,struct cifsTconInfo * tcon,
 		const unsigned char * searchName,const unsigned char * ea_name,
 		const unsigned char * searchName,const unsigned char * ea_name,
 		unsigned char * ea_value, size_t buf_size, 
 		unsigned char * ea_value, size_t buf_size, 
-		const struct nls_table *nls_codepage)
+		const struct nls_table *nls_codepage, int remap)
 {
 {
 	TRANSACTION2_QPI_REQ *pSMB = NULL;
 	TRANSACTION2_QPI_REQ *pSMB = NULL;
 	TRANSACTION2_QPI_RSP *pSMBr = NULL;
 	TRANSACTION2_QPI_RSP *pSMBr = NULL;
@@ -4037,9 +4028,8 @@ QEARetry:
 
 
 	if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
 	if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
 		name_len =
 		name_len =
-		    cifs_strtoUCS((wchar_t *) pSMB->FileName, searchName, PATH_MAX
-				  /* find define for this maxpathcomponent */
-				  , nls_codepage);
+		    cifsConvertToUCS((__u16 *) pSMB->FileName, searchName, 
+				     PATH_MAX, nls_codepage, remap);
 		name_len++;	/* trailing null */
 		name_len++;	/* trailing null */
 		name_len *= 2;
 		name_len *= 2;
 	} else {	/* BB improve the check for buffer overruns BB */
 	} else {	/* BB improve the check for buffer overruns BB */
@@ -4165,7 +4155,8 @@ QEARetry:
 int
 int
 CIFSSMBSetEA(const int xid, struct cifsTconInfo *tcon, const char *fileName,
 CIFSSMBSetEA(const int xid, struct cifsTconInfo *tcon, const char *fileName,
 		const char * ea_name, const void * ea_value, 
 		const char * ea_name, const void * ea_value, 
-		const __u16 ea_value_len, const struct nls_table *nls_codepage)
+		const __u16 ea_value_len, const struct nls_table *nls_codepage,
+		int remap)
 {
 {
 	struct smb_com_transaction2_spi_req *pSMB = NULL;
 	struct smb_com_transaction2_spi_req *pSMB = NULL;
 	struct smb_com_transaction2_spi_rsp *pSMBr = NULL;
 	struct smb_com_transaction2_spi_rsp *pSMBr = NULL;
@@ -4184,9 +4175,8 @@ SetEARetry:
 
 
 	if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
 	if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
 		name_len =
 		name_len =
-		    cifs_strtoUCS((wchar_t *) pSMB->FileName, fileName, PATH_MAX
-				  /* find define for this maxpathcomponent */
-				  , nls_codepage);
+		    cifsConvertToUCS((__u16 *) pSMB->FileName, fileName, 
+				     PATH_MAX, nls_codepage, remap);
 		name_len++;	/* trailing null */
 		name_len++;	/* trailing null */
 		name_len *= 2;
 		name_len *= 2;
 	} else {		/* BB improve the check for buffer overruns BB */
 	} else {		/* BB improve the check for buffer overruns BB */

+ 13 - 12
fs/cifs/connect.c

@@ -924,14 +924,15 @@ find_unc(__be32 new_target_ip_addr, char *uncName, char *userName)
 
 
 int
 int
 connect_to_dfs_path(int xid, struct cifsSesInfo *pSesInfo,
 connect_to_dfs_path(int xid, struct cifsSesInfo *pSesInfo,
-		    const char *old_path, const struct nls_table *nls_codepage)
+		    const char *old_path, const struct nls_table *nls_codepage,
+		    int remap)
 {
 {
 	unsigned char *referrals = NULL;
 	unsigned char *referrals = NULL;
 	unsigned int num_referrals;
 	unsigned int num_referrals;
 	int rc = 0;
 	int rc = 0;
 
 
 	rc = get_dfs_path(xid, pSesInfo,old_path, nls_codepage, 
 	rc = get_dfs_path(xid, pSesInfo,old_path, nls_codepage, 
-			&num_referrals, &referrals);
+			&num_referrals, &referrals, remap);
 
 
 	/* BB Add in code to: if valid refrl, if not ip address contact
 	/* BB Add in code to: if valid refrl, if not ip address contact
 		the helper that resolves tcp names, mount to it, try to 
 		the helper that resolves tcp names, mount to it, try to 
@@ -946,7 +947,8 @@ connect_to_dfs_path(int xid, struct cifsSesInfo *pSesInfo,
 int
 int
 get_dfs_path(int xid, struct cifsSesInfo *pSesInfo,
 get_dfs_path(int xid, struct cifsSesInfo *pSesInfo,
 			const char *old_path, const struct nls_table *nls_codepage, 
 			const char *old_path, const struct nls_table *nls_codepage, 
-			unsigned int *pnum_referrals, unsigned char ** preferrals)
+			unsigned int *pnum_referrals, 
+			unsigned char ** preferrals, int remap)
 {
 {
 	char *temp_unc;
 	char *temp_unc;
 	int rc = 0;
 	int rc = 0;
@@ -971,7 +973,7 @@ get_dfs_path(int xid, struct cifsSesInfo *pSesInfo,
 	}
 	}
 	if (rc == 0)
 	if (rc == 0)
 		rc = CIFSGetDFSRefer(xid, pSesInfo, old_path, preferrals,
 		rc = CIFSGetDFSRefer(xid, pSesInfo, old_path, preferrals,
-				     pnum_referrals, nls_codepage);
+				     pnum_referrals, nls_codepage, remap);
 
 
 	return rc;
 	return rc;
 }
 }
@@ -1456,11 +1458,10 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
 				if ((strchr(volume_info.UNC + 3, '\\') == NULL)
 				if ((strchr(volume_info.UNC + 3, '\\') == NULL)
 				    && (strchr(volume_info.UNC + 3, '/') ==
 				    && (strchr(volume_info.UNC + 3, '/') ==
 					NULL)) {
 					NULL)) {
-					rc = connect_to_dfs_path(xid,
-								 pSesInfo,
-								 "",
-								 cifs_sb->
-								 local_nls);
+					rc = connect_to_dfs_path(xid, pSesInfo,
+							"", cifs_sb->local_nls,
+							cifs_sb->mnt_cifs_flags & 
+							  CIFS_MOUNT_MAP_SPECIAL_CHR);
 					if(volume_info.UNC)
 					if(volume_info.UNC)
 						kfree(volume_info.UNC);
 						kfree(volume_info.UNC);
 					FreeXid(xid);
 					FreeXid(xid);
@@ -1523,10 +1524,10 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
 		tcon->ses = pSesInfo;
 		tcon->ses = pSesInfo;
 
 
 		/* do not care if following two calls succeed - informational only */
 		/* do not care if following two calls succeed - informational only */
-		CIFSSMBQFSDeviceInfo(xid, tcon, cifs_sb->local_nls);
-		CIFSSMBQFSAttributeInfo(xid, tcon, cifs_sb->local_nls);
+		CIFSSMBQFSDeviceInfo(xid, tcon);
+		CIFSSMBQFSAttributeInfo(xid, tcon);
 		if (tcon->ses->capabilities & CAP_UNIX) {
 		if (tcon->ses->capabilities & CAP_UNIX) {
-			if(!CIFSSMBQFSUnixInfo(xid, tcon, cifs_sb->local_nls)) {
+			if(!CIFSSMBQFSUnixInfo(xid, tcon)) {
 				if(!volume_info.no_psx_acl) {
 				if(!volume_info.no_psx_acl) {
 					if(CIFS_UNIX_POSIX_ACL_CAP & 
 					if(CIFS_UNIX_POSIX_ACL_CAP & 
 					   le64_to_cpu(tcon->fsUnixInfo.Capability))
 					   le64_to_cpu(tcon->fsUnixInfo.Capability))

+ 17 - 91
fs/cifs/dir.c

@@ -101,68 +101,15 @@ cifs_bp_rename_retry:
 	return full_path;
 	return full_path;
 }
 }
 
 
-/* Note: caller must free return buffer */
-char *
-build_wildcard_path_from_dentry(struct dentry *direntry)
+/* char * build_wildcard_path_from_dentry(struct dentry *direntry)
 {
 {
-	struct dentry *temp;
-	int namelen = 0;
-	char *full_path;
-
-	if(direntry == NULL)
-		return NULL;  /* not much we can do if dentry is freed and
-		we need to reopen the file after it was closed implicitly
-		when the server crashed */
-
-cifs_bwp_rename_retry:
-	for (temp = direntry; !IS_ROOT(temp);) {
-		namelen += (1 + temp->d_name.len);
-		temp = temp->d_parent;
-		if(temp == NULL) {
-			cERROR(1,("corrupt dentry"));
-			return NULL;
-		}
-	}
-
-	full_path = kmalloc(namelen+3, GFP_KERNEL);
 	if(full_path == NULL)
 	if(full_path == NULL)
 		return full_path;
 		return full_path;
 
 
 	full_path[namelen] = '\\';
 	full_path[namelen] = '\\';
 	full_path[namelen+1] = '*';
 	full_path[namelen+1] = '*';
-	full_path[namelen+2] = 0;  /* trailing null */
-
-	for (temp = direntry; !IS_ROOT(temp);) {
-		namelen -= 1 + temp->d_name.len;
-		if (namelen < 0) {
-			break;
-		} else {
-			full_path[namelen] = '\\';
-			strncpy(full_path + namelen + 1, temp->d_name.name,
-				temp->d_name.len);
-			cFYI(0, (" name: %s ", full_path + namelen));
-		}
-		temp = temp->d_parent;
-		if(temp == NULL) {
-			cERROR(1,("corrupt dentry"));
-			kfree(full_path);
-			return NULL;
-		}
-	}
-	if (namelen != 0) {
-		cERROR(1,
-		       ("We did not end path lookup where we expected namelen is %d",
-			namelen));
-		/* presumably this is only possible if we were racing with a rename 
-		of one of the parent directories  (we can not lock the dentries
-		above us to prevent this, but retrying should be harmless) */
-		kfree(full_path);
-		namelen = 0;
-		goto cifs_bwp_rename_retry;
-	}
-
-	return full_path;
-}
+	full_path[namelen+2] = 0;
+BB remove above eight lines BB */
 
 
 /* Inode operations in similar order to how they appear in the Linux file fs.h */
 /* Inode operations in similar order to how they appear in the Linux file fs.h */
 
 
@@ -235,7 +182,8 @@ cifs_create(struct inode *inode, struct dentry *direntry, int mode,
 
 
 	rc = CIFSSMBOpen(xid, pTcon, full_path, disposition,
 	rc = CIFSSMBOpen(xid, pTcon, full_path, disposition,
 			 desiredAccess, CREATE_NOT_DIR,
 			 desiredAccess, CREATE_NOT_DIR,
-			 &fileHandle, &oplock, buf, cifs_sb->local_nls);
+			 &fileHandle, &oplock, buf, cifs_sb->local_nls,
+			 cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR);
 	if (rc) {
 	if (rc) {
 		cFYI(1, ("cifs_create returned 0x%x ", rc));
 		cFYI(1, ("cifs_create returned 0x%x ", rc));
 	} else {
 	} else {
@@ -248,13 +196,17 @@ cifs_create(struct inode *inode, struct dentry *direntry, int mode,
 					(__u64)current->euid,
 					(__u64)current->euid,
 					(__u64)current->egid,
 					(__u64)current->egid,
 					0 /* dev */,
 					0 /* dev */,
-					cifs_sb->local_nls);
+					cifs_sb->local_nls, 
+					cifs_sb->mnt_cifs_flags & 
+						CIFS_MOUNT_MAP_SPECIAL_CHR);
 			} else {
 			} else {
 				CIFSSMBUnixSetPerms(xid, pTcon, full_path, mode,
 				CIFSSMBUnixSetPerms(xid, pTcon, full_path, mode,
 					(__u64)-1,
 					(__u64)-1,
 					(__u64)-1,
 					(__u64)-1,
 					0 /* dev */,
 					0 /* dev */,
-					cifs_sb->local_nls);
+					cifs_sb->local_nls,
+					cifs_sb->mnt_cifs_flags & 
+						CIFS_MOUNT_MAP_SPECIAL_CHR);
 			}
 			}
 		else {
 		else {
 			/* BB implement via Windows security descriptors */
 			/* BB implement via Windows security descriptors */
@@ -356,11 +308,15 @@ int cifs_mknod(struct inode *inode, struct dentry *direntry, int mode, dev_t dev
 		if(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SET_UID) {
 		if(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SET_UID) {
 			rc = CIFSSMBUnixSetPerms(xid, pTcon, full_path,
 			rc = CIFSSMBUnixSetPerms(xid, pTcon, full_path,
 				mode,(__u64)current->euid,(__u64)current->egid,
 				mode,(__u64)current->euid,(__u64)current->egid,
-				device_number, cifs_sb->local_nls);
+				device_number, cifs_sb->local_nls,
+				cifs_sb->mnt_cifs_flags & 
+					CIFS_MOUNT_MAP_SPECIAL_CHR);
 		} else {
 		} else {
 			rc = CIFSSMBUnixSetPerms(xid, pTcon,
 			rc = CIFSSMBUnixSetPerms(xid, pTcon,
 				full_path, mode, (__u64)-1, (__u64)-1,
 				full_path, mode, (__u64)-1, (__u64)-1,
-				device_number, cifs_sb->local_nls);
+				device_number, cifs_sb->local_nls,
+				cifs_sb->mnt_cifs_flags & 
+					CIFS_MOUNT_MAP_SPECIAL_CHR);
 		}
 		}
 
 
 		if(!rc) {
 		if(!rc) {
@@ -447,36 +403,6 @@ cifs_lookup(struct inode *parent_dir_inode, struct dentry *direntry, struct name
 	return ERR_PTR(rc);
 	return ERR_PTR(rc);
 }
 }
 
 
-int
-cifs_dir_open(struct inode *inode, struct file *file)
-{				/* NB: currently unused since searches are opened in readdir */
-	int rc = 0;
-	int xid;
-	struct cifs_sb_info *cifs_sb;
-	struct cifsTconInfo *pTcon;
-	char *full_path = NULL;
-
-	xid = GetXid();
-
-	cifs_sb = CIFS_SB(inode->i_sb);
-	pTcon = cifs_sb->tcon;
-
-	if(file->f_dentry) {
-		down(&file->f_dentry->d_sb->s_vfs_rename_sem);
-		full_path = build_wildcard_path_from_dentry(file->f_dentry);
-		up(&file->f_dentry->d_sb->s_vfs_rename_sem);
-	} else {
-		FreeXid(xid);
-		return -EIO;
-	}
-
-	cFYI(1, ("inode = 0x%p and full path is %s", inode, full_path));
-
-	kfree(full_path);
-	FreeXid(xid);
-	return rc;
-}
-
 static int
 static int
 cifs_d_revalidate(struct dentry *direntry, struct nameidata *nd)
 cifs_d_revalidate(struct dentry *direntry, struct nameidata *nd)
 {
 {

+ 2 - 1
fs/cifs/fcntl.c

@@ -92,7 +92,8 @@ int cifs_dir_notify(struct file * file, unsigned long arg)
 		cERROR(1,("cifs dir notify on file %s with arg 0x%lx",full_path,arg)); /* BB removeme BB */
 		cERROR(1,("cifs dir notify on file %s with arg 0x%lx",full_path,arg)); /* BB removeme BB */
 		rc = CIFSSMBOpen(xid, pTcon, full_path, FILE_OPEN, 
 		rc = CIFSSMBOpen(xid, pTcon, full_path, FILE_OPEN, 
 			GENERIC_READ | SYNCHRONIZE, 0 /* create options */,
 			GENERIC_READ | SYNCHRONIZE, 0 /* create options */,
-			&netfid, &oplock,NULL, cifs_sb->local_nls);
+			&netfid, &oplock,NULL, cifs_sb->local_nls,
+			cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR);
 		/* BB fixme - add this handle to a notify handle list */
 		/* BB fixme - add this handle to a notify handle list */
 		if(rc) {
 		if(rc) {
 			cERROR(1,("Could not open directory for notify"));  /* BB remove BB */
 			cERROR(1,("Could not open directory for notify"));  /* BB remove BB */

+ 7 - 3
fs/cifs/file.c

@@ -254,7 +254,8 @@ int cifs_open(struct inode *inode, struct file *file)
 	}
 	}
 	rc = CIFSSMBOpen(xid, pTcon, full_path, disposition, desiredAccess,
 	rc = CIFSSMBOpen(xid, pTcon, full_path, disposition, desiredAccess,
 			 CREATE_NOT_DIR, &netfid, &oplock, buf,
 			 CREATE_NOT_DIR, &netfid, &oplock, buf,
-			 cifs_sb->local_nls);
+			 cifs_sb->local_nls, cifs_sb->mnt_cifs_flags
+				 & CIFS_MOUNT_MAP_SPECIAL_CHR);
 	if (rc) {
 	if (rc) {
 		cFYI(1, ("cifs_open returned 0x%x ", rc));
 		cFYI(1, ("cifs_open returned 0x%x ", rc));
 		goto out;
 		goto out;
@@ -287,7 +288,9 @@ int cifs_open(struct inode *inode, struct file *file)
 			CIFSSMBUnixSetPerms(xid, pTcon, full_path,
 			CIFSSMBUnixSetPerms(xid, pTcon, full_path,
 					    inode->i_mode,
 					    inode->i_mode,
 					    (__u64)-1, (__u64)-1, 0 /* dev */,
 					    (__u64)-1, (__u64)-1, 0 /* dev */,
-					    cifs_sb->local_nls);
+					    cifs_sb->local_nls,
+					    cifs_sb->mnt_cifs_flags & 
+						CIFS_MOUNT_MAP_SPECIAL_CHR);
 		} else {
 		} else {
 			/* BB implement via Windows security descriptors eg
 			/* BB implement via Windows security descriptors eg
 			   CIFSSMBWinSetPerms(xid, pTcon, full_path, mode,
 			   CIFSSMBWinSetPerms(xid, pTcon, full_path, mode,
@@ -387,7 +390,8 @@ static int cifs_reopen_file(struct inode *inode, struct file *file,
 	} */
 	} */
 	rc = CIFSSMBOpen(xid, pTcon, full_path, disposition, desiredAccess,
 	rc = CIFSSMBOpen(xid, pTcon, full_path, disposition, desiredAccess,
 			 CREATE_NOT_DIR, &netfid, &oplock, NULL,
 			 CREATE_NOT_DIR, &netfid, &oplock, NULL,
-			 cifs_sb->local_nls);
+			 cifs_sb->local_nls, cifs_sb->mnt_cifs_flags & 
+				CIFS_MOUNT_MAP_SPECIAL_CHR);
 	if (rc) {
 	if (rc) {
 		up(&pCifsFile->fh_sem);
 		up(&pCifsFile->fh_sem);
 		cFYI(1, ("cifs_open returned 0x%x ", rc));
 		cFYI(1, ("cifs_open returned 0x%x ", rc));

+ 78 - 28
fs/cifs/inode.c

@@ -44,7 +44,8 @@ int cifs_get_inode_info_unix(struct inode **pinode,
 	cFYI(1, (" Getting info on %s ", search_path));
 	cFYI(1, (" Getting info on %s ", search_path));
 	/* could have done a find first instead but this returns more info */
 	/* could have done a find first instead but this returns more info */
 	rc = CIFSSMBUnixQPathInfo(xid, pTcon, search_path, &findData,
 	rc = CIFSSMBUnixQPathInfo(xid, pTcon, search_path, &findData,
-				  cifs_sb->local_nls);
+				  cifs_sb->local_nls, cifs_sb->mnt_cifs_flags &
+					CIFS_MOUNT_MAP_SPECIAL_CHR);
 /*	dump_mem("\nUnixQPathInfo return data", &findData,
 /*	dump_mem("\nUnixQPathInfo return data", &findData,
 		 sizeof(findData)); */
 		 sizeof(findData)); */
 	if (rc) {
 	if (rc) {
@@ -63,7 +64,9 @@ int cifs_get_inode_info_unix(struct inode **pinode,
 			strncat(tmp_path, search_path, MAX_PATHCONF);
 			strncat(tmp_path, search_path, MAX_PATHCONF);
 			rc = connect_to_dfs_path(xid, pTcon->ses,
 			rc = connect_to_dfs_path(xid, pTcon->ses,
 						 /* treename + */ tmp_path,
 						 /* treename + */ tmp_path,
-						 cifs_sb->local_nls);
+						 cifs_sb->local_nls, 
+						 cifs_sb->mnt_cifs_flags & 
+						    CIFS_MOUNT_MAP_SPECIAL_CHR);
 			kfree(tmp_path);
 			kfree(tmp_path);
 
 
 			/* BB fix up inode etc. */
 			/* BB fix up inode etc. */
@@ -210,7 +213,8 @@ int cifs_get_inode_info(struct inode **pinode,
 		pfindData = (FILE_ALL_INFO *)buf;
 		pfindData = (FILE_ALL_INFO *)buf;
 		/* could do find first instead but this returns more info */
 		/* could do find first instead but this returns more info */
 		rc = CIFSSMBQPathInfo(xid, pTcon, search_path, pfindData,
 		rc = CIFSSMBQPathInfo(xid, pTcon, search_path, pfindData,
-			      cifs_sb->local_nls);
+			      cifs_sb->local_nls, cifs_sb->mnt_cifs_flags & 
+				CIFS_MOUNT_MAP_SPECIAL_CHR);
 	}
 	}
 	/* dump_mem("\nQPathInfo return data",&findData, sizeof(findData)); */
 	/* dump_mem("\nQPathInfo return data",&findData, sizeof(findData)); */
 	if (rc) {
 	if (rc) {
@@ -230,7 +234,9 @@ int cifs_get_inode_info(struct inode **pinode,
 			strncat(tmp_path, search_path, MAX_PATHCONF);
 			strncat(tmp_path, search_path, MAX_PATHCONF);
 			rc = connect_to_dfs_path(xid, pTcon->ses,
 			rc = connect_to_dfs_path(xid, pTcon->ses,
 						 /* treename + */ tmp_path,
 						 /* treename + */ tmp_path,
-						 cifs_sb->local_nls);
+						 cifs_sb->local_nls, 
+						 cifs_sb->mnt_cifs_flags & 
+						   CIFS_MOUNT_MAP_SPECIAL_CHR);
 			kfree(tmp_path);
 			kfree(tmp_path);
 			/* BB fix up inode etc. */
 			/* BB fix up inode etc. */
 		} else if (rc) {
 		} else if (rc) {
@@ -268,7 +274,9 @@ int cifs_get_inode_info(struct inode **pinode,
 
 
 				rc1 = CIFSGetSrvInodeNumber(xid, pTcon, 
 				rc1 = CIFSGetSrvInodeNumber(xid, pTcon, 
 					search_path, &inode_num, 
 					search_path, &inode_num, 
-					cifs_sb->local_nls);
+					cifs_sb->local_nls,
+					cifs_sb->mnt_cifs_flags &
+						CIFS_MOUNT_MAP_SPECIAL_CHR);
 				if(rc1) {
 				if(rc1) {
 					cFYI(1,("GetSrvInodeNum rc %d", rc1));
 					cFYI(1,("GetSrvInodeNum rc %d", rc1));
 					/* BB EOPNOSUPP disable SERVER_INUM? */
 					/* BB EOPNOSUPP disable SERVER_INUM? */
@@ -410,7 +418,8 @@ int cifs_unlink(struct inode *inode, struct dentry *direntry)
 		FreeXid(xid);
 		FreeXid(xid);
 		return -ENOMEM;
 		return -ENOMEM;
 	}
 	}
-	rc = CIFSSMBDelFile(xid, pTcon, full_path, cifs_sb->local_nls);
+	rc = CIFSSMBDelFile(xid, pTcon, full_path, cifs_sb->local_nls,
+			cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR);
 
 
 	if (!rc) {
 	if (!rc) {
 		direntry->d_inode->i_nlink--;
 		direntry->d_inode->i_nlink--;
@@ -422,10 +431,14 @@ int cifs_unlink(struct inode *inode, struct dentry *direntry)
 
 
 		rc = CIFSSMBOpen(xid, pTcon, full_path, FILE_OPEN, DELETE,
 		rc = CIFSSMBOpen(xid, pTcon, full_path, FILE_OPEN, DELETE,
 				 CREATE_NOT_DIR | CREATE_DELETE_ON_CLOSE,
 				 CREATE_NOT_DIR | CREATE_DELETE_ON_CLOSE,
-				 &netfid, &oplock, NULL, cifs_sb->local_nls);
+				 &netfid, &oplock, NULL, cifs_sb->local_nls,
+				 cifs_sb->mnt_cifs_flags & 
+					CIFS_MOUNT_MAP_SPECIAL_CHR);
 		if (rc==0) {
 		if (rc==0) {
 			CIFSSMBRenameOpenFile(xid, pTcon, netfid, NULL,
 			CIFSSMBRenameOpenFile(xid, pTcon, netfid, NULL,
-					      cifs_sb->local_nls);
+					      cifs_sb->local_nls, 
+					      cifs_sb->mnt_cifs_flags & 
+						CIFS_MOUNT_MAP_SPECIAL_CHR);
 			CIFSSMBClose(xid, pTcon, netfid);
 			CIFSSMBClose(xid, pTcon, netfid);
 			direntry->d_inode->i_nlink--;
 			direntry->d_inode->i_nlink--;
 		}
 		}
@@ -439,7 +452,9 @@ int cifs_unlink(struct inode *inode, struct dentry *direntry)
 			if (!(pTcon->ses->flags & CIFS_SES_NT4))
 			if (!(pTcon->ses->flags & CIFS_SES_NT4))
 				rc = CIFSSMBSetTimes(xid, pTcon, full_path,
 				rc = CIFSSMBSetTimes(xid, pTcon, full_path,
 						     pinfo_buf,
 						     pinfo_buf,
-						     cifs_sb->local_nls);
+						     cifs_sb->local_nls,
+						     cifs_sb->mnt_cifs_flags & 
+							CIFS_MOUNT_MAP_SPECIAL_CHR);
 			else
 			else
 				rc = -EOPNOTSUPP;
 				rc = -EOPNOTSUPP;
 
 
@@ -461,7 +476,9 @@ int cifs_unlink(struct inode *inode, struct dentry *direntry)
 						 FILE_OPEN, SYNCHRONIZE |
 						 FILE_OPEN, SYNCHRONIZE |
 						 FILE_WRITE_ATTRIBUTES, 0,
 						 FILE_WRITE_ATTRIBUTES, 0,
 						 &netfid, &oplock, NULL,
 						 &netfid, &oplock, NULL,
-						 cifs_sb->local_nls);
+						 cifs_sb->local_nls,
+						 cifs_sb->mnt_cifs_flags & 
+						    CIFS_MOUNT_MAP_SPECIAL_CHR);
 				if (rc==0) {
 				if (rc==0) {
 					rc = CIFSSMBSetFileTimes(xid, pTcon,
 					rc = CIFSSMBSetFileTimes(xid, pTcon,
 								 pinfo_buf,
 								 pinfo_buf,
@@ -472,8 +489,10 @@ int cifs_unlink(struct inode *inode, struct dentry *direntry)
 			kfree(pinfo_buf);
 			kfree(pinfo_buf);
 		}
 		}
 		if (rc==0) {
 		if (rc==0) {
-			rc = CIFSSMBDelFile(xid, pTcon, full_path,
-					    cifs_sb->local_nls);
+			rc = CIFSSMBDelFile(xid, pTcon, full_path, 
+					    cifs_sb->local_nls, 
+					    cifs_sb->mnt_cifs_flags & 
+						CIFS_MOUNT_MAP_SPECIAL_CHR);
 			if (!rc) {
 			if (!rc) {
 				direntry->d_inode->i_nlink--;
 				direntry->d_inode->i_nlink--;
 			} else if (rc == -ETXTBSY) {
 			} else if (rc == -ETXTBSY) {
@@ -485,11 +504,15 @@ int cifs_unlink(struct inode *inode, struct dentry *direntry)
 						 CREATE_NOT_DIR |
 						 CREATE_NOT_DIR |
 						 CREATE_DELETE_ON_CLOSE,
 						 CREATE_DELETE_ON_CLOSE,
 						 &netfid, &oplock, NULL,
 						 &netfid, &oplock, NULL,
-						 cifs_sb->local_nls);
+						 cifs_sb->local_nls, 
+						 cifs_sb->mnt_cifs_flags & 
+						    CIFS_MOUNT_MAP_SPECIAL_CHR);
 				if (rc==0) {
 				if (rc==0) {
 					CIFSSMBRenameOpenFile(xid, pTcon,
 					CIFSSMBRenameOpenFile(xid, pTcon,
 						netfid, NULL,
 						netfid, NULL,
-						cifs_sb->local_nls);
+						cifs_sb->local_nls,
+						cifs_sb->mnt_cifs_flags &
+						    CIFS_MOUNT_MAP_SPECIAL_CHR);
 					CIFSSMBClose(xid, pTcon, netfid);
 					CIFSSMBClose(xid, pTcon, netfid);
 		                        direntry->d_inode->i_nlink--;
 		                        direntry->d_inode->i_nlink--;
 				}
 				}
@@ -534,7 +557,8 @@ int cifs_mkdir(struct inode *inode, struct dentry *direntry, int mode)
 		return -ENOMEM;
 		return -ENOMEM;
 	}
 	}
 	/* BB add setting the equivalent of mode via CreateX w/ACLs */
 	/* BB add setting the equivalent of mode via CreateX w/ACLs */
-	rc = CIFSSMBMkDir(xid, pTcon, full_path, cifs_sb->local_nls);
+	rc = CIFSSMBMkDir(xid, pTcon, full_path, cifs_sb->local_nls,
+			  cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR);
 	if (rc) {
 	if (rc) {
 		cFYI(1, ("cifs_mkdir returned 0x%x ", rc));
 		cFYI(1, ("cifs_mkdir returned 0x%x ", rc));
 		d_drop(direntry);
 		d_drop(direntry);
@@ -558,12 +582,16 @@ int cifs_mkdir(struct inode *inode, struct dentry *direntry, int mode)
 						    (__u64)current->euid,
 						    (__u64)current->euid,
 						    (__u64)current->egid,
 						    (__u64)current->egid,
 						    0 /* dev_t */,
 						    0 /* dev_t */,
-						    cifs_sb->local_nls);
+						    cifs_sb->local_nls,
+						    cifs_sb->mnt_cifs_flags &
+						    CIFS_MOUNT_MAP_SPECIAL_CHR);
 			} else {
 			} else {
 				CIFSSMBUnixSetPerms(xid, pTcon, full_path,
 				CIFSSMBUnixSetPerms(xid, pTcon, full_path,
 						    mode, (__u64)-1,
 						    mode, (__u64)-1,
 						    (__u64)-1, 0 /* dev_t */,
 						    (__u64)-1, 0 /* dev_t */,
-						    cifs_sb->local_nls);
+						    cifs_sb->local_nls,
+						    cifs_sb->mnt_cifs_flags & 
+						    CIFS_MOUNT_MAP_SPECIAL_CHR);
 			}
 			}
 		else {
 		else {
 			/* BB to be implemented via Windows secrty descriptors
 			/* BB to be implemented via Windows secrty descriptors
@@ -600,7 +628,8 @@ int cifs_rmdir(struct inode *inode, struct dentry *direntry)
 		return -ENOMEM;
 		return -ENOMEM;
 	}
 	}
 
 
-	rc = CIFSSMBRmDir(xid, pTcon, full_path, cifs_sb->local_nls);
+	rc = CIFSSMBRmDir(xid, pTcon, full_path, cifs_sb->local_nls,
+			  cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR);
 
 
 	if (!rc) {
 	if (!rc) {
 		inode->i_nlink--;
 		inode->i_nlink--;
@@ -653,7 +682,9 @@ int cifs_rename(struct inode *source_inode, struct dentry *source_direntry,
 	}
 	}
 
 
 	rc = CIFSSMBRename(xid, pTcon, fromName, toName,
 	rc = CIFSSMBRename(xid, pTcon, fromName, toName,
-			   cifs_sb_source->local_nls);
+			   cifs_sb_source->local_nls,
+			   cifs_sb_source->mnt_cifs_flags &
+				CIFS_MOUNT_MAP_SPECIAL_CHR);
 	if (rc == -EEXIST) {
 	if (rc == -EEXIST) {
 		/* check if they are the same file because rename of hardlinked
 		/* check if they are the same file because rename of hardlinked
 		   files is a noop */
 		   files is a noop */
@@ -665,11 +696,16 @@ int cifs_rename(struct inode *source_inode, struct dentry *source_direntry,
 		if (info_buf_source != NULL) {
 		if (info_buf_source != NULL) {
 			info_buf_target = info_buf_source + 1;
 			info_buf_target = info_buf_source + 1;
 			rc = CIFSSMBUnixQPathInfo(xid, pTcon, fromName,
 			rc = CIFSSMBUnixQPathInfo(xid, pTcon, fromName,
-				info_buf_source, cifs_sb_source->local_nls);
+				info_buf_source, cifs_sb_source->local_nls, 
+				cifs_sb_source->mnt_cifs_flags &
+					CIFS_MOUNT_MAP_SPECIAL_CHR);
 			if (rc == 0) {
 			if (rc == 0) {
 				rc = CIFSSMBUnixQPathInfo(xid, pTcon, toName,
 				rc = CIFSSMBUnixQPathInfo(xid, pTcon, toName,
 						info_buf_target,
 						info_buf_target,
-						cifs_sb_target->local_nls);
+						cifs_sb_target->local_nls,
+						/* remap based on source sb */
+						cifs_sb_source->mnt_cifs_flags &
+						    CIFS_MOUNT_MAP_SPECIAL_CHR);
 			}
 			}
 			if ((rc == 0) &&
 			if ((rc == 0) &&
 			    (info_buf_source->UniqueId ==
 			    (info_buf_source->UniqueId ==
@@ -685,7 +721,9 @@ int cifs_rename(struct inode *source_inode, struct dentry *source_direntry,
 				cifs_unlink(target_inode, target_direntry);
 				cifs_unlink(target_inode, target_direntry);
 				rc = CIFSSMBRename(xid, pTcon, fromName,
 				rc = CIFSSMBRename(xid, pTcon, fromName,
 						   toName,
 						   toName,
-						   cifs_sb_source->local_nls);
+						   cifs_sb_source->local_nls,
+						   cifs_sb_source->mnt_cifs_flags
+						   & CIFS_MOUNT_MAP_SPECIAL_CHR);
 			}
 			}
 			kfree(info_buf_source);
 			kfree(info_buf_source);
 		} /* if we can not get memory just leave rc as EEXIST */
 		} /* if we can not get memory just leave rc as EEXIST */
@@ -705,10 +743,14 @@ int cifs_rename(struct inode *source_inode, struct dentry *source_direntry,
 		   might not right be right access to request */
 		   might not right be right access to request */
 		rc = CIFSSMBOpen(xid, pTcon, fromName, FILE_OPEN, GENERIC_READ,
 		rc = CIFSSMBOpen(xid, pTcon, fromName, FILE_OPEN, GENERIC_READ,
 				 CREATE_NOT_DIR, &netfid, &oplock, NULL,
 				 CREATE_NOT_DIR, &netfid, &oplock, NULL,
-				 cifs_sb_source->local_nls);
+				 cifs_sb_source->local_nls, 
+				 cifs_sb_source->mnt_cifs_flags & 
+					CIFS_MOUNT_MAP_SPECIAL_CHR);
 		if (rc==0) {
 		if (rc==0) {
 			CIFSSMBRenameOpenFile(xid, pTcon, netfid, toName,
 			CIFSSMBRenameOpenFile(xid, pTcon, netfid, toName,
-					      cifs_sb_source->local_nls);
+					      cifs_sb_source->local_nls, 
+					      cifs_sb_source->mnt_cifs_flags &
+						CIFS_MOUNT_MAP_SPECIAL_CHR);
 			CIFSSMBClose(xid, pTcon, netfid);
 			CIFSSMBClose(xid, pTcon, netfid);
 		}
 		}
 	}
 	}
@@ -962,7 +1004,9 @@ int cifs_setattr(struct dentry *direntry, struct iattr *attrs)
 			   it by handle */
 			   it by handle */
 			rc = CIFSSMBSetEOF(xid, pTcon, full_path,
 			rc = CIFSSMBSetEOF(xid, pTcon, full_path,
 					   attrs->ia_size, FALSE,
 					   attrs->ia_size, FALSE,
-					   cifs_sb->local_nls);
+					   cifs_sb->local_nls, 
+					   cifs_sb->mnt_cifs_flags &
+						CIFS_MOUNT_MAP_SPECIAL_CHR);
 			cFYI(1, (" SetEOF by path (setattrs) rc = %d", rc));
 			cFYI(1, (" SetEOF by path (setattrs) rc = %d", rc));
 		}
 		}
 
 
@@ -999,7 +1043,9 @@ int cifs_setattr(struct dentry *direntry, struct iattr *attrs)
 	if ((cifs_sb->tcon->ses->capabilities & CAP_UNIX)
 	if ((cifs_sb->tcon->ses->capabilities & CAP_UNIX)
 	    && (attrs->ia_valid & (ATTR_MODE | ATTR_GID | ATTR_UID)))
 	    && (attrs->ia_valid & (ATTR_MODE | ATTR_GID | ATTR_UID)))
 		rc = CIFSSMBUnixSetPerms(xid, pTcon, full_path, mode, uid, gid,
 		rc = CIFSSMBUnixSetPerms(xid, pTcon, full_path, mode, uid, gid,
-					 0 /* dev_t */, cifs_sb->local_nls);
+					 0 /* dev_t */, cifs_sb->local_nls,
+					 cifs_sb->mnt_cifs_flags & 
+						CIFS_MOUNT_MAP_SPECIAL_CHR);
 	else if (attrs->ia_valid & ATTR_MODE) {
 	else if (attrs->ia_valid & ATTR_MODE) {
 		if ((mode & S_IWUGO) == 0) /* not writeable */ {
 		if ((mode & S_IWUGO) == 0) /* not writeable */ {
 			if ((cifsInode->cifsAttrs & ATTR_READONLY) == 0)
 			if ((cifsInode->cifsAttrs & ATTR_READONLY) == 0)
@@ -1048,7 +1094,9 @@ int cifs_setattr(struct dentry *direntry, struct iattr *attrs)
 		   via Handle (SetFileInfo) instead of by path */
 		   via Handle (SetFileInfo) instead of by path */
 		if (!(pTcon->ses->flags & CIFS_SES_NT4))
 		if (!(pTcon->ses->flags & CIFS_SES_NT4))
 			rc = CIFSSMBSetTimes(xid, pTcon, full_path, &time_buf,
 			rc = CIFSSMBSetTimes(xid, pTcon, full_path, &time_buf,
-					     cifs_sb->local_nls);
+					     cifs_sb->local_nls,
+					     cifs_sb->mnt_cifs_flags &
+						CIFS_MOUNT_MAP_SPECIAL_CHR);
 		else
 		else
 			rc = -EOPNOTSUPP;
 			rc = -EOPNOTSUPP;
 
 
@@ -1063,7 +1111,9 @@ int cifs_setattr(struct dentry *direntry, struct iattr *attrs)
 			rc = CIFSSMBOpen(xid, pTcon, full_path, FILE_OPEN,
 			rc = CIFSSMBOpen(xid, pTcon, full_path, FILE_OPEN,
 					 SYNCHRONIZE | FILE_WRITE_ATTRIBUTES,
 					 SYNCHRONIZE | FILE_WRITE_ATTRIBUTES,
 					 CREATE_NOT_DIR, &netfid, &oplock,
 					 CREATE_NOT_DIR, &netfid, &oplock,
-					 NULL, cifs_sb->local_nls);
+					 NULL, cifs_sb->local_nls,
+					 cifs_sb->mnt_cifs_flags &
+						CIFS_MOUNT_MAP_SPECIAL_CHR);
 			if (rc==0) {
 			if (rc==0) {
 				rc = CIFSSMBSetFileTimes(xid, pTcon, &time_buf,
 				rc = CIFSSMBSetFileTimes(xid, pTcon, &time_buf,
 							 netfid);
 							 netfid);

+ 14 - 4
fs/cifs/link.c

@@ -59,10 +59,14 @@ cifs_hardlink(struct dentry *old_file, struct inode *inode,
 
 
 	if (cifs_sb_target->tcon->ses->capabilities & CAP_UNIX)
 	if (cifs_sb_target->tcon->ses->capabilities & CAP_UNIX)
 		rc = CIFSUnixCreateHardLink(xid, pTcon, fromName, toName,
 		rc = CIFSUnixCreateHardLink(xid, pTcon, fromName, toName,
-					    cifs_sb_target->local_nls);
+					    cifs_sb_target->local_nls, 
+					    cifs_sb_target->mnt_cifs_flags &
+						CIFS_MOUNT_MAP_SPECIAL_CHR);
 	else {
 	else {
 		rc = CIFSCreateHardLink(xid, pTcon, fromName, toName,
 		rc = CIFSCreateHardLink(xid, pTcon, fromName, toName,
-					cifs_sb_target->local_nls);
+					cifs_sb_target->local_nls, 
+					cifs_sb_target->mnt_cifs_flags &
+						CIFS_MOUNT_MAP_SPECIAL_CHR);
 		if(rc == -EIO)
 		if(rc == -EIO)
 			rc = -EOPNOTSUPP;  
 			rc = -EOPNOTSUPP;  
 	}
 	}
@@ -260,7 +264,10 @@ cifs_readlink(struct dentry *direntry, char __user *pBuffer, int buflen)
 				cifs_sb->local_nls);
 				cifs_sb->local_nls);
 	else {
 	else {
 		rc = CIFSSMBOpen(xid, pTcon, full_path, FILE_OPEN, GENERIC_READ,
 		rc = CIFSSMBOpen(xid, pTcon, full_path, FILE_OPEN, GENERIC_READ,
-				OPEN_REPARSE_POINT,&fid, &oplock, NULL, cifs_sb->local_nls);
+				OPEN_REPARSE_POINT,&fid, &oplock, NULL, 
+				cifs_sb->local_nls, 
+				cifs_sb->mnt_cifs_flags & 
+					CIFS_MOUNT_MAP_SPECIAL_CHR);
 		if(!rc) {
 		if(!rc) {
 			rc = CIFSSMBQueryReparseLinkInfo(xid, pTcon, full_path,
 			rc = CIFSSMBQueryReparseLinkInfo(xid, pTcon, full_path,
 				tmpbuffer,
 				tmpbuffer,
@@ -279,7 +286,10 @@ cifs_readlink(struct dentry *direntry, char __user *pBuffer, int buflen)
 					strncpy(tmp_path, pTcon->treeName, MAX_TREE_SIZE);
 					strncpy(tmp_path, pTcon->treeName, MAX_TREE_SIZE);
 					strncat(tmp_path, full_path, MAX_PATHCONF);
 					strncat(tmp_path, full_path, MAX_PATHCONF);
 					rc = get_dfs_path(xid, pTcon->ses, tmp_path,
 					rc = get_dfs_path(xid, pTcon->ses, tmp_path,
-						cifs_sb->local_nls, &num_referrals, &referrals);
+						cifs_sb->local_nls,
+						&num_referrals, &referrals,
+						cifs_sb->mnt_cifs_flags &
+						    CIFS_MOUNT_MAP_SPECIAL_CHR);
 					cFYI(1,("Get DFS for %s rc = %d ",tmp_path, rc));
 					cFYI(1,("Get DFS for %s rc = %d ",tmp_path, rc));
 					if((num_referrals == 0) && (rc == 0))
 					if((num_referrals == 0) && (rc == 0))
 						rc = -EACCES;
 						rc = -EACCES;

+ 4 - 18
fs/cifs/readdir.c

@@ -314,7 +314,7 @@ static int initiate_cifs_search(const int xid, struct file *file)
 		return -EINVAL;
 		return -EINVAL;
 
 
 	down(&file->f_dentry->d_sb->s_vfs_rename_sem);
 	down(&file->f_dentry->d_sb->s_vfs_rename_sem);
-	full_path = build_wildcard_path_from_dentry(file->f_dentry);
+	full_path = build_path_from_dentry(file->f_dentry);
 	up(&file->f_dentry->d_sb->s_vfs_rename_sem);
 	up(&file->f_dentry->d_sb->s_vfs_rename_sem);
 
 
 	if(full_path == NULL) {
 	if(full_path == NULL) {
@@ -333,8 +333,9 @@ ffirst_retry:
 		cifsFile->srch_inf.info_level = SMB_FIND_FILE_DIRECTORY_INFO;
 		cifsFile->srch_inf.info_level = SMB_FIND_FILE_DIRECTORY_INFO;
 	}
 	}
 
 
-	rc = CIFSFindFirst(xid, pTcon,full_path,cifs_sb->local_nls, 
-		&cifsFile->netfid, &cifsFile->srch_inf); 
+	rc = CIFSFindFirst(xid, pTcon,full_path,cifs_sb->local_nls,
+		&cifsFile->netfid, &cifsFile->srch_inf,
+		cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR);
 	if(rc == 0)
 	if(rc == 0)
 		cifsFile->invalidHandle = FALSE;
 		cifsFile->invalidHandle = FALSE;
 	if((rc == -EOPNOTSUPP) && 
 	if((rc == -EOPNOTSUPP) && 
@@ -600,12 +601,10 @@ static int cifs_get_name_from_search_buf(struct qstr *pqst,
 	if(unicode) {
 	if(unicode) {
 		/* BB fixme - test with long names */
 		/* BB fixme - test with long names */
 		/* Note converted filename can be longer than in unicode */
 		/* Note converted filename can be longer than in unicode */
-#ifdef CONFIG_CIFS_EXPERIMENTAL
 		if(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR)
 		if(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR)
 			pqst->len = cifs_convertUCSpath((char *)pqst->name,
 			pqst->len = cifs_convertUCSpath((char *)pqst->name,
 					(__le16 *)filename, len/2, nlt);
 					(__le16 *)filename, len/2, nlt);
 		else
 		else
-#endif /* CIFS_EXPERIMENTAL */
 			pqst->len = cifs_strfromUCS_le((char *)pqst->name,
 			pqst->len = cifs_strfromUCS_le((char *)pqst->name,
 					(wchar_t *)filename,len/2,nlt);
 					(wchar_t *)filename,len/2,nlt);
 	} else {
 	} else {
@@ -849,19 +848,6 @@ int cifs_readdir(struct file *file, void *direntry, filldir_t filldir)
 				break;
 				break;
 			}
 			}
 
 
-			/* BB FIXME - need to enable the below code BB */
-
-		/* if((!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SERVER_INUM)) ||
-			   (cifsFile->srch_inf.info_level != 
-				   something that supports server inodes)) {
-				create dentry
-				create inode
-				fill in inode new_inode (getting local i_ino)
-			}
-			also create local inode for performance reasons (so we 
-			have a cache of inode metadata) unless this new mount 
-			parm says otherwise */
-
 			rc = cifs_filldir(current_entry, file, 
 			rc = cifs_filldir(current_entry, file, 
 					filldir, direntry,tmp_buf);
 					filldir, direntry,tmp_buf);
 			file->f_pos++;
 			file->f_pos++;

+ 25 - 10
fs/cifs/xattr.c

@@ -83,7 +83,8 @@ int cifs_removexattr(struct dentry * direntry, const char * ea_name)
 
 
 		ea_name+=5; /* skip past user. prefix */
 		ea_name+=5; /* skip past user. prefix */
 		rc = CIFSSMBSetEA(xid,pTcon,full_path,ea_name,NULL,
 		rc = CIFSSMBSetEA(xid,pTcon,full_path,ea_name,NULL,
-			(__u16)0, cifs_sb->local_nls);
+			(__u16)0, cifs_sb->local_nls,
+			cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR);
 	}
 	}
 remove_ea_exit:
 remove_ea_exit:
 	if (full_path)
 	if (full_path)
@@ -147,14 +148,16 @@ int cifs_setxattr(struct dentry * direntry, const char * ea_name,
 		}
 		}
 		ea_name += 5; /* skip past user. prefix */
 		ea_name += 5; /* skip past user. prefix */
 		rc = CIFSSMBSetEA(xid,pTcon,full_path,ea_name,ea_value,
 		rc = CIFSSMBSetEA(xid,pTcon,full_path,ea_name,ea_value,
-			(__u16)value_size, cifs_sb->local_nls);
+			(__u16)value_size, cifs_sb->local_nls,
+			cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR);
 	} else if(strncmp(ea_name, CIFS_XATTR_OS2_PREFIX,4) == 0) {
 	} else if(strncmp(ea_name, CIFS_XATTR_OS2_PREFIX,4) == 0) {
 		if(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_XATTR)
 		if(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_XATTR)
 			goto set_ea_exit;
 			goto set_ea_exit;
 
 
 		ea_name += 4; /* skip past os2. prefix */
 		ea_name += 4; /* skip past os2. prefix */
 		rc = CIFSSMBSetEA(xid,pTcon,full_path,ea_name,ea_value,
 		rc = CIFSSMBSetEA(xid,pTcon,full_path,ea_name,ea_value,
-			(__u16)value_size, cifs_sb->local_nls);
+			(__u16)value_size, cifs_sb->local_nls,
+			cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR);
 	} else {
 	} else {
 		int temp; 
 		int temp; 
 		temp = strncmp(ea_name,POSIX_ACL_XATTR_ACCESS,
 		temp = strncmp(ea_name,POSIX_ACL_XATTR_ACCESS,
@@ -164,7 +167,9 @@ int cifs_setxattr(struct dentry * direntry, const char * ea_name,
 			if(sb->s_flags & MS_POSIXACL)
 			if(sb->s_flags & MS_POSIXACL)
 				rc = CIFSSMBSetPosixACL(xid, pTcon,full_path,
 				rc = CIFSSMBSetPosixACL(xid, pTcon,full_path,
 					ea_value, (const int)value_size, 
 					ea_value, (const int)value_size, 
-					ACL_TYPE_ACCESS,cifs_sb->local_nls);
+					ACL_TYPE_ACCESS,cifs_sb->local_nls,
+					cifs_sb->mnt_cifs_flags & 
+						CIFS_MOUNT_MAP_SPECIAL_CHR);
 			cFYI(1,("set POSIX ACL rc %d",rc));
 			cFYI(1,("set POSIX ACL rc %d",rc));
 #else
 #else
 			cFYI(1,("set POSIX ACL not supported"));
 			cFYI(1,("set POSIX ACL not supported"));
@@ -174,7 +179,9 @@ int cifs_setxattr(struct dentry * direntry, const char * ea_name,
 			if(sb->s_flags & MS_POSIXACL)
 			if(sb->s_flags & MS_POSIXACL)
 				rc = CIFSSMBSetPosixACL(xid, pTcon,full_path,
 				rc = CIFSSMBSetPosixACL(xid, pTcon,full_path,
 					ea_value, (const int)value_size, 
 					ea_value, (const int)value_size, 
-					ACL_TYPE_DEFAULT, cifs_sb->local_nls);
+					ACL_TYPE_DEFAULT, cifs_sb->local_nls,
+					cifs_sb->mnt_cifs_flags & 
+						CIFS_MOUNT_MAP_SPECIAL_CHR);
 			cFYI(1,("set POSIX default ACL rc %d",rc));
 			cFYI(1,("set POSIX default ACL rc %d",rc));
 #else
 #else
 			cFYI(1,("set default POSIX ACL not supported"));
 			cFYI(1,("set default POSIX ACL not supported"));
@@ -240,20 +247,24 @@ ssize_t cifs_getxattr(struct dentry * direntry, const char * ea_name,
 		} /* BB add else when above is implemented */
 		} /* BB add else when above is implemented */
 		ea_name += 5; /* skip past user. prefix */
 		ea_name += 5; /* skip past user. prefix */
 		rc = CIFSSMBQueryEA(xid,pTcon,full_path,ea_name,ea_value,
 		rc = CIFSSMBQueryEA(xid,pTcon,full_path,ea_name,ea_value,
-			buf_size, cifs_sb->local_nls);
+			buf_size, cifs_sb->local_nls,
+			cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR);
 	} else if(strncmp(ea_name, CIFS_XATTR_OS2_PREFIX,4) == 0) {
 	} else if(strncmp(ea_name, CIFS_XATTR_OS2_PREFIX,4) == 0) {
 		if(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_XATTR)
 		if(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_XATTR)
 			goto get_ea_exit;
 			goto get_ea_exit;
 
 
 		ea_name += 4; /* skip past os2. prefix */
 		ea_name += 4; /* skip past os2. prefix */
 		rc = CIFSSMBQueryEA(xid,pTcon,full_path,ea_name,ea_value,
 		rc = CIFSSMBQueryEA(xid,pTcon,full_path,ea_name,ea_value,
-			buf_size, cifs_sb->local_nls);
+			buf_size, cifs_sb->local_nls,
+			cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR);
 	} else if(strncmp(ea_name,POSIX_ACL_XATTR_ACCESS,strlen(POSIX_ACL_XATTR_ACCESS)) == 0) {
 	} else if(strncmp(ea_name,POSIX_ACL_XATTR_ACCESS,strlen(POSIX_ACL_XATTR_ACCESS)) == 0) {
 #ifdef CONFIG_CIFS_POSIX
 #ifdef CONFIG_CIFS_POSIX
 		if(sb->s_flags & MS_POSIXACL)
 		if(sb->s_flags & MS_POSIXACL)
 			rc = CIFSSMBGetPosixACL(xid, pTcon, full_path,
 			rc = CIFSSMBGetPosixACL(xid, pTcon, full_path,
 				ea_value, buf_size, ACL_TYPE_ACCESS, 
 				ea_value, buf_size, ACL_TYPE_ACCESS, 
-				cifs_sb->local_nls);
+				cifs_sb->local_nls,
+				cifs_sb->mnt_cifs_flags & 
+					CIFS_MOUNT_MAP_SPECIAL_CHR);
 #else 
 #else 
 		cFYI(1,("query POSIX ACL not supported yet"));
 		cFYI(1,("query POSIX ACL not supported yet"));
 #endif /* CONFIG_CIFS_POSIX */
 #endif /* CONFIG_CIFS_POSIX */
@@ -262,7 +273,9 @@ ssize_t cifs_getxattr(struct dentry * direntry, const char * ea_name,
 		if(sb->s_flags & MS_POSIXACL)
 		if(sb->s_flags & MS_POSIXACL)
 			rc = CIFSSMBGetPosixACL(xid, pTcon, full_path,
 			rc = CIFSSMBGetPosixACL(xid, pTcon, full_path,
 				ea_value, buf_size, ACL_TYPE_DEFAULT, 
 				ea_value, buf_size, ACL_TYPE_DEFAULT, 
-				cifs_sb->local_nls);
+				cifs_sb->local_nls,
+				cifs_sb->mnt_cifs_flags & 
+					CIFS_MOUNT_MAP_SPECIAL_CHR);
 #else 
 #else 
 		cFYI(1,("query POSIX default ACL not supported yet"));
 		cFYI(1,("query POSIX default ACL not supported yet"));
 #endif
 #endif
@@ -328,7 +341,9 @@ ssize_t cifs_listxattr(struct dentry * direntry, char * data, size_t buf_size)
 		search server for EAs or streams to 
 		search server for EAs or streams to 
 		returns as xattrs */
 		returns as xattrs */
 	rc = CIFSSMBQAllEAs(xid,pTcon,full_path,data,buf_size,
 	rc = CIFSSMBQAllEAs(xid,pTcon,full_path,data,buf_size,
-				cifs_sb->local_nls);
+				cifs_sb->local_nls,
+				cifs_sb->mnt_cifs_flags & 
+					CIFS_MOUNT_MAP_SPECIAL_CHR);
 
 
 	if (full_path)
 	if (full_path)
 		kfree(full_path);
 		kfree(full_path);