Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 47c78b7f authored by Jeff Layton's avatar Jeff Layton
Browse files

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: default avatarJeff Layton <jlayton@redhat.com>
Reviewed-and-Tested-by: default avatarSuresh Jayaraman <sjayaraman@suse.de>
parent d9d5d8df
Loading
Loading
Loading
Loading
+11 −6
Original line number Diff line number Diff line
@@ -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 */