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->local_nls)
unload_nls(cifs_sb->local_nls);
if(cifs_sb)
if(cifs_sb) {
if(cifs_sb->local_nls)
unload_nls(cifs_sb->local_nls);
kfree(cifs_sb);
}
return rc;
}
......
......@@ -916,34 +916,34 @@ int CIFSSMBRenameOpenFile(const int xid,struct cifsTconInfo *pTcon,
int bytes_returned = 0;
int len_of_str;
cFYI(1, ("Rename to File by handle"));
rc = smb_init(SMB_COM_TRANSACTION2, 15, pTcon, (void **) &pSMB,
(void **) &pSMBr);
if (rc)
return rc;
pSMB->ParameterCount = 6;
pSMB->MaxSetupCount = 0;
pSMB->Reserved = 0;
pSMB->Flags = 0;
pSMB->Timeout = 0;
pSMB->Reserved2 = 0;
pSMB->ParameterOffset = offsetof(struct smb_com_transaction2_sfi_req,
Fid) - 4;
pSMB->DataOffset = pSMB->ParameterOffset + pSMB->ParameterCount;
cFYI(1, ("Rename to File by handle"));
rc = smb_init(SMB_COM_TRANSACTION2, 15, pTcon, (void **) &pSMB,
(void **) &pSMBr);
if (rc)
return rc;
pSMB->ParameterCount = 6;
pSMB->MaxSetupCount = 0;
pSMB->Reserved = 0;
pSMB->Flags = 0;
pSMB->Timeout = 0;
pSMB->Reserved2 = 0;
pSMB->ParameterOffset = offsetof(struct smb_com_transaction2_sfi_req,
Fid) - 4;
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;
pSMB->MaxParameterCount = cpu_to_le16(2);
pSMB->MaxDataCount = cpu_to_le16(1000); /* BB find max SMB PDU from sess */
pSMB->SetupCount = 1;
pSMB->Reserved3 = 0;
pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FILE_INFORMATION);
pSMB->ByteCount = 3 /* pad */ + pSMB->ParameterCount;
pSMB->ParameterCount = cpu_to_le16(pSMB->ParameterCount);
pSMB->TotalParameterCount = pSMB->ParameterCount;
pSMB->ParameterOffset = cpu_to_le16(pSMB->ParameterOffset);
pSMB->DataOffset = cpu_to_le16(pSMB->DataOffset);
pSMB->MaxParameterCount = cpu_to_le16(2);
pSMB->MaxDataCount = cpu_to_le16(1000); /* BB find max SMB PDU from sess */
pSMB->SetupCount = 1;
pSMB->Reserved3 = 0;
pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FILE_INFORMATION);
pSMB->ByteCount = 3 /* pad */ + pSMB->ParameterCount;
pSMB->ParameterCount = cpu_to_le16(pSMB->ParameterCount);
pSMB->TotalParameterCount = pSMB->ParameterCount;
pSMB->ParameterOffset = cpu_to_le16(pSMB->ParameterOffset);
pSMB->DataOffset = cpu_to_le16(pSMB->DataOffset);
/* construct random name ".cifs_tmp<inodenum><mid>" */
rename_info->overwrite = cpu_to_le32(1);
rename_info->root_fid = 0;
......@@ -968,11 +968,11 @@ int CIFSSMBRenameOpenFile(const int xid,struct cifsTconInfo *pTcon,
rc = SendReceive(xid, pTcon->ses, (struct smb_hdr *) pSMB,
(struct smb_hdr *) pSMBr, &bytes_returned, 0);
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)
cifs_buf_release(pSMB);
cifs_buf_release(pSMB);
/* Note: On -EAGAIN error only caller can retry on handle based calls
since file handle passed in no longer valid */
......
......@@ -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);
}
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"));
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);
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"));
......@@ -297,11 +298,11 @@ static int cifs_reopen_file(struct inode *inode, struct file *file)
else
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
and calling get_inode_info with returned buf (at least
helps non-Unix server case */
/* Also refresh inode by passing in file_info buf returned by SMBOpen
and calling get_inode_info with returned buf (at least
helps non-Unix server case */
buf = kmalloc(sizeof(FILE_ALL_INFO),GFP_KERNEL);
if(buf==0) {
up(&pCifsFile->fh_sem);
......@@ -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));
......
......@@ -204,10 +204,10 @@ cifs_get_inode_info(struct inode **pinode, const unsigned char *search_path,
strnlen(search_path, MAX_PATHCONF) + 1,
GFP_KERNEL);
if (tmp_path == NULL) {
if(buf)
kfree(buf);
FreeXid(xid);
return -ENOMEM;
if(buf)
kfree(buf);
FreeXid(xid);
return -ENOMEM;
}
strncpy(tmp_path, pTcon->treeName, MAX_TREE_SIZE);
......@@ -218,10 +218,10 @@ cifs_get_inode_info(struct inode **pinode, const unsigned char *search_path,
kfree(tmp_path);
/* BB fix up inode etc. */
} else if (rc) {
if(buf)
kfree(buf);
FreeXid(xid);
return rc;
if(buf)
kfree(buf);
FreeXid(xid);
return rc;
}
} else {
struct cifsInodeInfo *cifsInfo;
......@@ -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));
pfindData->AllocationSize = le64_to_cpu(pfindData->AllocationSize);
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);
......@@ -380,8 +380,8 @@ cifs_unlink(struct inode *inode, struct dentry *direntry)
__u16 netfid;
rc = CIFSSMBOpen(xid, pTcon, full_path, FILE_OPEN, DELETE,
CREATE_NOT_DIR | CREATE_DELETE_ON_CLOSE,
&netfid, &oplock, NULL, cifs_sb->local_nls);
CREATE_NOT_DIR | CREATE_DELETE_ON_CLOSE,
&netfid, &oplock, NULL, cifs_sb->local_nls);
if(rc==0) {
CIFSSMBRenameOpenFile(xid,pTcon,netfid,NULL,cifs_sb->local_nls);
CIFSSMBClose(xid, pTcon, netfid);
......
......@@ -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;
}
......@@ -251,10 +255,11 @@ cifs_readlink(struct dentry *direntry, char *pBuffer, int buflen)
cFYI(1,("num referral: %d",num_referrals));
if(referrals) {
cFYI(1,("referral string: %s ",referrals));
strncpy(tmpbuffer, referrals, len-1);
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