fix O_EXCL handling for devices
authorAl Viro <viro@zeniv.linux.org.uk>
Mon, 30 Jul 2012 07:50:30 +0000 (11:50 +0400)
committerAl Viro <viro@zeniv.linux.org.uk>
Mon, 30 Jul 2012 07:50:30 +0000 (11:50 +0400)
O_EXCL without O_CREAT has different semantics; it's "fail if already opened",
not "fail if already exists".  commit 71574865 broke that...

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
fs/namei.c

index 618d3531cf9f7a9221e56e7fa9b6a27556c7d893..e133bf3bbb03c2ba4360a6bbb536f4b91c7e95f3 100644 (file)
@@ -2418,7 +2418,7 @@ static int atomic_open(struct nameidata *nd, struct dentry *dentry,
        if ((open_flag & O_CREAT) && !IS_POSIXACL(dir))
                mode &= ~current_umask();
 
-       if (open_flag & O_EXCL) {
+       if ((open_flag & (O_EXCL | O_CREAT)) == (O_EXCL | O_CREAT)) {
                open_flag &= ~O_TRUNC;
                *opened |= FILE_CREATED;
        }
@@ -2742,7 +2742,7 @@ retry_lookup:
        }
 
        error = -EEXIST;
-       if (open_flag & O_EXCL)
+       if ((open_flag & (O_EXCL | O_CREAT)) == (O_EXCL | O_CREAT))
                goto exit_dput;
 
        error = follow_managed(path, nd->flags);