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 Version 1.06
------------ ------------
Send NTCreateX with ATTR_POSIX if Linux/Unix extensions negotiated with server. 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, ...@@ -127,10 +127,11 @@ cifs_read_super(struct super_block *sb, void *data,
iput(inode); iput(inode);
out_mount_failed: out_mount_failed:
if(cifs_sb->local_nls) if(cifs_sb) {
unload_nls(cifs_sb->local_nls); if(cifs_sb->local_nls)
if(cifs_sb) unload_nls(cifs_sb->local_nls);
kfree(cifs_sb); kfree(cifs_sb);
}
return rc; return rc;
} }
......
...@@ -916,34 +916,34 @@ int CIFSSMBRenameOpenFile(const int xid,struct cifsTconInfo *pTcon, ...@@ -916,34 +916,34 @@ int CIFSSMBRenameOpenFile(const int xid,struct cifsTconInfo *pTcon,
int bytes_returned = 0; int bytes_returned = 0;
int len_of_str; int len_of_str;
cFYI(1, ("Rename to File by handle")); cFYI(1, ("Rename to File by handle"));
rc = smb_init(SMB_COM_TRANSACTION2, 15, pTcon, (void **) &pSMB, rc = smb_init(SMB_COM_TRANSACTION2, 15, pTcon, (void **) &pSMB,
(void **) &pSMBr); (void **) &pSMBr);
if (rc) if (rc)
return rc; return rc;
pSMB->ParameterCount = 6; pSMB->ParameterCount = 6;
pSMB->MaxSetupCount = 0; pSMB->MaxSetupCount = 0;
pSMB->Reserved = 0; pSMB->Reserved = 0;
pSMB->Flags = 0; pSMB->Flags = 0;
pSMB->Timeout = 0; pSMB->Timeout = 0;
pSMB->Reserved2 = 0; pSMB->Reserved2 = 0;
pSMB->ParameterOffset = offsetof(struct smb_com_transaction2_sfi_req, pSMB->ParameterOffset = offsetof(struct smb_com_transaction2_sfi_req,
Fid) - 4; Fid) - 4;
pSMB->DataOffset = pSMB->ParameterOffset + pSMB->ParameterCount; pSMB->DataOffset = pSMB->ParameterOffset + pSMB->ParameterCount;
data_offset = (char *) (&pSMB->hdr.Protocol) + pSMB->DataOffset; data_offset = (char *) (&pSMB->hdr.Protocol) + pSMB->DataOffset;
rename_info = (struct set_file_rename *) data_offset; rename_info = (struct set_file_rename *) data_offset;
pSMB->MaxParameterCount = cpu_to_le16(2); pSMB->MaxParameterCount = cpu_to_le16(2);
pSMB->MaxDataCount = cpu_to_le16(1000); /* BB find max SMB PDU from sess */ pSMB->MaxDataCount = cpu_to_le16(1000); /* BB find max SMB PDU from sess */
pSMB->SetupCount = 1; pSMB->SetupCount = 1;
pSMB->Reserved3 = 0; pSMB->Reserved3 = 0;
pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FILE_INFORMATION); pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FILE_INFORMATION);
pSMB->ByteCount = 3 /* pad */ + pSMB->ParameterCount; pSMB->ByteCount = 3 /* pad */ + pSMB->ParameterCount;
pSMB->ParameterCount = cpu_to_le16(pSMB->ParameterCount); pSMB->ParameterCount = cpu_to_le16(pSMB->ParameterCount);
pSMB->TotalParameterCount = pSMB->ParameterCount; pSMB->TotalParameterCount = pSMB->ParameterCount;
pSMB->ParameterOffset = cpu_to_le16(pSMB->ParameterOffset); pSMB->ParameterOffset = cpu_to_le16(pSMB->ParameterOffset);
pSMB->DataOffset = cpu_to_le16(pSMB->DataOffset); pSMB->DataOffset = cpu_to_le16(pSMB->DataOffset);
/* construct random name ".cifs_tmp<inodenum><mid>" */ /* construct random name ".cifs_tmp<inodenum><mid>" */
rename_info->overwrite = cpu_to_le32(1); rename_info->overwrite = cpu_to_le32(1);
rename_info->root_fid = 0; rename_info->root_fid = 0;
...@@ -968,11 +968,11 @@ int CIFSSMBRenameOpenFile(const int xid,struct cifsTconInfo *pTcon, ...@@ -968,11 +968,11 @@ int CIFSSMBRenameOpenFile(const int xid,struct cifsTconInfo *pTcon,
rc = SendReceive(xid, pTcon->ses, (struct smb_hdr *) pSMB, rc = SendReceive(xid, pTcon->ses, (struct smb_hdr *) pSMB,
(struct smb_hdr *) pSMBr, &bytes_returned, 0); (struct smb_hdr *) pSMBr, &bytes_returned, 0);
if (rc) { if (rc) {
cFYI(1,("Send error in Rename (by file handle) = %d", rc)); cFYI(1,("Send error in Rename (by file handle) = %d", rc));
} }
if (pSMB) if (pSMB)
cifs_buf_release(pSMB); cifs_buf_release(pSMB);
/* Note: On -EAGAIN error only caller can retry on handle based calls /* Note: On -EAGAIN error only caller can retry on handle based calls
since file handle passed in no longer valid */ since file handle passed in no longer valid */
......
...@@ -378,7 +378,7 @@ cifs_demultiplex_thread(struct TCP_Server_Info *server) ...@@ -378,7 +378,7 @@ cifs_demultiplex_thread(struct TCP_Server_Info *server)
ses->server = NULL; ses->server = NULL;
} }
} }
kfree(server); read_unlock(&GlobalSMBSeslock);
} else { } else {
spin_lock(&GlobalMid_Lock); spin_lock(&GlobalMid_Lock);
list_for_each(tmp, &server->pending_mid_q) { list_for_each(tmp, &server->pending_mid_q) {
...@@ -393,8 +393,22 @@ cifs_demultiplex_thread(struct TCP_Server_Info *server) ...@@ -393,8 +393,22 @@ cifs_demultiplex_thread(struct TCP_Server_Info *server)
} }
} }
spin_unlock(&GlobalMid_Lock); 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);
} }
read_unlock(&GlobalSMBSeslock);
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")); cFYI(1, ("About to exit from demultiplex thread"));
return 0; return 0;
...@@ -765,7 +779,8 @@ connect_to_dfs_path(int xid, struct cifsSesInfo *pSesInfo, ...@@ -765,7 +779,8 @@ connect_to_dfs_path(int xid, struct cifsSesInfo *pSesInfo,
the helper that resolves tcp names, mount to it, try to the helper that resolves tcp names, mount to it, try to
tcon to it unmount it if fail */ tcon to it unmount it if fail */
/* BB free memory for referrals string BB */ if(referrals)
kfree(referrals);
return rc; return rc;
} }
...@@ -955,6 +970,8 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb, ...@@ -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 (cifs_parse_mount_options(mount_data, devname, &volume_info)) {
if(volume_info.UNC) if(volume_info.UNC)
kfree(volume_info.UNC); kfree(volume_info.UNC);
if(volume_info.password)
kfree(volume_info.password);
FreeXid(xid); FreeXid(xid);
return -EINVAL; return -EINVAL;
} }
...@@ -966,6 +983,10 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb, ...@@ -966,6 +983,10 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
cifserror("No username specified "); cifserror("No username specified ");
/* In userspace mount helper we can get user name from alternate /* In userspace mount helper we can get user name from alternate
locations such as env variables and files on disk */ 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); FreeXid(xid);
return -EINVAL; return -EINVAL;
} }
...@@ -979,6 +1000,10 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb, ...@@ -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 */ { } else /* which servers DFS root would we conect to */ {
cERROR(1, cERROR(1,
("CIFS mount error: No UNC path (e.g. -o unc=//192.168.1.100/public) specified ")); ("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); FreeXid(xid);
return -EINVAL; return -EINVAL;
} }
...@@ -991,6 +1016,10 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb, ...@@ -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); cifs_sb->local_nls = load_nls(volume_info.iocharset);
if(cifs_sb->local_nls == NULL) { if(cifs_sb->local_nls == NULL) {
cERROR(1,("CIFS mount error: iocharset %s not found",volume_info.iocharset)); 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); FreeXid(xid);
return -ELIBACC; return -ELIBACC;
} }
...@@ -1014,6 +1043,8 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb, ...@@ -1014,6 +1043,8 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
sock_release(csocket); sock_release(csocket);
if(volume_info.UNC) if(volume_info.UNC)
kfree(volume_info.UNC); kfree(volume_info.UNC);
if(volume_info.password)
kfree(volume_info.password);
FreeXid(xid); FreeXid(xid);
return rc; return rc;
} }
...@@ -1024,6 +1055,8 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb, ...@@ -1024,6 +1055,8 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
sock_release(csocket); sock_release(csocket);
if(volume_info.UNC) if(volume_info.UNC)
kfree(volume_info.UNC); kfree(volume_info.UNC);
if(volume_info.password)
kfree(volume_info.password);
FreeXid(xid); FreeXid(xid);
return rc; return rc;
} else { } else {
...@@ -1044,6 +1077,8 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb, ...@@ -1044,6 +1077,8 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
if (existingCifsSes) { if (existingCifsSes) {
pSesInfo = existingCifsSes; pSesInfo = existingCifsSes;
cFYI(1, ("Existing smb sess found ")); cFYI(1, ("Existing smb sess found "));
if(volume_info.password)
kfree(volume_info.password);
} else if (!rc) { } else if (!rc) {
cFYI(1, ("Existing smb sess not found ")); cFYI(1, ("Existing smb sess not found "));
pSesInfo = sesInfoAlloc(); pSesInfo = sesInfoAlloc();
...@@ -1070,7 +1105,9 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb, ...@@ -1070,7 +1105,9 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
up(&pSesInfo->sesSem); up(&pSesInfo->sesSem);
if(!rc) if(!rc)
atomic_inc(&srvTcp->socketUseCount); atomic_inc(&srvTcp->socketUseCount);
} } else
if(volume_info.password)
kfree(volume_info.password);
} }
/* search for existing tcon to this server share */ /* search for existing tcon to this server share */
...@@ -2494,6 +2531,8 @@ CIFSTCon(unsigned int xid, struct cifsSesInfo *ses, ...@@ -2494,6 +2531,8 @@ CIFSTCon(unsigned int xid, struct cifsSesInfo *ses,
if (((long) bcc_ptr + (2 * length)) - if (((long) bcc_ptr + (2 * length)) -
(long) pByteArea(smb_buffer_response) <= (long) pByteArea(smb_buffer_response) <=
BCC(smb_buffer_response)) { BCC(smb_buffer_response)) {
if(tcon->nativeFileSystem)
kfree(tcon->nativeFileSystem);
tcon->nativeFileSystem = tcon->nativeFileSystem =
cifs_kcalloc(length + 2, GFP_KERNEL); cifs_kcalloc(length + 2, GFP_KERNEL);
cifs_strfromUCS_le(tcon->nativeFileSystem, cifs_strfromUCS_le(tcon->nativeFileSystem,
...@@ -2510,6 +2549,8 @@ CIFSTCon(unsigned int xid, struct cifsSesInfo *ses, ...@@ -2510,6 +2549,8 @@ CIFSTCon(unsigned int xid, struct cifsSesInfo *ses,
if (((long) bcc_ptr + length) - if (((long) bcc_ptr + length) -
(long) pByteArea(smb_buffer_response) <= (long) pByteArea(smb_buffer_response) <=
BCC(smb_buffer_response)) { BCC(smb_buffer_response)) {
if(tcon->nativeFileSystem)
kfree(tcon->nativeFileSystem);
tcon->nativeFileSystem = tcon->nativeFileSystem =
cifs_kcalloc(length + 1, GFP_KERNEL); cifs_kcalloc(length + 1, GFP_KERNEL);
strncpy(tcon->nativeFileSystem, bcc_ptr, strncpy(tcon->nativeFileSystem, bcc_ptr,
......
...@@ -150,11 +150,12 @@ cifs_open(struct inode *inode, struct file *file) ...@@ -150,11 +150,12 @@ cifs_open(struct inode *inode, struct file *file)
cFYI(1, ("cifs_open returned 0x%x ", rc)); cFYI(1, ("cifs_open returned 0x%x ", rc));
cFYI(1, ("oplock: %d ", oplock)); cFYI(1, ("oplock: %d ", oplock));
} else { } else {
if(file->private_data)
kfree(file->private_data);
file->private_data = file->private_data =
kmalloc(sizeof (struct cifsFileInfo), GFP_KERNEL); kmalloc(sizeof (struct cifsFileInfo), GFP_KERNEL);
if (file->private_data) { if (file->private_data) {
memset(file->private_data, 0, memset(file->private_data, 0, sizeof(struct cifsFileInfo));
sizeof (struct cifsFileInfo));
pCifsFile = (struct cifsFileInfo *) file->private_data; pCifsFile = (struct cifsFileInfo *) file->private_data;
pCifsFile->netfid = netfid; pCifsFile->netfid = netfid;
pCifsFile->pid = current->pid; pCifsFile->pid = current->pid;
...@@ -183,7 +184,7 @@ cifs_open(struct inode *inode, struct file *file) ...@@ -183,7 +184,7 @@ cifs_open(struct inode *inode, struct file *file)
struct timespec temp; struct timespec temp;
temp = cifs_NTtimeToUnix(le64_to_cpu(buf->LastWriteTime)); temp = cifs_NTtimeToUnix(le64_to_cpu(buf->LastWriteTime));
if(timespec_equal(&file->f_dentry->d_inode->i_mtime,&temp) && 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")); cFYI(1,("inode unchanged on server"));
} else { } else {
cFYI(1,("invalidating remote inode since open detected it changed")); cFYI(1,("invalidating remote inode since open detected it changed"));
...@@ -297,11 +298,11 @@ static int cifs_reopen_file(struct inode *inode, struct file *file) ...@@ -297,11 +298,11 @@ static int cifs_reopen_file(struct inode *inode, struct file *file)
else else
oplock = FALSE; oplock = FALSE;
/* BB pass O_SYNC flag through on file attributes .. BB */ /* BB pass O_SYNC flag through on file attributes .. BB */
/* Also refresh inode by passing in file_info buf returned by SMBOpen /* Also refresh inode by passing in file_info buf returned by SMBOpen
and calling get_inode_info with returned buf (at least and calling get_inode_info with returned buf (at least
helps non-Unix server case */ helps non-Unix server case */
buf = kmalloc(sizeof(FILE_ALL_INFO),GFP_KERNEL); buf = kmalloc(sizeof(FILE_ALL_INFO),GFP_KERNEL);
if(buf==0) { if(buf==0) {
up(&pCifsFile->fh_sem); up(&pCifsFile->fh_sem);
...@@ -1497,8 +1498,7 @@ cifs_readdir(struct file *file, void *direntry, filldir_t filldir) ...@@ -1497,8 +1498,7 @@ cifs_readdir(struct file *file, void *direntry, filldir_t filldir)
searchHandle = findParms.SearchHandle; searchHandle = findParms.SearchHandle;
if(file->private_data == NULL) if(file->private_data == NULL)
file->private_data = file->private_data =
kmalloc(sizeof(struct cifsFileInfo), kmalloc(sizeof(struct cifsFileInfo),GFP_KERNEL);
GFP_KERNEL);
if (file->private_data) { if (file->private_data) {
memset(file->private_data, 0, memset(file->private_data, 0,
sizeof (struct cifsFileInfo)); sizeof (struct cifsFileInfo));
......
...@@ -204,10 +204,10 @@ cifs_get_inode_info(struct inode **pinode, const unsigned char *search_path, ...@@ -204,10 +204,10 @@ cifs_get_inode_info(struct inode **pinode, const unsigned char *search_path,
strnlen(search_path, MAX_PATHCONF) + 1, strnlen(search_path, MAX_PATHCONF) + 1,
GFP_KERNEL); GFP_KERNEL);
if (tmp_path == NULL) { if (tmp_path == NULL) {
if(buf) if(buf)
kfree(buf); kfree(buf);
FreeXid(xid); FreeXid(xid);
return -ENOMEM; return -ENOMEM;
} }
strncpy(tmp_path, pTcon->treeName, MAX_TREE_SIZE); strncpy(tmp_path, pTcon->treeName, MAX_TREE_SIZE);
...@@ -218,10 +218,10 @@ cifs_get_inode_info(struct inode **pinode, const unsigned char *search_path, ...@@ -218,10 +218,10 @@ cifs_get_inode_info(struct inode **pinode, const unsigned char *search_path,
kfree(tmp_path); kfree(tmp_path);
/* BB fix up inode etc. */ /* BB fix up inode etc. */
} else if (rc) { } else if (rc) {
if(buf) if(buf)
kfree(buf); kfree(buf);
FreeXid(xid); FreeXid(xid);
return rc; return rc;
} }
} else { } else {
struct cifsInodeInfo *cifsInfo; struct cifsInodeInfo *cifsInfo;
...@@ -275,7 +275,7 @@ cifs_get_inode_info(struct inode **pinode, const unsigned char *search_path, ...@@ -275,7 +275,7 @@ cifs_get_inode_info(struct inode **pinode, const unsigned char *search_path,
i_size_write(inode,le64_to_cpu(pfindData->EndOfFile)); i_size_write(inode,le64_to_cpu(pfindData->EndOfFile));
pfindData->AllocationSize = le64_to_cpu(pfindData->AllocationSize); pfindData->AllocationSize = le64_to_cpu(pfindData->AllocationSize);
inode->i_blocks = inode->i_blocks =
(inode->i_blksize - 1 + pfindData->AllocationSize) >> inode->i_blkbits; (inode->i_blksize - 1 + pfindData->AllocationSize) >> inode->i_blkbits;
inode->i_nlink = le32_to_cpu(pfindData->NumberOfLinks); inode->i_nlink = le32_to_cpu(pfindData->NumberOfLinks);
...@@ -380,8 +380,8 @@ cifs_unlink(struct inode *inode, struct dentry *direntry) ...@@ -380,8 +380,8 @@ cifs_unlink(struct inode *inode, struct dentry *direntry)
__u16 netfid; __u16 netfid;
rc = CIFSSMBOpen(xid, pTcon, full_path, FILE_OPEN, DELETE, rc = CIFSSMBOpen(xid, pTcon, full_path, FILE_OPEN, DELETE,
CREATE_NOT_DIR | CREATE_DELETE_ON_CLOSE, CREATE_NOT_DIR | CREATE_DELETE_ON_CLOSE,
&netfid, &oplock, NULL, cifs_sb->local_nls); &netfid, &oplock, NULL, cifs_sb->local_nls);
if(rc==0) { if(rc==0) {
CIFSSMBRenameOpenFile(xid,pTcon,netfid,NULL,cifs_sb->local_nls); CIFSSMBRenameOpenFile(xid,pTcon,netfid,NULL,cifs_sb->local_nls);
CIFSSMBClose(xid, pTcon, netfid); CIFSSMBClose(xid, pTcon, netfid);
......
...@@ -96,6 +96,8 @@ cifs_follow_link(struct dentry *direntry, struct nameidata *nd) ...@@ -96,6 +96,8 @@ cifs_follow_link(struct dentry *direntry, struct nameidata *nd)
pTcon = cifs_sb->tcon; pTcon = cifs_sb->tcon;
target_path = kmalloc(PATH_MAX, GFP_KERNEL); target_path = kmalloc(PATH_MAX, GFP_KERNEL);
if(target_path == NULL) { if(target_path == NULL) {
if (full_path)
kfree(full_path);
FreeXid(xid); FreeXid(xid);
return -ENOMEM; return -ENOMEM;
} }
...@@ -212,6 +214,8 @@ cifs_readlink(struct dentry *direntry, char *pBuffer, int buflen) ...@@ -212,6 +214,8 @@ cifs_readlink(struct dentry *direntry, char *pBuffer, int buflen)
len = buflen; len = buflen;
tmpbuffer = kmalloc(len,GFP_KERNEL); tmpbuffer = kmalloc(len,GFP_KERNEL);
if(tmpbuffer == NULL) { if(tmpbuffer == NULL) {
if (full_path)
kfree(full_path);
FreeXid(xid); FreeXid(xid);
return -ENOMEM; return -ENOMEM;
} }
...@@ -251,10 +255,11 @@ cifs_readlink(struct dentry *direntry, char *pBuffer, int buflen) ...@@ -251,10 +255,11 @@ cifs_readlink(struct dentry *direntry, char *pBuffer, int buflen)
cFYI(1,("num referral: %d",num_referrals)); cFYI(1,("num referral: %d",num_referrals));
if(referrals) { if(referrals) {
cFYI(1,("referral string: %s ",referrals)); cFYI(1,("referral string: %s ",referrals));
strncpy(tmpbuffer, referrals, len-1); strncpy(tmpbuffer, referrals, len-1);
} }
} }
if(referrals)
kfree(referrals);
kfree(tmp_path); kfree(tmp_path);
if(referrals) { if(referrals) {
kfree(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