Commit fae319a5 authored by Steve French's avatar Steve French Committed by Steve French

Fix misc. minor memory leaks in error paths

parent a9075dec
Version 1.07
------------
Fix some small memory leaks in some unmount error paths.
Version 1.06
------------
Send NTCreateX with ATTR_POSIX if Linux/Unix extensions negotiated with server.
......
......@@ -127,10 +127,11 @@ cifs_read_super(struct super_block *sb, void *data,
iput(inode);
out_mount_failed:
if(cifs_sb) {
if(cifs_sb->local_nls)
unload_nls(cifs_sb->local_nls);
if(cifs_sb)
kfree(cifs_sb);
}
return rc;
}
......
......@@ -378,7 +378,7 @@ cifs_demultiplex_thread(struct TCP_Server_Info *server)
ses->server = NULL;
}
}
kfree(server);
read_unlock(&GlobalSMBSeslock);
} else {
spin_lock(&GlobalMid_Lock);
list_for_each(tmp, &server->pending_mid_q) {
......@@ -393,8 +393,22 @@ cifs_demultiplex_thread(struct TCP_Server_Info *server)
}
}
spin_unlock(&GlobalMid_Lock);
}
read_unlock(&GlobalSMBSeslock);
set_current_state(TASK_INTERRUPTIBLE);
/* 1/8th of sec should be more than enough time for them to exit */
schedule_timeout(HZ/8);
}
if (list_empty(&server->pending_mid_q)) {
/* mpx threads have not exited yet give them
at least the smb send timeout time for long ops */
cFYI(1, ("Wait for exit from demultiplex thread"));
set_current_state(TASK_INTERRUPTIBLE);
schedule_timeout(46 * HZ);
/* if threads still have not exited they are probably never
coming home not much else we can do but free the memory */
}
kfree(server);
cFYI(1, ("About to exit from demultiplex thread"));
return 0;
......@@ -765,7 +779,8 @@ connect_to_dfs_path(int xid, struct cifsSesInfo *pSesInfo,
the helper that resolves tcp names, mount to it, try to
tcon to it unmount it if fail */
/* BB free memory for referrals string BB */
if(referrals)
kfree(referrals);
return rc;
}
......@@ -955,6 +970,8 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
if (cifs_parse_mount_options(mount_data, devname, &volume_info)) {
if(volume_info.UNC)
kfree(volume_info.UNC);
if(volume_info.password)
kfree(volume_info.password);
FreeXid(xid);
return -EINVAL;
}
......@@ -966,6 +983,10 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
cifserror("No username specified ");
/* In userspace mount helper we can get user name from alternate
locations such as env variables and files on disk */
if(volume_info.UNC)
kfree(volume_info.UNC);
if(volume_info.password)
kfree(volume_info.password);
FreeXid(xid);
return -EINVAL;
}
......@@ -979,6 +1000,10 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
} else /* which servers DFS root would we conect to */ {
cERROR(1,
("CIFS mount error: No UNC path (e.g. -o unc=//192.168.1.100/public) specified "));
if(volume_info.UNC)
kfree(volume_info.UNC);
if(volume_info.password)
kfree(volume_info.password);
FreeXid(xid);
return -EINVAL;
}
......@@ -991,6 +1016,10 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
cifs_sb->local_nls = load_nls(volume_info.iocharset);
if(cifs_sb->local_nls == NULL) {
cERROR(1,("CIFS mount error: iocharset %s not found",volume_info.iocharset));
if(volume_info.UNC)
kfree(volume_info.UNC);
if(volume_info.password)
kfree(volume_info.password);
FreeXid(xid);
return -ELIBACC;
}
......@@ -1014,6 +1043,8 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
sock_release(csocket);
if(volume_info.UNC)
kfree(volume_info.UNC);
if(volume_info.password)
kfree(volume_info.password);
FreeXid(xid);
return rc;
}
......@@ -1024,6 +1055,8 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
sock_release(csocket);
if(volume_info.UNC)
kfree(volume_info.UNC);
if(volume_info.password)
kfree(volume_info.password);
FreeXid(xid);
return rc;
} else {
......@@ -1044,6 +1077,8 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
if (existingCifsSes) {
pSesInfo = existingCifsSes;
cFYI(1, ("Existing smb sess found "));
if(volume_info.password)
kfree(volume_info.password);
} else if (!rc) {
cFYI(1, ("Existing smb sess not found "));
pSesInfo = sesInfoAlloc();
......@@ -1070,7 +1105,9 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
up(&pSesInfo->sesSem);
if(!rc)
atomic_inc(&srvTcp->socketUseCount);
}
} else
if(volume_info.password)
kfree(volume_info.password);
}
/* search for existing tcon to this server share */
......@@ -2494,6 +2531,8 @@ CIFSTCon(unsigned int xid, struct cifsSesInfo *ses,
if (((long) bcc_ptr + (2 * length)) -
(long) pByteArea(smb_buffer_response) <=
BCC(smb_buffer_response)) {
if(tcon->nativeFileSystem)
kfree(tcon->nativeFileSystem);
tcon->nativeFileSystem =
cifs_kcalloc(length + 2, GFP_KERNEL);
cifs_strfromUCS_le(tcon->nativeFileSystem,
......@@ -2510,6 +2549,8 @@ CIFSTCon(unsigned int xid, struct cifsSesInfo *ses,
if (((long) bcc_ptr + length) -
(long) pByteArea(smb_buffer_response) <=
BCC(smb_buffer_response)) {
if(tcon->nativeFileSystem)
kfree(tcon->nativeFileSystem);
tcon->nativeFileSystem =
cifs_kcalloc(length + 1, GFP_KERNEL);
strncpy(tcon->nativeFileSystem, bcc_ptr,
......
......@@ -150,11 +150,12 @@ cifs_open(struct inode *inode, struct file *file)
cFYI(1, ("cifs_open returned 0x%x ", rc));
cFYI(1, ("oplock: %d ", oplock));
} else {
if(file->private_data)
kfree(file->private_data);
file->private_data =
kmalloc(sizeof (struct cifsFileInfo), GFP_KERNEL);
if (file->private_data) {
memset(file->private_data, 0,
sizeof (struct cifsFileInfo));
memset(file->private_data, 0, sizeof(struct cifsFileInfo));
pCifsFile = (struct cifsFileInfo *) file->private_data;
pCifsFile->netfid = netfid;
pCifsFile->pid = current->pid;
......@@ -183,7 +184,7 @@ cifs_open(struct inode *inode, struct file *file)
struct timespec temp;
temp = cifs_NTtimeToUnix(le64_to_cpu(buf->LastWriteTime));
if(timespec_equal(&file->f_dentry->d_inode->i_mtime,&temp) &&
(file->f_dentry->d_inode->i_size == le64_to_cpu(buf->EndOfFile))) {
(file->f_dentry->d_inode->i_size == (loff_t)le64_to_cpu(buf->EndOfFile))) {
cFYI(1,("inode unchanged on server"));
} else {
cFYI(1,("invalidating remote inode since open detected it changed"));
......@@ -1497,8 +1498,7 @@ cifs_readdir(struct file *file, void *direntry, filldir_t filldir)
searchHandle = findParms.SearchHandle;
if(file->private_data == NULL)
file->private_data =
kmalloc(sizeof(struct cifsFileInfo),
GFP_KERNEL);
kmalloc(sizeof(struct cifsFileInfo),GFP_KERNEL);
if (file->private_data) {
memset(file->private_data, 0,
sizeof (struct cifsFileInfo));
......
......@@ -96,6 +96,8 @@ cifs_follow_link(struct dentry *direntry, struct nameidata *nd)
pTcon = cifs_sb->tcon;
target_path = kmalloc(PATH_MAX, GFP_KERNEL);
if(target_path == NULL) {
if (full_path)
kfree(full_path);
FreeXid(xid);
return -ENOMEM;
}
......@@ -212,6 +214,8 @@ cifs_readlink(struct dentry *direntry, char *pBuffer, int buflen)
len = buflen;
tmpbuffer = kmalloc(len,GFP_KERNEL);
if(tmpbuffer == NULL) {
if (full_path)
kfree(full_path);
FreeXid(xid);
return -ENOMEM;
}
......@@ -254,7 +258,8 @@ cifs_readlink(struct dentry *direntry, char *pBuffer, int buflen)
strncpy(tmpbuffer, referrals, len-1);
}
}
if(referrals)
kfree(referrals);
kfree(tmp_path);
if(referrals) {
kfree(referrals);
......
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