From patchwork Tue Jun 1 14:54:52 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: [8/8] cifs: don't call cifs_new_fileinfo unless cifs_open succeeds Date: Tue, 01 Jun 2010 04:54:52 -0000 From: Jeff Layton X-Patchwork-Id: 54222 Message-Id: <1275404092-8400-9-git-send-email-jlayton@redhat.com> To: smfrench@gmail.com Cc: linux-cifs-client@lists.samba.org 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 and 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 --- fs/cifs/file.c | 17 +++++++++++------ 1 files changed, 11 insertions(+), 6 deletions(-) diff --git a/fs/cifs/file.c b/fs/cifs/file.c index 02a2df9..409e4f5 100644 --- a/fs/cifs/file.c +++ b/fs/cifs/file.c @@ -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 */