提交 737b758c 编写于 作者: S Steve French 提交者: Linus Torvalds

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

Signed-off-by: Steve French (sfrench@us.ibm.com)
Signed-off-by: NLinus Torvalds <torvalds@osdl.org>
上级 6c91d362
......@@ -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
------------
......
......@@ -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
......
......@@ -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
......
......@@ -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;
......
......@@ -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 */
此差异已折叠。
......@@ -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))
......
......@@ -101,68 +101,15 @@ build_path_from_dentry(struct dentry *direntry)
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)
{
......
......@@ -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 */
......
......@@ -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));
......
......@@ -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);
......
......@@ -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;
......
......@@ -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 @@ static int initiate_cifs_search(const int xid, struct file *file)
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++;
......
......@@ -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);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册