Commit 3bcb39b0 authored by Al Viro's avatar Al Viro
Browse files

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: default avatarAl Viro <viro@zeniv.linux.org.uk>
parent 4ab5260d
Loading
Loading
Loading
Loading
+11 −1
Original line number Diff line number Diff line
@@ -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