diff options
author | Miklos Szeredi <mszeredi@redhat.com> | 2016-12-16 05:02:55 -0500 |
---|---|---|
committer | Miklos Szeredi <mszeredi@redhat.com> | 2016-12-16 05:02:55 -0500 |
commit | 370e55ace59c2d3ed8f0ca933155030b9652e04f (patch) | |
tree | 3cef98f251aee75f32615945ff012bc8bb22fc0a | |
parent | 38e813db61c3951ef76d071ca7d2f46c2e939b80 (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.c | 30 | ||||
-rw-r--r-- | fs/overlayfs/overlayfs.h | 3 |
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 | ||
764 | static 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 | |||
764 | static int ovl_rename(struct inode *olddir, struct dentry *old, | 771 | static 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" |