From 737b758c965a9b223ac1243ab38d9e507ac86c64 Mon Sep 17 00:00:00 2001 From: Steve French Date: Thu, 28 Apr 2005 22:41:06 -0700 Subject: [PATCH] [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 --- fs/cifs/CHANGES | 2 +- fs/cifs/README | 4 +- fs/cifs/TODO | 3 + fs/cifs/cifsfs.c | 4 +- fs/cifs/cifsproto.h | 103 ++++++++++++-------- fs/cifs/cifssmb.c | 226 +++++++++++++++++++++----------------------- fs/cifs/connect.c | 25 ++--- fs/cifs/dir.c | 108 ++++----------------- fs/cifs/fcntl.c | 3 +- fs/cifs/file.c | 10 +- fs/cifs/inode.c | 106 +++++++++++++++------ fs/cifs/link.c | 18 +++- fs/cifs/readdir.c | 22 +---- fs/cifs/xattr.c | 35 +++++-- 14 files changed, 337 insertions(+), 332 deletions(-) diff --git a/fs/cifs/CHANGES b/fs/cifs/CHANGES index 412b6d243d53..de8858028d64 100644 --- a/fs/cifs/CHANGES +++ b/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 cifs_close. Add mount option for remapping reserved characters in 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 ------------ diff --git a/fs/cifs/README b/fs/cifs/README index 83e054576258..93900fc4adaa 100644 --- a/fs/cifs/README +++ b/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 and getfattr utilities. 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 allows the CIFS client to recognize files created with such characters by Windows's POSIX emulation. This can diff --git a/fs/cifs/TODO b/fs/cifs/TODO index a69227415a73..1e8490ed6948 100644 --- a/fs/cifs/TODO +++ b/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) +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) ==================================== See http://bugzilla.samba.org - search on product "CifsVFS" for diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c index ae48ef042977..3d5365b9f5ba 100644 --- a/fs/cifs/cifsfs.c +++ b/fs/cifs/cifsfs.c @@ -191,13 +191,13 @@ cifs_statfs(struct super_block *sb, struct kstatfs *buf) #ifdef CONFIG_CIFS_EXPERIMENTAL /* BB we could add a second check for a QFS Unix capability bit */ 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 on newer one */ if(rc) #endif /* CIFS_EXPERIMENTAL */ - rc = CIFSSMBQFSInfo(xid, pTcon, buf, cifs_sb->local_nls); + rc = CIFSSMBQFSInfo(xid, pTcon, buf); /* int f_type; diff --git a/fs/cifs/cifsproto.h b/fs/cifs/cifsproto.h index b486ba738d95..0010511083fc 100644 --- a/fs/cifs/cifsproto.h +++ b/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 map_smb_to_linux_error(struct smb_hdr *smb); 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 struct timespec cifs_NTtimeToUnix(u64 /* utc nanoseconds since 1601 */ ); 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, 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, __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, const unsigned char *searchName, FILE_ALL_INFO * findData, - const struct nls_table *nls_codepage); + const struct nls_table *nls_codepage, int remap); extern int CIFSSMBUnixQPathInfo(const int xid, struct cifsTconInfo *tcon, const unsigned char *searchName, 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, const unsigned char *searchName, unsigned char **targetUNCs, 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, 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, - 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, - struct kstatfs *FSData, - const struct nls_table *nls_codepage); + struct kstatfs *FSData); 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, - struct kstatfs *FSData, const struct nls_table *nls_codepage); + struct kstatfs *FSData); extern int CIFSSMBSetTimes(const int xid, struct cifsTconInfo *tcon, 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, const FILE_BASIC_INFO * data, __u16 fid); #if 0 @@ -143,36 +144,49 @@ extern int CIFSSMBSetAttrLegacy(int xid, struct cifsTconInfo *tcon, const struct nls_table *nls_codepage); #endif /* possibly unneeded function */ 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, - __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, 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, 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, - 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, 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, 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, - 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, struct cifsTconInfo *tcon, 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, struct cifsTconInfo *tcon, 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, struct cifsTconInfo *tcon, 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 int access_flags, const int omode, __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, 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); extern int CIFSGetSrvInodeNumber(const int xid, struct cifsTconInfo *tcon, 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, 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, const __u16 netfid, const __u64 len, @@ -243,29 +260,31 @@ extern int CIFSSMBCopy(int xid, const char *fromName, const __u16 target_tid, 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, - 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, 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, const unsigned char * searchName,const unsigned char * ea_name, 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, const char *fileName, const char * ea_name, 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, const unsigned char *searchName, 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, const unsigned char *fileName, 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, const int netfid, __u64 * pExtAttrBits, __u64 *pMask); #endif /* _CIFSPROTO_H */ diff --git a/fs/cifs/cifssmb.c b/fs/cifs/cifssmb.c index 237e3bf94bfe..f7c4914c3dd9 100644 --- a/fs/cifs/cifssmb.c +++ b/fs/cifs/cifssmb.c @@ -538,8 +538,8 @@ CIFSSMBLogoff(const int xid, struct cifsSesInfo *ses) } 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_RSP *pSMBr = NULL; @@ -555,9 +555,8 @@ DelFileRetry: if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { 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 *= 2; } else { /* BB improve the check for buffer overruns BB */ @@ -589,8 +588,8 @@ DelFileRetry: } 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_RSP *pSMBr = NULL; @@ -606,9 +605,8 @@ RmDirRetry: return rc; 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 *= 2; } else { /* BB improve the check for buffer overruns BB */ @@ -639,7 +637,7 @@ RmDirRetry: int 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; CREATE_DIRECTORY_REQ *pSMB = NULL; @@ -655,9 +653,8 @@ MkDirRetry: return rc; 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 *= 2; } 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 int access_flags, const int create_options, __u16 * netfid, int *pOplock, FILE_ALL_INFO * pfile_info, - const struct nls_table *nls_codepage) + const struct nls_table *nls_codepage, int remap) { int rc = -EACCES; OPEN_REQ *pSMB = NULL; @@ -710,10 +707,8 @@ openRetry: if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { count = 1; /* account for one byte pad to word boundary */ 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 *= 2; pSMB->NameLength = cpu_to_le16(name_len); @@ -1108,7 +1103,7 @@ CIFSSMBClose(const int xid, struct cifsTconInfo *tcon, int smb_file_id) int CIFSSMBRename(const int xid, struct cifsTconInfo *tcon, const char *fromName, const char *toName, - const struct nls_table *nls_codepage) + const struct nls_table *nls_codepage, int remap) { int rc = 0; RENAME_REQ *pSMB = NULL; @@ -1131,18 +1126,16 @@ renameRetry: if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { 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 *= 2; pSMB->OldFileName[name_len] = 0x04; /* pad */ /* protocol requires ASCII signature byte on Unicode string */ pSMB->OldFileName[name_len + 1] = 0x00; 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 *= 2; /* convert to bytes */ } else { /* BB improve the check for buffer overruns BB */ @@ -1182,7 +1175,8 @@ renameRetry: } 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_rsp *pSMBr = NULL; @@ -1227,9 +1221,11 @@ int CIFSSMBRenameOpenFile(const int xid,struct cifsTconInfo *pTcon, /* unicode only call */ if(target_name == NULL) { 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 { - 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); 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 CIFSSMBCopy(const int xid, struct cifsTconInfo *tcon, const char * fromName, 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; COPY_REQ *pSMB = NULL; @@ -1285,18 +1281,16 @@ copyRetry: pSMB->Flags = cpu_to_le16(flags & COPY_TREE); 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 *= 2; pSMB->OldFileName[name_len] = 0x04; /* pad */ /* protocol requires ASCII signature byte on Unicode string */ 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 *= 2; /* convert to bytes */ } else { /* BB improve the check for buffer overruns BB */ @@ -1425,7 +1419,7 @@ createSymLinkRetry: int CIFSUnixCreateHardLink(const int xid, struct cifsTconInfo *tcon, 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_RSP *pSMBr = NULL; @@ -1444,9 +1438,8 @@ createHardLinkRetry: return rc; 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 *= 2; @@ -1468,9 +1461,8 @@ createHardLinkRetry: data_offset = (char *) (&pSMB->hdr.Protocol) + offset; if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { 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 *= 2; } else { /* BB improve the check for buffer overruns BB */ @@ -1512,7 +1504,7 @@ createHardLinkRetry: int CIFSCreateHardLink(const int xid, struct cifsTconInfo *tcon, const char *fromName, const char *toName, - const struct nls_table *nls_codepage) + const struct nls_table *nls_codepage, int remap) { int rc = 0; NT_RENAME_REQ *pSMB = NULL; @@ -1539,17 +1531,15 @@ winCreateHardLinkRetry: if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { 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 *= 2; pSMB->OldFileName[name_len] = 0; /* pad */ pSMB->OldFileName[name_len + 1] = 0x04; 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 *= 2; /* convert to bytes */ } else { /* BB improve the check for buffer overruns BB */ @@ -1659,6 +1649,7 @@ querySymLinkRetry: name_len = UniStrnlen((wchar_t *) ((char *) &pSMBr->hdr.Protocol +data_offset), min_t(const int, buflen,count) / 2); + /* BB FIXME investigate remapping reserved chars here */ cifs_strfromUCS_le(symlinkinfo, (wchar_t *) ((char *)&pSMBr->hdr.Protocol + 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 */ -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 i; @@ -1912,7 +1904,7 @@ int CIFSSMBGetPosixACL(const int xid, struct cifsTconInfo *tcon, const unsigned char *searchName, 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 */ TRANSACTION2_QPI_REQ *pSMB = NULL; @@ -1932,8 +1924,8 @@ queryAclRetry: if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { 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 *= 2; pSMB->FileName[name_len] = 0; @@ -1997,8 +1989,9 @@ queryAclRetry: int CIFSSMBSetPosixACL(const int xid, struct cifsTconInfo *tcon, 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_rsp *pSMBr = NULL; @@ -2016,8 +2009,8 @@ setAclRetry: return rc; if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { 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 *= 2; } else { /* BB improve the check for buffer overruns BB */ @@ -2161,7 +2154,7 @@ int CIFSSMBQPathInfo(const int xid, struct cifsTconInfo *tcon, const unsigned char *searchName, 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 */ TRANSACTION2_QPI_REQ *pSMB = NULL; @@ -2180,9 +2173,8 @@ QPathInfoRetry: if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { 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 *= 2; } else { /* BB improve the check for buffer overruns BB */ @@ -2243,7 +2235,7 @@ int CIFSSMBUnixQPathInfo(const int xid, struct cifsTconInfo *tcon, const unsigned char *searchName, FILE_UNIX_BASIC_INFO * pFindData, - const struct nls_table *nls_codepage) + const struct nls_table *nls_codepage, int remap) { /* SMB_QUERY_FILE_UNIX_BASIC */ TRANSACTION2_QPI_REQ *pSMB = NULL; @@ -2262,9 +2254,8 @@ UnixQPathInfoRetry: if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { 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 *= 2; } else { /* BB improve the check for buffer overruns BB */ @@ -2344,7 +2335,7 @@ findUniqueRetry: if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { name_len = - cifs_strtoUCS((wchar_t *) pSMB->FileName, searchName, PATH_MAX + cifsConvertToUCS((wchar_t *) pSMB->FileName, searchName, PATH_MAX /* find define for this maxpathcomponent */ , nls_codepage); name_len++; /* trailing null */ @@ -2408,7 +2399,7 @@ CIFSFindFirst(const int xid, struct cifsTconInfo *tcon, const char *searchName, const struct nls_table *nls_codepage, __u16 * pnetfid, - struct cifs_search_info * psrch_inf) + struct cifs_search_info * psrch_inf, int remap) { /* level 257 SMB_ */ TRANSACTION2_FFIRST_REQ *pSMB = NULL; @@ -2419,7 +2410,7 @@ CIFSFindFirst(const int xid, struct cifsTconInfo *tcon, int name_len; __u16 params, byte_count; - cFYI(1, ("In FindFirst")); + cFYI(1, ("In FindFirst for %s",searchName)); findFirstRetry: rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB, @@ -2429,12 +2420,20 @@ findFirstRetry: if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { 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; + 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+1] = 0; + name_len += 2; } else { /* BB add check for overrun of SMB buf BB */ name_len = strnlen(searchName, PATH_MAX); name_len++; /* trailing null */ @@ -2691,7 +2690,7 @@ int CIFSGetSrvInodeNumber(const int xid, struct cifsTconInfo *tcon, const unsigned char *searchName, __u64 * inode_number, - const struct nls_table *nls_codepage) + const struct nls_table *nls_codepage, int remap) { int rc = 0; TRANSACTION2_QPI_REQ *pSMB = NULL; @@ -2712,8 +2711,8 @@ GetInodeNumberRetry: if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { 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 *= 2; } else { /* BB improve the check for buffer overruns BB */ @@ -2787,7 +2786,7 @@ CIFSGetDFSRefer(const int xid, struct cifsSesInfo *ses, const unsigned char *searchName, unsigned char **targetUNCs, 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 */ TRANSACTION2_GET_DFS_REFER_REQ *pSMB = NULL; @@ -2823,10 +2822,8 @@ getDFSRetry: if (ses->capabilities & CAP_UNICODE) { pSMB->hdr.Flags2 |= SMBFLG2_UNICODE; 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 *= 2; } else { /* BB improve the check for buffer overruns BB */ @@ -2954,8 +2951,7 @@ GetDFSRefExit: } 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 */ TRANSACTION2_QFSI_REQ *pSMB = NULL; @@ -3038,8 +3034,7 @@ QFSInfoRetry: } 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 */ TRANSACTION2_QFSI_REQ *pSMB = NULL; @@ -3107,8 +3102,7 @@ QFSAttributeRetry: } 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 */ TRANSACTION2_QFSI_REQ *pSMB = NULL; @@ -3161,8 +3155,8 @@ QFSDeviceRetry: else { __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset); response_data = - (FILE_SYSTEM_DEVICE_INFO - *) (((char *) &pSMBr->hdr.Protocol) + + (FILE_SYSTEM_DEVICE_INFO *) + (((char *) &pSMBr->hdr.Protocol) + data_offset); memcpy(&tcon->fsDevInfo, response_data, sizeof (FILE_SYSTEM_DEVICE_INFO)); @@ -3177,8 +3171,7 @@ QFSDeviceRetry: } 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 */ TRANSACTION2_QFSI_REQ *pSMB = NULL; @@ -3249,7 +3242,7 @@ QFSUnixRetry: int 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 */ TRANSACTION2_QFSI_REQ *pSMB = NULL; @@ -3341,7 +3334,8 @@ QFSPosixRetry: int 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_rsp *pSMBr = NULL; @@ -3360,9 +3354,8 @@ SetEOFRetry: if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { 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 *= 2; } 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 CIFSSMBSetTimes(const int xid, struct cifsTconInfo *tcon, const char *fileName, 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_RSP *pSMBr = NULL; @@ -3615,9 +3608,8 @@ SetTimesRetry: if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { 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 *= 2; } else { /* BB improve the check for buffer overruns BB */ @@ -3697,7 +3689,7 @@ SetAttrLgcyRetry: if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { name_len = - cifs_strtoUCS((wchar_t *) pSMB->fileName, fileName, + ConvertToUCS((wchar_t *) pSMB->fileName, fileName, PATH_MAX, nls_codepage); name_len++; /* trailing null */ name_len *= 2; @@ -3727,8 +3719,9 @@ SetAttrLgcyRetry: int 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_RSP *pSMBr = NULL; @@ -3747,9 +3740,8 @@ setPermsRetry: if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { 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 *= 2; } else { /* BB improve the check for buffer overruns BB */ @@ -3872,7 +3864,7 @@ ssize_t CIFSSMBQAllEAs(const int xid, struct cifsTconInfo *tcon, const unsigned char *searchName, 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 */ TRANSACTION2_QPI_REQ *pSMB = NULL; @@ -3893,9 +3885,8 @@ QAllEAsRetry: if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { 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 *= 2; } else { /* BB improve the check for buffer overruns BB */ @@ -4017,7 +4008,7 @@ QAllEAsRetry: ssize_t CIFSSMBQueryEA(const int xid,struct cifsTconInfo * tcon, const unsigned char * searchName,const unsigned char * ea_name, 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_RSP *pSMBr = NULL; @@ -4037,9 +4028,8 @@ QEARetry: if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { 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 *= 2; } else { /* BB improve the check for buffer overruns BB */ @@ -4165,7 +4155,8 @@ QEARetry: int CIFSSMBSetEA(const int xid, struct cifsTconInfo *tcon, const char *fileName, 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_rsp *pSMBr = NULL; @@ -4184,9 +4175,8 @@ SetEARetry: if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { 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 *= 2; } else { /* BB improve the check for buffer overruns BB */ diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c index 3d036bf689d8..1f22b85324cf 100644 --- a/fs/cifs/connect.c +++ b/fs/cifs/connect.c @@ -924,14 +924,15 @@ find_unc(__be32 new_target_ip_addr, char *uncName, char *userName) int 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 int num_referrals; int rc = 0; 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 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 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) + unsigned int *pnum_referrals, + unsigned char ** preferrals, int remap) { char *temp_unc; int rc = 0; @@ -971,7 +973,7 @@ get_dfs_path(int xid, struct cifsSesInfo *pSesInfo, } if (rc == 0) rc = CIFSGetDFSRefer(xid, pSesInfo, old_path, preferrals, - pnum_referrals, nls_codepage); + pnum_referrals, nls_codepage, remap); 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) && (strchr(volume_info.UNC + 3, '/') == 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) kfree(volume_info.UNC); FreeXid(xid); @@ -1523,10 +1524,10 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb, tcon->ses = pSesInfo; /* 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(!CIFSSMBQFSUnixInfo(xid, tcon, cifs_sb->local_nls)) { + if(!CIFSSMBQFSUnixInfo(xid, tcon)) { if(!volume_info.no_psx_acl) { if(CIFS_UNIX_POSIX_ACL_CAP & le64_to_cpu(tcon->fsUnixInfo.Capability)) diff --git a/fs/cifs/dir.c b/fs/cifs/dir.c index 12ba81d7b07f..e3137aa48cdd 100644 --- a/fs/cifs/dir.c +++ b/fs/cifs/dir.c @@ -101,68 +101,15 @@ cifs_bp_rename_retry: 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) return full_path; full_path[namelen] = '\\'; 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 */ @@ -235,7 +182,8 @@ cifs_create(struct inode *inode, struct dentry *direntry, int mode, rc = CIFSSMBOpen(xid, pTcon, full_path, disposition, 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) { cFYI(1, ("cifs_create returned 0x%x ", rc)); } else { @@ -248,13 +196,17 @@ cifs_create(struct inode *inode, struct dentry *direntry, int mode, (__u64)current->euid, (__u64)current->egid, 0 /* dev */, - cifs_sb->local_nls); + cifs_sb->local_nls, + cifs_sb->mnt_cifs_flags & + CIFS_MOUNT_MAP_SPECIAL_CHR); } else { CIFSSMBUnixSetPerms(xid, pTcon, full_path, mode, (__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 { /* 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) { rc = CIFSSMBUnixSetPerms(xid, pTcon, full_path, 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 { rc = CIFSSMBUnixSetPerms(xid, pTcon, 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) { @@ -447,36 +403,6 @@ cifs_lookup(struct inode *parent_dir_inode, struct dentry *direntry, struct name 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 cifs_d_revalidate(struct dentry *direntry, struct nameidata *nd) { diff --git a/fs/cifs/fcntl.c b/fs/cifs/fcntl.c index 9d24c40f1967..7d2a9202c39a 100644 --- a/fs/cifs/fcntl.c +++ b/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 */ rc = CIFSSMBOpen(xid, pTcon, full_path, FILE_OPEN, 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 */ if(rc) { cERROR(1,("Could not open directory for notify")); /* BB remove BB */ diff --git a/fs/cifs/file.c b/fs/cifs/file.c index 9c7755053099..1df26ddf68b1 100644 --- a/fs/cifs/file.c +++ b/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, 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) { cFYI(1, ("cifs_open returned 0x%x ", rc)); goto out; @@ -287,7 +288,9 @@ int cifs_open(struct inode *inode, struct file *file) CIFSSMBUnixSetPerms(xid, pTcon, full_path, inode->i_mode, (__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 { /* BB implement via Windows security descriptors eg 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, 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) { up(&pCifsFile->fh_sem); cFYI(1, ("cifs_open returned 0x%x ", rc)); diff --git a/fs/cifs/inode.c b/fs/cifs/inode.c index d73b0aa86775..670947288262 100644 --- a/fs/cifs/inode.c +++ b/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)); /* could have done a find first instead but this returns more info */ 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, sizeof(findData)); */ if (rc) { @@ -63,7 +64,9 @@ int cifs_get_inode_info_unix(struct inode **pinode, strncat(tmp_path, search_path, MAX_PATHCONF); rc = connect_to_dfs_path(xid, pTcon->ses, /* treename + */ tmp_path, - cifs_sb->local_nls); + cifs_sb->local_nls, + cifs_sb->mnt_cifs_flags & + CIFS_MOUNT_MAP_SPECIAL_CHR); kfree(tmp_path); /* BB fix up inode etc. */ @@ -210,7 +213,8 @@ int cifs_get_inode_info(struct inode **pinode, pfindData = (FILE_ALL_INFO *)buf; /* could do find first instead but this returns more info */ 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)); */ if (rc) { @@ -230,7 +234,9 @@ int cifs_get_inode_info(struct inode **pinode, strncat(tmp_path, search_path, MAX_PATHCONF); rc = connect_to_dfs_path(xid, pTcon->ses, /* treename + */ tmp_path, - cifs_sb->local_nls); + cifs_sb->local_nls, + cifs_sb->mnt_cifs_flags & + CIFS_MOUNT_MAP_SPECIAL_CHR); kfree(tmp_path); /* BB fix up inode etc. */ } else if (rc) { @@ -268,7 +274,9 @@ int cifs_get_inode_info(struct inode **pinode, rc1 = CIFSGetSrvInodeNumber(xid, pTcon, search_path, &inode_num, - cifs_sb->local_nls); + cifs_sb->local_nls, + cifs_sb->mnt_cifs_flags & + CIFS_MOUNT_MAP_SPECIAL_CHR); if(rc1) { cFYI(1,("GetSrvInodeNum rc %d", rc1)); /* BB EOPNOSUPP disable SERVER_INUM? */ @@ -410,7 +418,8 @@ int cifs_unlink(struct inode *inode, struct dentry *direntry) FreeXid(xid); 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) { 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, 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) { 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); 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)) rc = CIFSSMBSetTimes(xid, pTcon, full_path, pinfo_buf, - cifs_sb->local_nls); + cifs_sb->local_nls, + cifs_sb->mnt_cifs_flags & + CIFS_MOUNT_MAP_SPECIAL_CHR); else rc = -EOPNOTSUPP; @@ -461,7 +476,9 @@ int cifs_unlink(struct inode *inode, struct dentry *direntry) FILE_OPEN, SYNCHRONIZE | FILE_WRITE_ATTRIBUTES, 0, &netfid, &oplock, NULL, - cifs_sb->local_nls); + cifs_sb->local_nls, + cifs_sb->mnt_cifs_flags & + CIFS_MOUNT_MAP_SPECIAL_CHR); if (rc==0) { rc = CIFSSMBSetFileTimes(xid, pTcon, pinfo_buf, @@ -472,8 +489,10 @@ int cifs_unlink(struct inode *inode, struct dentry *direntry) kfree(pinfo_buf); } 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) { direntry->d_inode->i_nlink--; } else if (rc == -ETXTBSY) { @@ -485,11 +504,15 @@ int cifs_unlink(struct inode *inode, struct dentry *direntry) CREATE_NOT_DIR | CREATE_DELETE_ON_CLOSE, &netfid, &oplock, NULL, - cifs_sb->local_nls); + cifs_sb->local_nls, + cifs_sb->mnt_cifs_flags & + CIFS_MOUNT_MAP_SPECIAL_CHR); if (rc==0) { 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); direntry->d_inode->i_nlink--; } @@ -534,7 +557,8 @@ int cifs_mkdir(struct inode *inode, struct dentry *direntry, int mode) return -ENOMEM; } /* 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) { cFYI(1, ("cifs_mkdir returned 0x%x ", rc)); d_drop(direntry); @@ -558,12 +582,16 @@ int cifs_mkdir(struct inode *inode, struct dentry *direntry, int mode) (__u64)current->euid, (__u64)current->egid, 0 /* dev_t */, - cifs_sb->local_nls); + cifs_sb->local_nls, + cifs_sb->mnt_cifs_flags & + CIFS_MOUNT_MAP_SPECIAL_CHR); } else { CIFSSMBUnixSetPerms(xid, pTcon, full_path, mode, (__u64)-1, (__u64)-1, 0 /* dev_t */, - cifs_sb->local_nls); + cifs_sb->local_nls, + cifs_sb->mnt_cifs_flags & + CIFS_MOUNT_MAP_SPECIAL_CHR); } else { /* BB to be implemented via Windows secrty descriptors @@ -600,7 +628,8 @@ int cifs_rmdir(struct inode *inode, struct dentry *direntry) 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) { inode->i_nlink--; @@ -653,7 +682,9 @@ int cifs_rename(struct inode *source_inode, struct dentry *source_direntry, } 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) { /* check if they are the same file because rename of hardlinked files is a noop */ @@ -665,11 +696,16 @@ int cifs_rename(struct inode *source_inode, struct dentry *source_direntry, if (info_buf_source != NULL) { info_buf_target = info_buf_source + 1; 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) { rc = CIFSSMBUnixQPathInfo(xid, pTcon, toName, 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) && (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); 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); } kfree(info_buf_source); } /* 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 */ rc = CIFSSMBOpen(xid, pTcon, fromName, FILE_OPEN, GENERIC_READ, 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) { 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); } } @@ -962,7 +1004,9 @@ int cifs_setattr(struct dentry *direntry, struct iattr *attrs) it by handle */ rc = CIFSSMBSetEOF(xid, pTcon, full_path, 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)); } @@ -999,7 +1043,9 @@ int cifs_setattr(struct dentry *direntry, struct iattr *attrs) if ((cifs_sb->tcon->ses->capabilities & CAP_UNIX) && (attrs->ia_valid & (ATTR_MODE | ATTR_GID | ATTR_UID))) 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) { if ((mode & S_IWUGO) == 0) /* not writeable */ { 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 */ if (!(pTcon->ses->flags & CIFS_SES_NT4)) 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 rc = -EOPNOTSUPP; @@ -1063,7 +1111,9 @@ int cifs_setattr(struct dentry *direntry, struct iattr *attrs) rc = CIFSSMBOpen(xid, pTcon, full_path, FILE_OPEN, SYNCHRONIZE | FILE_WRITE_ATTRIBUTES, 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) { rc = CIFSSMBSetFileTimes(xid, pTcon, &time_buf, netfid); diff --git a/fs/cifs/link.c b/fs/cifs/link.c index 1455810ba1cb..bde0fabfece0 100644 --- a/fs/cifs/link.c +++ b/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) 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 { 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) rc = -EOPNOTSUPP; } @@ -260,7 +264,10 @@ cifs_readlink(struct dentry *direntry, char __user *pBuffer, int buflen) cifs_sb->local_nls); else { 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) { rc = CIFSSMBQueryReparseLinkInfo(xid, pTcon, full_path, tmpbuffer, @@ -279,7 +286,10 @@ cifs_readlink(struct dentry *direntry, char __user *pBuffer, int buflen) strncpy(tmp_path, pTcon->treeName, MAX_TREE_SIZE); strncat(tmp_path, full_path, MAX_PATHCONF); 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)); if((num_referrals == 0) && (rc == 0)) rc = -EACCES; diff --git a/fs/cifs/readdir.c b/fs/cifs/readdir.c index 4a33add24d53..7ca876b6f2ab 100644 --- a/fs/cifs/readdir.c +++ b/fs/cifs/readdir.c @@ -314,7 +314,7 @@ static int initiate_cifs_search(const int xid, struct file *file) return -EINVAL; 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); if(full_path == NULL) { @@ -333,8 +333,9 @@ ffirst_retry: 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) cifsFile->invalidHandle = FALSE; if((rc == -EOPNOTSUPP) && @@ -600,12 +601,10 @@ static int cifs_get_name_from_search_buf(struct qstr *pqst, if(unicode) { /* BB fixme - test with long names */ /* Note converted filename can be longer than in unicode */ -#ifdef CONFIG_CIFS_EXPERIMENTAL if(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR) pqst->len = cifs_convertUCSpath((char *)pqst->name, (__le16 *)filename, len/2, nlt); else -#endif /* CIFS_EXPERIMENTAL */ pqst->len = cifs_strfromUCS_le((char *)pqst->name, (wchar_t *)filename,len/2,nlt); } else { @@ -849,19 +848,6 @@ int cifs_readdir(struct file *file, void *direntry, filldir_t filldir) 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, filldir, direntry,tmp_buf); file->f_pos++; diff --git a/fs/cifs/xattr.c b/fs/cifs/xattr.c index 9a41bee11c5a..c1e02eff1d25 100644 --- a/fs/cifs/xattr.c +++ b/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 */ 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: if (full_path) @@ -147,14 +148,16 @@ int cifs_setxattr(struct dentry * direntry, const char * ea_name, } ea_name += 5; /* skip past user. prefix */ 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) { if(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_XATTR) goto set_ea_exit; ea_name += 4; /* skip past os2. prefix */ 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 { int temp; 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) rc = CIFSSMBSetPosixACL(xid, pTcon,full_path, 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)); #else 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) rc = CIFSSMBSetPosixACL(xid, pTcon,full_path, 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)); #else 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 */ ea_name += 5; /* skip past user. prefix */ 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) { if(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_XATTR) goto get_ea_exit; ea_name += 4; /* skip past os2. prefix */ 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) { #ifdef CONFIG_CIFS_POSIX if(sb->s_flags & MS_POSIXACL) rc = CIFSSMBGetPosixACL(xid, pTcon, full_path, 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 cFYI(1,("query POSIX ACL not supported yet")); #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) rc = CIFSSMBGetPosixACL(xid, pTcon, full_path, 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 cFYI(1,("query POSIX default ACL not supported yet")); #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 returns as xattrs */ 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) kfree(full_path);