ovl: opaque cleanup
authorMiklos Szeredi <mszeredi@redhat.com>
Fri, 16 Dec 2016 10:02:57 +0000 (11:02 +0100)
committerMiklos Szeredi <mszeredi@redhat.com>
Fri, 16 Dec 2016 10:02:57 +0000 (11:02 +0100)
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 <mszeredi@redhat.com>
fs/overlayfs/copy_up.c
fs/overlayfs/dir.c
fs/overlayfs/overlayfs.h
fs/overlayfs/util.c

index e191c63..6c3aaf4 100644 (file)
@@ -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:
index b84d61b..76e39aa 100644 (file)
@@ -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,
index bdda37f..a83de5d 100644 (file)
@@ -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);
index 260b215..952286f 100644 (file)
@@ -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)