staging/lustre: Always return EEXIST on mkdir for existing names
authorOleg Drokin <green@linuxhacker.ru>
Sat, 20 Aug 2016 21:34:25 +0000 (17:34 -0400)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Sun, 21 Aug 2016 14:03:38 +0000 (16:03 +0200)
if the name already exists, but we don't have write permissions
in the parent, force talking to the MDS to determine what
more sensical error code to return.
This also happens to fix matlab and other such programs that
assume that EEXIST is the only valid error code for mkdir of
an existing directory.

Signed-off-by: Oleg Drokin <green@linuxhacker.ru>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/staging/lustre/lustre/llite/namei.c

index ee5a42e5e95df0fce89a45defcd6b61619737732..d13debbb08b2bc7c2d8e8b63dc8a782f2388abac 100644 (file)
@@ -606,8 +606,12 @@ static struct dentry *ll_lookup_nd(struct inode *parent, struct dentry *dentry,
        CDEBUG(D_VFSTRACE, "VFS Op:name=%pd, dir="DFID"(%p),flags=%u\n",
               dentry, PFID(ll_inode2fid(parent)), parent, flags);
 
-       /* Optimize away (CREATE && !OPEN). Let .create handle the race. */
-       if ((flags & LOOKUP_CREATE) && !(flags & LOOKUP_OPEN))
+       /* Optimize away (CREATE && !OPEN). Let .create handle the race.
+        * but only if we have write permissions there, otherwise we need
+        * to proceed with lookup. LU-4185
+        */
+       if ((flags & LOOKUP_CREATE) && !(flags & LOOKUP_OPEN) &&
+           (inode_permission(parent, MAY_WRITE | MAY_EXEC) == 0))
                return NULL;
 
        if (flags & (LOOKUP_PARENT|LOOKUP_OPEN|LOOKUP_CREATE))