From: Al Viro Date: Thu, 11 Feb 2021 03:13:03 +0000 (-0500) Subject: cifs: have ->mkdir() handle race with another client sanely X-Git-Url: http://git.maquefel.me/?a=commitdiff_plain;h=3bcb39b086bf8d7c3cff013564f86162ec497d90;p=linux.git cifs: have ->mkdir() handle race with another client sanely if we have mkdir request reported successful *and* simulating lookup gets us a non-directory (which is possible if another client has managed to get rmdir and create in between), the sane action is not to mangle ->i_mode of non-directory inode to S_IFDIR | mode, it's "report success and return with dentry negative unhashed" - that way the next lookup will do the right thing. Signed-off-by: Al Viro --- diff --git a/fs/cifs/inode.c b/fs/cifs/inode.c index d46b36d52211a..80c487fcf10e5 100644 --- a/fs/cifs/inode.c +++ b/fs/cifs/inode.c @@ -1739,6 +1739,16 @@ cifs_mkdir_qinfo(struct inode *parent, struct dentry *dentry, umode_t mode, if (rc) return rc; + if (!S_ISDIR(inode->i_mode)) { + /* + * mkdir succeeded, but another client has managed to remove the + * sucker and replace it with non-directory. Return success, + * but don't leave the child in dcache. + */ + iput(inode); + d_drop(dentry); + return 0; + } /* * setting nlink not necessary except in cases where we failed to get it * from the server or was set bogus. Also, since this is a brand new @@ -1790,7 +1800,7 @@ cifs_mkdir_qinfo(struct inode *parent, struct dentry *dentry, umode_t mode, } } d_instantiate(dentry, inode); - return rc; + return 0; } static int