aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMiklos Szeredi <mszeredi@redhat.com>2016-12-16 05:02:57 -0500
committerMiklos Szeredi <mszeredi@redhat.com>2016-12-16 05:02:57 -0500
commit5cf5b477f0ca33f56a30c7ec00e61a6204da2efb (patch)
treee418f95e7847541a12dc96411d6929f89849ce53
parentc5bef3a72b9d8a2040d5e9f4bde03db7c86bbfce (diff)
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 <mszeredi@redhat.com>
-rw-r--r--fs/overlayfs/copy_up.c6
-rw-r--r--fs/overlayfs/dir.c43
-rw-r--r--fs/overlayfs/overlayfs.h2
-rw-r--r--fs/overlayfs/util.c5
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,
303 ovl_dentry_update(dentry, newdentry); 303 ovl_dentry_update(dentry, newdentry);
304 ovl_inode_update(d_inode(dentry), d_inode(newdentry)); 304 ovl_inode_update(d_inode(dentry), d_inode(newdentry));
305 newdentry = NULL; 305 newdentry = NULL;
306
307 /*
308 * Non-directores become opaque when copied up.
309 */
310 if (!S_ISDIR(stat->mode))
311 ovl_dentry_set_opaque(dentry, true);
312out2: 306out2:
313 dput(upper); 307 dput(upper);
314out1: 308out1:
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,
128 return err; 128 return err;
129} 129}
130 130
131static int ovl_set_opaque(struct dentry *upperdentry) 131static int ovl_set_opaque(struct dentry *dentry, struct dentry *upperdentry)
132{ 132{
133 return ovl_do_setxattr(upperdentry, OVL_XATTR_OPAQUE, "y", 1, 0); 133 int err;
134
135 err = ovl_do_setxattr(upperdentry, OVL_XATTR_OPAQUE, "y", 1, 0);
136 if (!err)
137 ovl_dentry_set_opaque(dentry);
138
139 return err;
134} 140}
135 141
136static int ovl_dir_getattr(struct vfsmount *mnt, struct dentry *dentry, 142static int ovl_dir_getattr(struct vfsmount *mnt, struct dentry *dentry,
@@ -274,7 +280,7 @@ static struct dentry *ovl_clear_empty(struct dentry *dentry,
274 if (err) 280 if (err)
275 goto out_cleanup; 281 goto out_cleanup;
276 282
277 err = ovl_set_opaque(opaquedir); 283 err = ovl_set_opaque(dentry, opaquedir);
278 if (err) 284 if (err)
279 goto out_cleanup; 285 goto out_cleanup;
280 286
@@ -435,7 +441,7 @@ static int ovl_create_over_whiteout(struct dentry *dentry, struct inode *inode,
435 } 441 }
436 442
437 if (!hardlink && S_ISDIR(stat->mode)) { 443 if (!hardlink && S_ISDIR(stat->mode)) {
438 err = ovl_set_opaque(newdentry); 444 err = ovl_set_opaque(dentry, newdentry);
439 if (err) 445 if (err)
440 goto out_cleanup; 446 goto out_cleanup;
441 447
@@ -996,29 +1002,22 @@ static int ovl_rename(struct inode *olddir, struct dentry *old,
996 if (WARN_ON(olddentry->d_inode == newdentry->d_inode)) 1002 if (WARN_ON(olddentry->d_inode == newdentry->d_inode))
997 goto out_dput; 1003 goto out_dput;
998 1004
1005 err = 0;
999 if (is_dir) { 1006 if (is_dir) {
1000 if (ovl_type_merge_or_lower(old)) { 1007 if (ovl_type_merge_or_lower(old))
1001 err = ovl_set_redirect(old, samedir); 1008 err = ovl_set_redirect(old, samedir);
1002 if (err) 1009 else if (!old_opaque && ovl_lower_positive(new))
1003 goto out_dput; 1010 err = ovl_set_opaque(old, olddentry);
1004 } else if (!old_opaque && ovl_lower_positive(new)) { 1011 if (err)
1005 err = ovl_set_opaque(olddentry); 1012 goto out_dput;
1006 if (err)
1007 goto out_dput;
1008 ovl_dentry_set_opaque(old, true);
1009 }
1010 } 1013 }
1011 if (!overwrite && new_is_dir) { 1014 if (!overwrite && new_is_dir) {
1012 if (ovl_type_merge_or_lower(new)) { 1015 if (ovl_type_merge_or_lower(new))
1013 err = ovl_set_redirect(new, samedir); 1016 err = ovl_set_redirect(new, samedir);
1014 if (err) 1017 else if (!new_opaque && ovl_lower_positive(old))
1015 goto out_dput; 1018 err = ovl_set_opaque(new, newdentry);
1016 } else if (!new_opaque && ovl_lower_positive(old)) { 1019 if (err)
1017 err = ovl_set_opaque(newdentry); 1020 goto out_dput;
1018 if (err)
1019 goto out_dput;
1020 ovl_dentry_set_opaque(new, true);
1021 }
1022 } 1021 }
1023 1022
1024 err = ovl_do_rename(old_upperdir->d_inode, olddentry, 1023 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);
156void ovl_set_dir_cache(struct dentry *dentry, struct ovl_dir_cache *cache); 156void ovl_set_dir_cache(struct dentry *dentry, struct ovl_dir_cache *cache);
157bool ovl_dentry_is_opaque(struct dentry *dentry); 157bool ovl_dentry_is_opaque(struct dentry *dentry);
158bool ovl_dentry_is_whiteout(struct dentry *dentry); 158bool ovl_dentry_is_whiteout(struct dentry *dentry);
159void ovl_dentry_set_opaque(struct dentry *dentry, bool opaque); 159void ovl_dentry_set_opaque(struct dentry *dentry);
160bool ovl_redirect_dir(struct super_block *sb); 160bool ovl_redirect_dir(struct super_block *sb);
161void ovl_clear_redirect_dir(struct super_block *sb); 161void ovl_clear_redirect_dir(struct super_block *sb);
162const char *ovl_dentry_get_redirect(struct dentry *dentry); 162const 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)
170 return !dentry->d_inode && ovl_dentry_is_opaque(dentry); 170 return !dentry->d_inode && ovl_dentry_is_opaque(dentry);
171} 171}
172 172
173void ovl_dentry_set_opaque(struct dentry *dentry, bool opaque) 173void ovl_dentry_set_opaque(struct dentry *dentry)
174{ 174{
175 struct ovl_entry *oe = dentry->d_fsdata; 175 struct ovl_entry *oe = dentry->d_fsdata;
176 oe->opaque = opaque; 176
177 oe->opaque = true;
177} 178}
178 179
179bool ovl_redirect_dir(struct super_block *sb) 180bool ovl_redirect_dir(struct super_block *sb)