aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMiklos Szeredi <mszeredi@redhat.com>2016-12-16 05:02:55 -0500
committerMiklos Szeredi <mszeredi@redhat.com>2016-12-16 05:02:55 -0500
commit370e55ace59c2d3ed8f0ca933155030b9652e04f (patch)
tree3cef98f251aee75f32615945ff012bc8bb22fc0a
parent38e813db61c3951ef76d071ca7d2f46c2e939b80 (diff)
ovl: rename: simplify handling of lower/merged directory
d_is_dir() is safe to call on a negative dentry. Use this fact to simplify handling of the lower or merged directories. Signed-off-by: Miklos Szeredi <mszeredi@redhat.com>
-rw-r--r--fs/overlayfs/dir.c30
-rw-r--r--fs/overlayfs/overlayfs.h3
2 files changed, 12 insertions, 21 deletions
diff --git a/fs/overlayfs/dir.c b/fs/overlayfs/dir.c
index 76b1edccbedd..69c3971a9992 100644
--- a/fs/overlayfs/dir.c
+++ b/fs/overlayfs/dir.c
@@ -761,13 +761,18 @@ static int ovl_rmdir(struct inode *dir, struct dentry *dentry)
761 return ovl_do_remove(dentry, true); 761 return ovl_do_remove(dentry, true);
762} 762}
763 763
764static bool ovl_type_merge_or_lower(struct dentry *dentry)
765{
766 enum ovl_path_type type = ovl_path_type(dentry);
767
768 return OVL_TYPE_MERGE(type) || !OVL_TYPE_UPPER(type);
769}
770
764static int ovl_rename(struct inode *olddir, struct dentry *old, 771static int ovl_rename(struct inode *olddir, struct dentry *old,
765 struct inode *newdir, struct dentry *new, 772 struct inode *newdir, struct dentry *new,
766 unsigned int flags) 773 unsigned int flags)
767{ 774{
768 int err; 775 int err;
769 enum ovl_path_type old_type;
770 enum ovl_path_type new_type;
771 struct dentry *old_upperdir; 776 struct dentry *old_upperdir;
772 struct dentry *new_upperdir; 777 struct dentry *new_upperdir;
773 struct dentry *olddentry; 778 struct dentry *olddentry;
@@ -778,7 +783,7 @@ static int ovl_rename(struct inode *olddir, struct dentry *old,
778 bool cleanup_whiteout = false; 783 bool cleanup_whiteout = false;
779 bool overwrite = !(flags & RENAME_EXCHANGE); 784 bool overwrite = !(flags & RENAME_EXCHANGE);
780 bool is_dir = d_is_dir(old); 785 bool is_dir = d_is_dir(old);
781 bool new_is_dir = false; 786 bool new_is_dir = d_is_dir(new);
782 struct dentry *opaquedir = NULL; 787 struct dentry *opaquedir = NULL;
783 const struct cred *old_cred = NULL; 788 const struct cred *old_cred = NULL;
784 789
@@ -789,22 +794,11 @@ static int ovl_rename(struct inode *olddir, struct dentry *old,
789 flags &= ~RENAME_NOREPLACE; 794 flags &= ~RENAME_NOREPLACE;
790 795
791 /* Don't copy up directory trees */ 796 /* Don't copy up directory trees */
792 old_type = ovl_path_type(old);
793 err = -EXDEV; 797 err = -EXDEV;
794 if (OVL_TYPE_MERGE_OR_LOWER(old_type) && is_dir) 798 if (is_dir && ovl_type_merge_or_lower(old))
799 goto out;
800 if (!overwrite && new_is_dir && ovl_type_merge_or_lower(new))
795 goto out; 801 goto out;
796
797 if (new->d_inode) {
798 if (d_is_dir(new))
799 new_is_dir = true;
800
801 new_type = ovl_path_type(new);
802 err = -EXDEV;
803 if (!overwrite && OVL_TYPE_MERGE_OR_LOWER(new_type) && new_is_dir)
804 goto out;
805 } else {
806 new_type = __OVL_PATH_UPPER;
807 }
808 802
809 err = ovl_want_write(old); 803 err = ovl_want_write(old);
810 if (err) 804 if (err)
@@ -828,7 +822,7 @@ static int ovl_rename(struct inode *olddir, struct dentry *old,
828 822
829 old_cred = ovl_override_creds(old->d_sb); 823 old_cred = ovl_override_creds(old->d_sb);
830 824
831 if (overwrite && OVL_TYPE_MERGE_OR_LOWER(new_type) && new_is_dir) { 825 if (overwrite && new_is_dir && ovl_type_merge_or_lower(new)) {
832 opaquedir = ovl_check_empty_and_clear(new); 826 opaquedir = ovl_check_empty_and_clear(new);
833 err = PTR_ERR(opaquedir); 827 err = PTR_ERR(opaquedir);
834 if (IS_ERR(opaquedir)) { 828 if (IS_ERR(opaquedir)) {
diff --git a/fs/overlayfs/overlayfs.h b/fs/overlayfs/overlayfs.h
index f183d1db78bd..db28512165c5 100644
--- a/fs/overlayfs/overlayfs.h
+++ b/fs/overlayfs/overlayfs.h
@@ -18,9 +18,6 @@ enum ovl_path_type {
18 18
19#define OVL_TYPE_UPPER(type) ((type) & __OVL_PATH_UPPER) 19#define OVL_TYPE_UPPER(type) ((type) & __OVL_PATH_UPPER)
20#define OVL_TYPE_MERGE(type) ((type) & __OVL_PATH_MERGE) 20#define OVL_TYPE_MERGE(type) ((type) & __OVL_PATH_MERGE)
21#define OVL_TYPE_MERGE_OR_LOWER(type) \
22 (OVL_TYPE_MERGE(type) || !OVL_TYPE_UPPER(type))
23
24 21
25#define OVL_XATTR_PREFIX XATTR_TRUSTED_PREFIX "overlay." 22#define OVL_XATTR_PREFIX XATTR_TRUSTED_PREFIX "overlay."
26#define OVL_XATTR_OPAQUE OVL_XATTR_PREFIX "opaque" 23#define OVL_XATTR_OPAQUE OVL_XATTR_PREFIX "opaque"