cifs: don't call cifs_new_fileinfo unless cifs_open succeeds
It's currently possible for cifs_open to fail after it has already called cifs_new_fileinfo. In that situation, the new fileinfo will be leaked as the caller doesn't call fput. That in turn leads to a busy inodes after umount problem since the fileinfo holds an extra inode reference now. Shuffle cifs_open around a bit so that it only calls cifs_new_fileinfo if it's going to succeed. Signed-off-by: Jeff Layton <jlayton@redhat.com> Reviewed-and-Tested-by: Suresh Jayaraman <sjayaraman@suse.de>
This commit is contained in:
		
							parent
							
								
									d9d5d8df95
								
							
						
					
					
						commit
						47c78b7f40
					
				@ -268,17 +268,20 @@ int cifs_open(struct inode *inode, struct file *file)
 | 
			
		||||
			/* no need for special case handling of setting mode
 | 
			
		||||
			   on read only files needed here */
 | 
			
		||||
 | 
			
		||||
			rc = cifs_posix_open_inode_helper(inode, file,
 | 
			
		||||
					pCifsInode, oplock, netfid);
 | 
			
		||||
			if (rc != 0) {
 | 
			
		||||
				CIFSSMBClose(xid, tcon, netfid);
 | 
			
		||||
				goto out;
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			pCifsFile = cifs_new_fileinfo(inode, netfid, file,
 | 
			
		||||
							file->f_path.mnt,
 | 
			
		||||
							oflags);
 | 
			
		||||
			if (pCifsFile == NULL) {
 | 
			
		||||
				CIFSSMBClose(xid, tcon, netfid);
 | 
			
		||||
				rc = -ENOMEM;
 | 
			
		||||
				goto out;
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			rc = cifs_posix_open_inode_helper(inode, file,
 | 
			
		||||
					pCifsInode, oplock, netfid);
 | 
			
		||||
			goto out;
 | 
			
		||||
		} else if ((rc == -EINVAL) || (rc == -EOPNOTSUPP)) {
 | 
			
		||||
			if (tcon->ses->serverNOS)
 | 
			
		||||
@ -359,6 +362,10 @@ int cifs_open(struct inode *inode, struct file *file)
 | 
			
		||||
		goto out;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	rc = cifs_open_inode_helper(inode, tcon, &oplock, buf, full_path, xid);
 | 
			
		||||
	if (rc != 0)
 | 
			
		||||
		goto out;
 | 
			
		||||
 | 
			
		||||
	pCifsFile = cifs_new_fileinfo(inode, netfid, file, file->f_path.mnt,
 | 
			
		||||
					file->f_flags);
 | 
			
		||||
	if (pCifsFile == NULL) {
 | 
			
		||||
@ -366,8 +373,6 @@ int cifs_open(struct inode *inode, struct file *file)
 | 
			
		||||
		goto out;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	rc = cifs_open_inode_helper(inode, tcon, &oplock, buf, full_path, xid);
 | 
			
		||||
 | 
			
		||||
	if (oplock & CIFS_CREATE_ACTION) {
 | 
			
		||||
		/* time to set mode which we can not set earlier due to
 | 
			
		||||
		   problems creating new read-only files */
 | 
			
		||||
 | 
			
		||||
		Loading…
	
		Reference in New Issue
	
	Block a user