summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAl Viro <viro@zeniv.linux.org.uk>2016-04-27 08:36:39 +0200
committerAl Viro <viro@zeniv.linux.org.uk>2016-05-03 01:51:12 +0200
commit55db2fd9361424a6a5815e7796bcf03b19df437c (patch)
tree35ec9e92b476a194f13a3fe9c5a592af74b9bd96
parentatomic_open(): consolidate "overridden ENOENT" in open-yourself cases (diff)
downloadlinux-55db2fd9361424a6a5815e7796bcf03b19df437c.tar.xz
linux-55db2fd9361424a6a5815e7796bcf03b19df437c.zip
atomic_open(): massage the create_error logics a bit
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
-rw-r--r--fs/namei.c43
1 files changed, 20 insertions, 23 deletions
diff --git a/fs/namei.c b/fs/namei.c
index 36520fc23746..ed48178ada19 100644
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -2855,33 +2855,30 @@ static int atomic_open(struct nameidata *nd, struct dentry *dentry,
* Another problem is returing the "right" error value (e.g. for an
* O_EXCL open we want to return EEXIST not EROFS).
*/
- if (((open_flag & (O_CREAT | O_TRUNC)) ||
- (open_flag & O_ACCMODE) != O_RDONLY) && unlikely(!got_write)) {
- if (!(open_flag & O_CREAT)) {
- /*
- * No O_CREATE -> atomicity not a requirement -> fall
- * back to lookup + open
- */
- goto no_open;
- } else if (open_flag & (O_EXCL | O_TRUNC)) {
- /* Fall back and fail with the right error */
- create_error = -EROFS;
- goto no_open;
- } else {
- /* No side effects, safe to clear O_CREAT */
- create_error = -EROFS;
- open_flag &= ~O_CREAT;
- }
- }
-
if (open_flag & O_CREAT) {
- error = may_o_create(&nd->path, dentry, mode);
- if (error) {
- create_error = error;
- if (open_flag & O_EXCL)
+ if (unlikely(!got_write)) {
+ create_error = -EROFS;
+ if (open_flag & (O_EXCL | O_TRUNC)) {
+ /* Fall back and fail with the right error */
goto no_open;
+ }
+ /* No side effects, safe to clear O_CREAT */
open_flag &= ~O_CREAT;
+ } else {
+ create_error = may_o_create(&nd->path, dentry, mode);
+ if (create_error) {
+ if (open_flag & O_EXCL)
+ goto no_open;
+ open_flag &= ~O_CREAT;
+ }
}
+ } else if ((open_flag & (O_TRUNC|O_WRONLY|O_RDWR)) &&
+ unlikely(!got_write)) {
+ /*
+ * No O_CREATE -> atomicity not a requirement -> fall
+ * back to lookup + open
+ */
+ goto no_open;
}
if (nd->flags & LOOKUP_DIRECTORY)