[PATCH] cifs: character mapping of special characters (part 3 of 3)
Signed-off-by: Steve French (sfrench@us.ibm.com) Signed-off-by: Linus Torvalds <torvalds@osdl.org>
This commit is contained in:

committed by
Linus Torvalds

parent
6c91d362f1
commit
737b758c96
108
fs/cifs/dir.c
108
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)
|
||||
{
|
||||
|
Reference in New Issue
Block a user