diff --git a/fs/overlayfs/dir.c b/fs/overlayfs/dir.c index 72e95c9c244de06d66e6bf08426f8f2c3e5b7abc..8ee7b77effcdd61cde5b16a0e23d059772ae12fc 100644 --- a/fs/overlayfs/dir.c +++ b/fs/overlayfs/dir.c @@ -116,8 +116,7 @@ int ovl_cleanup_and_whiteout(struct dentry *workdir, struct inode *dir, goto out; } -static int ovl_mkdir_real(struct inode *dir, struct dentry **newdentry, - umode_t mode) +int ovl_mkdir_real(struct inode *dir, struct dentry **newdentry, umode_t mode) { int err; struct dentry *d, *dentry = *newdentry; diff --git a/fs/overlayfs/overlayfs.h b/fs/overlayfs/overlayfs.h index 9199e1665311775ae70926df017498216f23f80e..76e096ad2ef90786cd7731c2ecdc578fbf3f4947 100644 --- a/fs/overlayfs/overlayfs.h +++ b/fs/overlayfs/overlayfs.h @@ -411,6 +411,7 @@ struct ovl_cattr { #define OVL_CATTR(m) (&(struct ovl_cattr) { .mode = (m) }) +int ovl_mkdir_real(struct inode *dir, struct dentry **newdentry, umode_t mode); struct dentry *ovl_create_real(struct inode *dir, struct dentry *newdentry, struct ovl_cattr *attr); int ovl_cleanup(struct inode *dir, struct dentry *dentry); diff --git a/fs/overlayfs/super.c b/fs/overlayfs/super.c index 20c20f6210a5fd86dbbf03209b4a8a35668a79d3..6729999f4a66ce770252477fd3fc17de2b704168 100644 --- a/fs/overlayfs/super.c +++ b/fs/overlayfs/super.c @@ -654,10 +654,14 @@ static struct dentry *ovl_workdir_create(struct ovl_fs *ofs, goto retry; } - work = ovl_create_real(dir, work, OVL_CATTR(attr.ia_mode)); - err = PTR_ERR(work); - if (IS_ERR(work)) - goto out_err; + err = ovl_mkdir_real(dir, &work, attr.ia_mode); + if (err) + goto out_dput; + + /* Weird filesystem returning with hashed negative (kernfs)? */ + err = -EINVAL; + if (d_really_is_negative(work)) + goto out_dput; /* * Try to remove POSIX ACL xattrs from workdir. We are good if: