if (tmpbuffer) { kfree(tmpbuffer); } if (full_path) { kfree(full_path); } 
kfree(tmpbuffer); kfree(full_path); 
cifs_readlink(struct dentry *direntry, char __user *pBuffer, int buflen){	struct inode *inode = direntry->d_inode;	int rc = -EACCES;	int xid;	int oplock = FALSE;	struct cifs_sb_info *cifs_sb;	struct cifsTconInfo *pTcon;	char *full_path = NULL;	char *tmp_path =  NULL;	char * tmpbuffer;	unsigned char * referrals = NULL;	int num_referrals = 0;	int len;	__u16 fid;	xid = GetXid();	cifs_sb = CIFS_SB(inode->i_sb);	pTcon = cifs_sb->tcon;/* BB would it be safe against deadlock to grab this sem       even though rename itself grabs the sem and calls lookup? *//*       down(&inode->i_sb->s_vfs_rename_sem);*/	full_path = build_path_from_dentry(direntry);/*       up(&inode->i_sb->s_vfs_rename_sem);*/	if(full_path == NULL) {		FreeXid(xid);		return -ENOMEM;	}	cFYI(1,	     ("Full path: %s inode = 0x%p pBuffer = 0x%p buflen = %d",	      full_path, inode, pBuffer, buflen));	if(buflen > PATH_MAX)		len = PATH_MAX;	else		len = buflen;	tmpbuffer = kmalloc(len,GFP_KERNEL);   	if(tmpbuffer == NULL) {		if (full_path)			kfree(full_path);		FreeXid(xid);		return -ENOMEM;	}/* BB add read reparse point symlink code and Unix extensions symlink code here BB */	if (cifs_sb->tcon->ses->capabilities & CAP_UNIX)		rc = CIFSSMBUnixQuerySymLink(xid, pTcon, full_path,				tmpbuffer,				len - 1,				cifs_sb->local_nls);	else {		rc = CIFSSMBOpen(xid, pTcon, full_path, FILE_OPEN, GENERIC_READ,				OPEN_REPARSE_POINT,&fid, &oplock, NULL, 				cifs_sb->local_nls, 				cifs_sb->mnt_cifs_flags & 					CIFS_MOUNT_MAP_SPECIAL_CHR);		if(!rc) {			rc = CIFSSMBQueryReparseLinkInfo(xid, pTcon, full_path,				tmpbuffer,				len - 1, 				fid,				cifs_sb->local_nls);			if(CIFSSMBClose(xid, pTcon, fid)) {				cFYI(1,("Error closing junction point (open for ioctl)"));			}			if(rc == -EIO) {				/* Query if DFS Junction */				tmp_path =					kmalloc(MAX_TREE_SIZE + MAX_PATHCONF + 1,						GFP_KERNEL);				if (tmp_path) {					strncpy(tmp_path, pTcon->treeName, MAX_TREE_SIZE);					strncat(tmp_path, full_path, MAX_PATHCONF);					rc = get_dfs_path(xid, pTcon->ses, tmp_path,						cifs_sb->local_nls,						&num_referrals, &referrals,						cifs_sb->mnt_cifs_flags &						    CIFS_MOUNT_MAP_SPECIAL_CHR);					cFYI(1,("Get DFS for %s rc = %d ",tmp_path, rc));					if((num_referrals == 0) && (rc == 0))						rc = -EACCES;					else {						cFYI(1,("num referral: %d",num_referrals));						if(referrals) {							cFYI(1,("referral string: %s ",referrals));							strncpy(tmpbuffer, referrals, len-1);                            						}					}					if(referrals)						kfree(referrals);					kfree(tmp_path);}				/* BB add code like else decode referrals then memcpy to				  tmpbuffer and free referrals string array BB */			}		}	}	/* BB Anything else to do to handle recursive links? */	/* BB Should we be using page ops here? */	/* BB null terminate returned string in pBuffer? BB */	if (rc == 0) {		rc = vfs_readlink(direntry, pBuffer, len, tmpbuffer);		cFYI(1,		     ("vfs_readlink called from cifs_readlink returned %d",		      rc));	}	if (tmpbuffer) {		kfree(tmpbuffer);	}	if (full_path) {		kfree(full_path);	}	FreeXid(xid);	return rc;}
4520	/local/tlutelli/issta_data/temp/c/2005_temp/2005/4520/f99d49adf527fa6f7a9c42257fa76bca6b8df1e3/link.c/clean/fs/cifs/link.c