提交 47c78b7f 编写于 作者: J Jeff Layton

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: NJeff Layton <jlayton@redhat.com>
Reviewed-and-Tested-by: NSuresh Jayaraman <sjayaraman@suse.de>
上级 d9d5d8df
...@@ -268,17 +268,20 @@ int cifs_open(struct inode *inode, struct file *file) ...@@ -268,17 +268,20 @@ int cifs_open(struct inode *inode, struct file *file)
/* no need for special case handling of setting mode /* no need for special case handling of setting mode
on read only files needed here */ 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, pCifsFile = cifs_new_fileinfo(inode, netfid, file,
file->f_path.mnt, file->f_path.mnt,
oflags); oflags);
if (pCifsFile == NULL) { if (pCifsFile == NULL) {
CIFSSMBClose(xid, tcon, netfid); CIFSSMBClose(xid, tcon, netfid);
rc = -ENOMEM; rc = -ENOMEM;
goto out;
} }
rc = cifs_posix_open_inode_helper(inode, file,
pCifsInode, oplock, netfid);
goto out; goto out;
} else if ((rc == -EINVAL) || (rc == -EOPNOTSUPP)) { } else if ((rc == -EINVAL) || (rc == -EOPNOTSUPP)) {
if (tcon->ses->serverNOS) if (tcon->ses->serverNOS)
...@@ -359,6 +362,10 @@ int cifs_open(struct inode *inode, struct file *file) ...@@ -359,6 +362,10 @@ int cifs_open(struct inode *inode, struct file *file)
goto out; 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, pCifsFile = cifs_new_fileinfo(inode, netfid, file, file->f_path.mnt,
file->f_flags); file->f_flags);
if (pCifsFile == NULL) { if (pCifsFile == NULL) {
...@@ -366,8 +373,6 @@ int cifs_open(struct inode *inode, struct file *file) ...@@ -366,8 +373,6 @@ int cifs_open(struct inode *inode, struct file *file)
goto out; goto out;
} }
rc = cifs_open_inode_helper(inode, tcon, &oplock, buf, full_path, xid);
if (oplock & CIFS_CREATE_ACTION) { if (oplock & CIFS_CREATE_ACTION) {
/* time to set mode which we can not set earlier due to /* time to set mode which we can not set earlier due to
problems creating new read-only files */ problems creating new read-only files */
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册