diff options
author | Miklos Szeredi <mszeredi@redhat.com> | 2016-12-16 05:02:57 -0500 |
---|---|---|
committer | Miklos Szeredi <mszeredi@redhat.com> | 2016-12-16 05:02:57 -0500 |
commit | 5cf5b477f0ca33f56a30c7ec00e61a6204da2efb (patch) | |
tree | e418f95e7847541a12dc96411d6929f89849ce53 | |
parent | c5bef3a72b9d8a2040d5e9f4bde03db7c86bbfce (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.c | 6 | ||||
-rw-r--r-- | fs/overlayfs/dir.c | 43 | ||||
-rw-r--r-- | fs/overlayfs/overlayfs.h | 2 | ||||
-rw-r--r-- | 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, | |||
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); | ||
312 | out2: | 306 | out2: |
313 | dput(upper); | 307 | dput(upper); |
314 | out1: | 308 | 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, | |||
128 | return err; | 128 | return err; |
129 | } | 129 | } |
130 | 130 | ||
131 | static int ovl_set_opaque(struct dentry *upperdentry) | 131 | static 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 | ||
136 | static int ovl_dir_getattr(struct vfsmount *mnt, struct dentry *dentry, | 142 | static 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); | |||
156 | void ovl_set_dir_cache(struct dentry *dentry, struct ovl_dir_cache *cache); | 156 | void ovl_set_dir_cache(struct dentry *dentry, struct ovl_dir_cache *cache); |
157 | bool ovl_dentry_is_opaque(struct dentry *dentry); | 157 | bool ovl_dentry_is_opaque(struct dentry *dentry); |
158 | bool ovl_dentry_is_whiteout(struct dentry *dentry); | 158 | bool ovl_dentry_is_whiteout(struct dentry *dentry); |
159 | void ovl_dentry_set_opaque(struct dentry *dentry, bool opaque); | 159 | void ovl_dentry_set_opaque(struct dentry *dentry); |
160 | bool ovl_redirect_dir(struct super_block *sb); | 160 | bool ovl_redirect_dir(struct super_block *sb); |
161 | void ovl_clear_redirect_dir(struct super_block *sb); | 161 | void ovl_clear_redirect_dir(struct super_block *sb); |
162 | const char *ovl_dentry_get_redirect(struct dentry *dentry); | 162 | 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) | |||
170 | return !dentry->d_inode && ovl_dentry_is_opaque(dentry); | 170 | return !dentry->d_inode && ovl_dentry_is_opaque(dentry); |
171 | } | 171 | } |
172 | 172 | ||
173 | void ovl_dentry_set_opaque(struct dentry *dentry, bool opaque) | 173 | void 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 | ||
179 | bool ovl_redirect_dir(struct super_block *sb) | 180 | bool ovl_redirect_dir(struct super_block *sb) |