Commit d9a9f484 authored by Al Viro's avatar Al Viro

cifs_atomic_open(): fix double-put on late allocation failure

several iterations of ->atomic_open() calling conventions ago, we
used to need fput() if ->atomic_open() failed at some point after
successful finish_open().  Now (since 2016) it's not needed -
struct file carries enough state to make fput() work regardless
of the point in struct file lifecycle and discarding it on
failure exits in open() got unified.  Unfortunately, I'd missed
the fact that we had an instance of ->atomic_open() (cifs one)
that used to need that fput(), as well as the stale comment in
finish_open() demanding such late failure handling.  Trivially
fixed...

Fixes: fe9ec829 "do_last(): take fput() on error after opening to out:"
Cc: stable@kernel.org # v4.7+
Signed-off-by: default avatarAl Viro <viro@zeniv.linux.org.uk>
parent 21039132
...@@ -850,3 +850,11 @@ business doing so. ...@@ -850,3 +850,11 @@ business doing so.
d_alloc_pseudo() is internal-only; uses outside of alloc_file_pseudo() are d_alloc_pseudo() is internal-only; uses outside of alloc_file_pseudo() are
very suspect (and won't work in modules). Such uses are very likely to very suspect (and won't work in modules). Such uses are very likely to
be misspelled d_alloc_anon(). be misspelled d_alloc_anon().
---
**mandatory**
[should've been added in 2016] stale comment in finish_open() nonwithstanding,
failure exits in ->atomic_open() instances should *NOT* fput() the file,
no matter what. Everything is handled by the caller.
...@@ -555,7 +555,6 @@ cifs_atomic_open(struct inode *inode, struct dentry *direntry, ...@@ -555,7 +555,6 @@ cifs_atomic_open(struct inode *inode, struct dentry *direntry,
if (server->ops->close) if (server->ops->close)
server->ops->close(xid, tcon, &fid); server->ops->close(xid, tcon, &fid);
cifs_del_pending_open(&open); cifs_del_pending_open(&open);
fput(file);
rc = -ENOMEM; rc = -ENOMEM;
} }
......
...@@ -860,9 +860,6 @@ static int do_dentry_open(struct file *f, ...@@ -860,9 +860,6 @@ static int do_dentry_open(struct file *f,
* the return value of d_splice_alias(), then the caller needs to perform dput() * the return value of d_splice_alias(), then the caller needs to perform dput()
* on it after finish_open(). * on it after finish_open().
* *
* On successful return @file is a fully instantiated open file. After this, if
* an error occurs in ->atomic_open(), it needs to clean up with fput().
*
* Returns zero on success or -errno if the open failed. * Returns zero on success or -errno if the open failed.
*/ */
int finish_open(struct file *file, struct dentry *dentry, int finish_open(struct file *file, struct dentry *dentry,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment