Commit 4659e8f4 authored by Steve French's avatar Steve French

Fix search handle leak on search rewind. Fix setting of uid

and gid in local inode (not just remote)
parent af47c86f
Version 0.68
------------
Fix search handle leak on rewind. Fix setuid and gid so that they are
reflected in the local inode immediately. Cleanup of whitespace
to make 2.4 and 2.5 versions more consistent.
Version 0.67 Version 0.67
------------ ------------
Fix signal sending so that captive thread (cifsd) exits on umount Fix signal sending so that captive thread (cifsd) exits on umount
(which was causing the warning in kmem_cache_free of the request buffers (which was causing the warning in kmem_cache_free of the request buffers
at rmmod time). This had broken as a sideeffect of the recent global at rmmod time). This had broken as a sideeffect of the recent global
kernel change to daemonize kernel change to daemonize. Fix memory leak in readdir code which
showed up in "ls -R" (and applications that did search rewinding).
Version 0.66 Version 0.66
------------ ------------
......
...@@ -54,7 +54,7 @@ unsigned int ntlmv2_support = 0; ...@@ -54,7 +54,7 @@ unsigned int ntlmv2_support = 0;
unsigned int sign_CIFS_PDUs = 0; unsigned int sign_CIFS_PDUs = 0;
extern int cifs_mount(struct super_block *, struct cifs_sb_info *, char *, extern int cifs_mount(struct super_block *, struct cifs_sb_info *, char *,
char *); char *);
extern int cifs_umount(struct super_block *, struct cifs_sb_info *); extern int cifs_umount(struct super_block *, struct cifs_sb_info *);
void cifs_proc_init(void); void cifs_proc_init(void);
void cifs_proc_clean(void); void cifs_proc_clean(void);
...@@ -178,8 +178,10 @@ cifs_alloc_inode(struct super_block *sb) ...@@ -178,8 +178,10 @@ cifs_alloc_inode(struct super_block *sb)
cifs_inode->cifsAttrs = 0x20; /* default */ cifs_inode->cifsAttrs = 0x20; /* default */
atomic_set(&cifs_inode->inUse, 0); atomic_set(&cifs_inode->inUse, 0);
cifs_inode->time = 0; cifs_inode->time = 0;
if(oplockEnabled) if(oplockEnabled) {
cifs_inode->clientCanCacheAll = 1; cifs_inode->clientCanCacheRead = 1;
cifs_inode->clientCanCacheAll = 1;
}
INIT_LIST_HEAD(&cifs_inode->openFileList); INIT_LIST_HEAD(&cifs_inode->openFileList);
return &cifs_inode->vfs_inode; return &cifs_inode->vfs_inode;
} }
......
...@@ -445,6 +445,10 @@ parse_mount_options(char *options, char *devname, struct smb_vol *vol) ...@@ -445,6 +445,10 @@ parse_mount_options(char *options, char *devname, struct smb_vol *vol)
printk(KERN_WARNING "CIFS: Unknown mount option %s\n",data); printk(KERN_WARNING "CIFS: Unknown mount option %s\n",data);
} }
if (vol->UNC == NULL) { if (vol->UNC == NULL) {
if(devname == NULL) {
printk(KERN_WARNING "CIFS: Missing UNC name for mount target\n");
return 1;
}
if (strnlen(devname, 300) < 300) { if (strnlen(devname, 300) < 300) {
vol->UNC = devname; vol->UNC = devname;
if (strncmp(vol->UNC, "//", 2) == 0) { if (strncmp(vol->UNC, "//", 2) == 0) {
...@@ -2288,11 +2292,6 @@ cifs_umount(struct super_block *sb, struct cifs_sb_info *cifs_sb) ...@@ -2288,11 +2292,6 @@ cifs_umount(struct super_block *sb, struct cifs_sb_info *cifs_sb)
if (ses) { if (ses) {
set_current_state(TASK_INTERRUPTIBLE); set_current_state(TASK_INTERRUPTIBLE);
schedule_timeout(HZ / 2); schedule_timeout(HZ / 2);
/* if ((ses->server) && (ses->server->ssocket)) {
cFYI(1,("Releasing socket "));
sock_release(ses->server->ssocket);
kfree(ses->server);
} */
} }
if (ses) if (ses)
sesInfoFree(ses); sesInfoFree(ses);
......
...@@ -1091,18 +1091,29 @@ cifs_readdir(struct file *file, void *direntry, filldir_t filldir) ...@@ -1091,18 +1091,29 @@ cifs_readdir(struct file *file, void *direntry, filldir_t filldir)
file->f_pos++; file->f_pos++;
/* fallthrough */ /* fallthrough */
case 2: case 2:
/* Should we first check if file->private_data is null? */ /* do not reallocate search handle if rewind */
rc = CIFSFindFirst(xid, pTcon, full_path, pfindData, if(file->private_data == NULL) {
rc = CIFSFindFirst(xid, pTcon, full_path, pfindData,
&findParms, cifs_sb->local_nls, &findParms, cifs_sb->local_nls,
&Unicode, &UnixSearch); &Unicode, &UnixSearch);
cFYI(1, cFYI(1,
("Count: %d End: %d ", findParms.SearchCount, ("Count: %d End: %d ", findParms.SearchCount,
findParms.EndofSearch)); findParms.EndofSearch));
} else {
cFYI(1,("Search rewinding on %s",full_path));
goto readdir_rewind;
}
if (rc == 0) { if (rc == 0) {
searchHandle = findParms.SearchHandle; searchHandle = findParms.SearchHandle;
file->private_data = if(file->private_data == NULL)
kmalloc(sizeof (struct cifsFileInfo), GFP_KERNEL); file->private_data =
kmalloc(sizeof(struct cifsFileInfo),
GFP_KERNEL);
else {
/* BB close search handle */
cFYI(1,("Search rewinding on %s",full_path));
}
if (file->private_data) { if (file->private_data) {
memset(file->private_data, 0, memset(file->private_data, 0,
sizeof (struct cifsFileInfo)); sizeof (struct cifsFileInfo));
...@@ -1186,7 +1197,9 @@ cifs_readdir(struct file *file, void *direntry, filldir_t filldir) ...@@ -1186,7 +1197,9 @@ cifs_readdir(struct file *file, void *direntry, filldir_t filldir)
rc = 0; /* unless parent directory disappeared - do not return error here (eg Access Denied or no more files) */ rc = 0; /* unless parent directory disappeared - do not return error here (eg Access Denied or no more files) */
} }
break; break;
readdir_rewind:
default: default:
/* BB rewrite eventually to better handle rewind */
if (file->private_data == NULL) { if (file->private_data == NULL) {
rc = -EBADF; rc = -EBADF;
cFYI(1, cFYI(1,
......
...@@ -86,11 +86,8 @@ cifs_get_inode_info_unix(struct inode **pinode, ...@@ -86,11 +86,8 @@ cifs_get_inode_info_unix(struct inode **pinode,
/* get new inode */ /* get new inode */
if (*pinode == NULL) { if (*pinode == NULL) {
*pinode = new_inode(sb); *pinode = new_inode(sb);
cFYI(1, (" Alloc new inode %p ", *pinode));
} }
inode = *pinode; inode = *pinode;
/* new_inode = iget(parent_dir_inode->i_sb, findData.IndexNumber); */
/* index number not reliable in response data */
cifsInfo = CIFS_I(inode); cifsInfo = CIFS_I(inode);
...@@ -215,7 +212,6 @@ cifs_get_inode_info(struct inode **pinode, ...@@ -215,7 +212,6 @@ cifs_get_inode_info(struct inode **pinode,
/* get new inode */ /* get new inode */
if (*pinode == NULL) { if (*pinode == NULL) {
*pinode = new_inode(sb); *pinode = new_inode(sb);
cFYI(1, (" Alloc new inode %p ", *pinode));
} }
inode = *pinode; inode = *pinode;
...@@ -457,8 +453,8 @@ cifs_rename(struct inode *source_inode, struct dentry *source_direntry, ...@@ -457,8 +453,8 @@ cifs_rename(struct inode *source_inode, struct dentry *source_direntry,
if (pTcon != cifs_sb_target->tcon) { if (pTcon != cifs_sb_target->tcon) {
return -EXDEV; /* BB actually could be allowed if same server, but return -EXDEV; /* BB actually could be allowed if same server, but
different share. Might eventually add support for this */ different share. Might eventually add support for this */
FreeXid(xid); FreeXid(xid);
} }
fromName = build_path_from_dentry(source_direntry); fromName = build_path_from_dentry(source_direntry);
toName = build_path_from_dentry(target_direntry); toName = build_path_from_dentry(target_direntry);
...@@ -504,7 +500,7 @@ cifs_revalidate(struct dentry *direntry) ...@@ -504,7 +500,7 @@ cifs_revalidate(struct dentry *direntry)
if (time_before(jiffies, cifsInode->time + HZ)) { if (time_before(jiffies, cifsInode->time + HZ)) {
if((S_ISREG(direntry->d_inode->i_mode) == 0) || if((S_ISREG(direntry->d_inode->i_mode) == 0) ||
(direntry->d_inode->i_nlink == 1)) { (direntry->d_inode->i_nlink == 1)) {
if (full_path) if (full_path)
kfree(full_path); kfree(full_path);
FreeXid(xid); FreeXid(xid);
...@@ -665,7 +661,7 @@ cifs_setattr(struct dentry *direntry, struct iattr *attrs) ...@@ -665,7 +661,7 @@ cifs_setattr(struct dentry *direntry, struct iattr *attrs)
if ((cifs_sb->tcon->ses->capabilities & CAP_UNIX) if ((cifs_sb->tcon->ses->capabilities & CAP_UNIX)
&& (attrs->ia_valid & (ATTR_MODE | ATTR_GID | ATTR_UID))) && (attrs->ia_valid & (ATTR_MODE | ATTR_GID | ATTR_UID)))
CIFSSMBUnixSetPerms(xid, pTcon, full_path, mode, uid, gid, rc = CIFSSMBUnixSetPerms(xid, pTcon, full_path, mode, uid, gid,
cifs_sb->local_nls); cifs_sb->local_nls);
else { /* BB to be implemented - via Windows security descriptors */ else { /* BB to be implemented - via Windows security descriptors */
/* CIFSSMBWinSetPerms(xid,pTcon,full_path,mode,uid,gid,cifs_sb->local_nls);*/ /* CIFSSMBWinSetPerms(xid,pTcon,full_path,mode,uid,gid,cifs_sb->local_nls);*/
...@@ -702,8 +698,9 @@ cifs_setattr(struct dentry *direntry, struct iattr *attrs) ...@@ -702,8 +698,9 @@ cifs_setattr(struct dentry *direntry, struct iattr *attrs)
rc = CIFSSMBSetTimes(xid, pTcon, full_path, &time_buf, rc = CIFSSMBSetTimes(xid, pTcon, full_path, &time_buf,
cifs_sb->local_nls); cifs_sb->local_nls);
} }
/* cifsInode->time = 0; */ /* force revalidate to get attributes when needed */
/* do not need local check to inode_check_ok since the server does that */
inode_setattr(direntry->d_inode, attrs);
if (full_path) if (full_path)
kfree(full_path); kfree(full_path);
FreeXid(xid); FreeXid(xid);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment