From 5cf5b477f0ca33f56a30c7ec00e61a6204da2efb Mon Sep 17 00:00:00 2001 From: Miklos Szeredi Date: Fri, 16 Dec 2016 11:02:57 +0100 Subject: [PATCH] ovl: opaque cleanup oe->opaque is set for a) whiteouts b) directories having the "trusted.overlay.opaque" xattr Case b can be simplified, since setting the xattr always implies setting oe->opaque. Also once set, the opaque flag is never cleared. Don't need to set opaque flag for non-directories. Signed-off-by: Miklos Szeredi --- fs/overlayfs/copy_up.c | 6 ------ fs/overlayfs/dir.c | 43 ++++++++++++++++++++-------------------- fs/overlayfs/overlayfs.h | 2 +- fs/overlayfs/util.c | 5 +++-- 4 files changed, 25 insertions(+), 31 deletions(-) diff --git a/fs/overlayfs/copy_up.c b/fs/overlayfs/copy_up.c index e191c631b17f..6c3aaf45e9cf 100644 --- a/fs/overlayfs/copy_up.c +++ b/fs/overlayfs/copy_up.c @@ -303,12 +303,6 @@ static int ovl_copy_up_locked(struct dentry *workdir, struct dentry *upperdir, ovl_dentry_update(dentry, newdentry); ovl_inode_update(d_inode(dentry), d_inode(newdentry)); newdentry = NULL; - - /* - * Non-directores become opaque when copied up. - */ - if (!S_ISDIR(stat->mode)) - ovl_dentry_set_opaque(dentry, true); out2: dput(upper); out1: diff --git a/fs/overlayfs/dir.c b/fs/overlayfs/dir.c index b84d61b353cd..76e39aaaa038 100644 --- a/fs/overlayfs/dir.c +++ b/fs/overlayfs/dir.c @@ -128,9 +128,15 @@ int ovl_create_real(struct inode *dir, struct dentry *newdentry, return err; } -static int ovl_set_opaque(struct dentry *upperdentry) +static int ovl_set_opaque(struct dentry *dentry, struct dentry *upperdentry) { - return ovl_do_setxattr(upperdentry, OVL_XATTR_OPAQUE, "y", 1, 0); + int err; + + err = ovl_do_setxattr(upperdentry, OVL_XATTR_OPAQUE, "y", 1, 0); + if (!err) + ovl_dentry_set_opaque(dentry); + + return err; } static int ovl_dir_getattr(struct vfsmount *mnt, struct dentry *dentry, @@ -274,7 +280,7 @@ static struct dentry *ovl_clear_empty(struct dentry *dentry, if (err) goto out_cleanup; - err = ovl_set_opaque(opaquedir); + err = ovl_set_opaque(dentry, opaquedir); if (err) goto out_cleanup; @@ -435,7 +441,7 @@ static int ovl_create_over_whiteout(struct dentry *dentry, struct inode *inode, } if (!hardlink && S_ISDIR(stat->mode)) { - err = ovl_set_opaque(newdentry); + err = ovl_set_opaque(dentry, newdentry); if (err) goto out_cleanup; @@ -996,29 +1002,22 @@ static int ovl_rename(struct inode *olddir, struct dentry *old, if (WARN_ON(olddentry->d_inode == newdentry->d_inode)) goto out_dput; + err = 0; if (is_dir) { - if (ovl_type_merge_or_lower(old)) { + if (ovl_type_merge_or_lower(old)) err = ovl_set_redirect(old, samedir); - if (err) - goto out_dput; - } else if (!old_opaque && ovl_lower_positive(new)) { - err = ovl_set_opaque(olddentry); - if (err) - goto out_dput; - ovl_dentry_set_opaque(old, true); - } + else if (!old_opaque && ovl_lower_positive(new)) + err = ovl_set_opaque(old, olddentry); + if (err) + goto out_dput; } if (!overwrite && new_is_dir) { - if (ovl_type_merge_or_lower(new)) { + if (ovl_type_merge_or_lower(new)) err = ovl_set_redirect(new, samedir); - if (err) - goto out_dput; - } else if (!new_opaque && ovl_lower_positive(old)) { - err = ovl_set_opaque(newdentry); - if (err) - goto out_dput; - ovl_dentry_set_opaque(new, true); - } + else if (!new_opaque && ovl_lower_positive(old)) + err = ovl_set_opaque(new, newdentry); + if (err) + goto out_dput; } err = ovl_do_rename(old_upperdir->d_inode, olddentry, diff --git a/fs/overlayfs/overlayfs.h b/fs/overlayfs/overlayfs.h index bdda37fa3f67..a83de5d5b8a0 100644 --- a/fs/overlayfs/overlayfs.h +++ b/fs/overlayfs/overlayfs.h @@ -156,7 +156,7 @@ struct ovl_dir_cache *ovl_dir_cache(struct dentry *dentry); void ovl_set_dir_cache(struct dentry *dentry, struct ovl_dir_cache *cache); bool ovl_dentry_is_opaque(struct dentry *dentry); bool ovl_dentry_is_whiteout(struct dentry *dentry); -void ovl_dentry_set_opaque(struct dentry *dentry, bool opaque); +void ovl_dentry_set_opaque(struct dentry *dentry); bool ovl_redirect_dir(struct super_block *sb); void ovl_clear_redirect_dir(struct super_block *sb); const char *ovl_dentry_get_redirect(struct dentry *dentry); diff --git a/fs/overlayfs/util.c b/fs/overlayfs/util.c index 260b215852a3..952286f4826c 100644 --- a/fs/overlayfs/util.c +++ b/fs/overlayfs/util.c @@ -170,10 +170,11 @@ bool ovl_dentry_is_whiteout(struct dentry *dentry) return !dentry->d_inode && ovl_dentry_is_opaque(dentry); } -void ovl_dentry_set_opaque(struct dentry *dentry, bool opaque) +void ovl_dentry_set_opaque(struct dentry *dentry) { struct ovl_entry *oe = dentry->d_fsdata; - oe->opaque = opaque; + + oe->opaque = true; } bool ovl_redirect_dir(struct super_block *sb) -- 2.45.2