diff options
Diffstat (limited to 'fs/overlayfs/dir.c')
-rw-r--r-- | fs/overlayfs/dir.c | 14 |
1 files changed, 12 insertions, 2 deletions
diff --git a/fs/overlayfs/dir.c b/fs/overlayfs/dir.c index 76e39aaaa038..3cc65e60df02 100644 --- a/fs/overlayfs/dir.c +++ b/fs/overlayfs/dir.c @@ -184,6 +184,11 @@ static void ovl_instantiate(struct dentry *dentry, struct inode *inode, d_instantiate(dentry, inode); } +static bool ovl_type_merge(struct dentry *dentry) +{ + return OVL_TYPE_MERGE(ovl_path_type(dentry)); +} + static int ovl_create_upper(struct dentry *dentry, struct inode *inode, struct kstat *stat, const char *link, struct dentry *hardlink) @@ -206,6 +211,11 @@ static int ovl_create_upper(struct dentry *dentry, struct inode *inode, if (err) goto out_dput; + if (ovl_type_merge(dentry->d_parent)) { + /* Setting opaque here is just an optimization, allow to fail */ + ovl_set_opaque(dentry, newdentry); + } + ovl_instantiate(dentry, inode, newdentry, !!hardlink); newdentry = NULL; out_dput: @@ -1006,7 +1016,7 @@ static int ovl_rename(struct inode *olddir, struct dentry *old, if (is_dir) { if (ovl_type_merge_or_lower(old)) err = ovl_set_redirect(old, samedir); - else if (!old_opaque && ovl_lower_positive(new)) + else if (!old_opaque && ovl_type_merge(new->d_parent)) err = ovl_set_opaque(old, olddentry); if (err) goto out_dput; @@ -1014,7 +1024,7 @@ static int ovl_rename(struct inode *olddir, struct dentry *old, if (!overwrite && new_is_dir) { if (ovl_type_merge_or_lower(new)) err = ovl_set_redirect(new, samedir); - else if (!new_opaque && ovl_lower_positive(old)) + else if (!new_opaque && ovl_type_merge(old->d_parent)) err = ovl_set_opaque(new, newdentry); if (err) goto out_dput; |