static int ovl_mkdir_real(struct inode *dir, struct dentry **newdentry, umode_t mode) { int err; struct dentry *d, *dentry = *newdentry; err = ovl_do_mkdir(dir, dentry, mode); if (err) return err; if (likely(!d_unhashed(dentry))) return 0; /* * vfs_mkdir() may succeed and leave the dentry passed * to it unhashed and negative. If that happens, try to * lookup a new hashed and positive dentry. */ d = lookup_one_len(dentry->d_name.name, dentry->d_parent, dentry->d_name.len); if (IS_ERR(d)) { pr_warn("overlayfs: failed lookup after mkdir (%pd2, err=%i).\n", dentry, err); return PTR_ERR(d); } dput(dentry); *newdentry = d; return 0; }
int ovl_create_real(struct inode *dir, struct dentry *newdentry, struct kstat *stat, const char *link, struct dentry *hardlink, bool debug) { int err; if (newdentry->d_inode) return -ESTALE; if (hardlink) { err = ovl_do_link(hardlink, dir, newdentry, debug); } else { switch (stat->mode & S_IFMT) { case S_IFREG: err = ovl_do_create(dir, newdentry, stat->mode, debug); break; case S_IFDIR: err = ovl_do_mkdir(dir, newdentry, stat->mode, debug); break; case S_IFCHR: case S_IFBLK: case S_IFIFO: case S_IFSOCK: err = ovl_do_mknod(dir, newdentry, stat->mode, stat->rdev, debug); break; case S_IFLNK: err = ovl_do_symlink(dir, newdentry, link, debug); break; default: err = -EPERM; } } if (!err && WARN_ON(!newdentry->d_inode)) { /* * Not quite sure if non-instantiated dentry is legal or not. * VFS doesn't seem to care so check and warn here. */ err = -ENOENT; } return err; }