aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--fs/cifsd/vfs.c28
1 files changed, 23 insertions, 5 deletions
diff --git a/fs/cifsd/vfs.c b/fs/cifsd/vfs.c
index b509c90d911f..bdc30a7b6d52 100644
--- a/fs/cifsd/vfs.c
+++ b/fs/cifsd/vfs.c
@@ -190,14 +190,32 @@ int ksmbd_vfs_mkdir(struct ksmbd_work *work, const char *name, umode_t mode)
mode |= S_IFDIR;
err = vfs_mkdir(&init_user_ns, d_inode(path.dentry), dentry, mode);
- if (!err) {
+ if (err)
+ goto out;
+ else if (d_unhashed(dentry)) {
+ struct dentry *d;
+
+ d = lookup_one_len(dentry->d_name.name,
+ dentry->d_parent,
+ dentry->d_name.len);
+ if (IS_ERR(d)) {
+ err = PTR_ERR(d);
+ goto out;
+ }
+ if (unlikely(d_is_negative(d))) {
+ dput(d);
+ err = -ENOENT;
+ goto out;
+ }
+
ksmbd_vfs_inherit_owner(work, d_inode(path.dentry),
- d_inode(dentry));
- } else {
- ksmbd_err("mkdir(%s): creation failed (err:%d)\n", name, err);
+ d_inode(d));
+ dput(d);
}
-
+out:
done_path_create(&path, dentry);
+ if (err)
+ ksmbd_err("mkdir(%s): creation failed (err:%d)\n", name, err);
return err;
}