diff options
author | Al Viro <viro@zeniv.linux.org.uk> | 2016-04-27 02:36:39 -0400 |
---|---|---|
committer | Al Viro <viro@zeniv.linux.org.uk> | 2016-05-02 19:51:12 -0400 |
commit | 55db2fd9361424a6a5815e7796bcf03b19df437c (patch) | |
tree | 35ec9e92b476a194f13a3fe9c5a592af74b9bd96 | |
parent | 9d0728e16e9269f368a6217b34166999c8ba2f3e (diff) |
atomic_open(): massage the create_error logics a bit
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
-rw-r--r-- | fs/namei.c | 43 |
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) |