ovl: rename: simplify handling of lower/merged directory
authorMiklos Szeredi <mszeredi@redhat.com>
Fri, 16 Dec 2016 10:02:55 +0000 (11:02 +0100)
committerMiklos Szeredi <mszeredi@redhat.com>
Fri, 16 Dec 2016 10:02:55 +0000 (11:02 +0100)
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>
fs/overlayfs/dir.c
fs/overlayfs/overlayfs.h

index 76b1edccbedd04d2b05af6c8e7c4dcc04ad283f4..69c3971a9992dcc75e0c7ece84188c0071221bfe 100644 (file)
@@ -761,13 +761,18 @@ static int ovl_rmdir(struct inode *dir, struct dentry *dentry)
        return ovl_do_remove(dentry, true);
 }
 
+static bool ovl_type_merge_or_lower(struct dentry *dentry)
+{
+       enum ovl_path_type type = ovl_path_type(dentry);
+
+       return OVL_TYPE_MERGE(type) || !OVL_TYPE_UPPER(type);
+}
+
 static int ovl_rename(struct inode *olddir, struct dentry *old,
                      struct inode *newdir, struct dentry *new,
                      unsigned int flags)
 {
        int err;
-       enum ovl_path_type old_type;
-       enum ovl_path_type new_type;
        struct dentry *old_upperdir;
        struct dentry *new_upperdir;
        struct dentry *olddentry;
@@ -778,7 +783,7 @@ static int ovl_rename(struct inode *olddir, struct dentry *old,
        bool cleanup_whiteout = false;
        bool overwrite = !(flags & RENAME_EXCHANGE);
        bool is_dir = d_is_dir(old);
-       bool new_is_dir = false;
+       bool new_is_dir = d_is_dir(new);
        struct dentry *opaquedir = NULL;
        const struct cred *old_cred = NULL;
 
@@ -789,22 +794,11 @@ static int ovl_rename(struct inode *olddir, struct dentry *old,
        flags &= ~RENAME_NOREPLACE;
 
        /* Don't copy up directory trees */
-       old_type = ovl_path_type(old);
        err = -EXDEV;
-       if (OVL_TYPE_MERGE_OR_LOWER(old_type) && is_dir)
+       if (is_dir && ovl_type_merge_or_lower(old))
+               goto out;
+       if (!overwrite && new_is_dir && ovl_type_merge_or_lower(new))
                goto out;
-
-       if (new->d_inode) {
-               if (d_is_dir(new))
-                       new_is_dir = true;
-
-               new_type = ovl_path_type(new);
-               err = -EXDEV;
-               if (!overwrite && OVL_TYPE_MERGE_OR_LOWER(new_type) && new_is_dir)
-                       goto out;
-       } else {
-               new_type = __OVL_PATH_UPPER;
-       }
 
        err = ovl_want_write(old);
        if (err)
@@ -828,7 +822,7 @@ static int ovl_rename(struct inode *olddir, struct dentry *old,
 
        old_cred = ovl_override_creds(old->d_sb);
 
-       if (overwrite && OVL_TYPE_MERGE_OR_LOWER(new_type) && new_is_dir) {
+       if (overwrite && new_is_dir && ovl_type_merge_or_lower(new)) {
                opaquedir = ovl_check_empty_and_clear(new);
                err = PTR_ERR(opaquedir);
                if (IS_ERR(opaquedir)) {
index f183d1db78bd8273971c079b368c962b634c331f..db28512165c55dbab6a2fd36be08680424ae9c93 100644 (file)
@@ -18,9 +18,6 @@ enum ovl_path_type {
 
 #define OVL_TYPE_UPPER(type)   ((type) & __OVL_PATH_UPPER)
 #define OVL_TYPE_MERGE(type)   ((type) & __OVL_PATH_MERGE)
-#define OVL_TYPE_MERGE_OR_LOWER(type) \
-       (OVL_TYPE_MERGE(type) || !OVL_TYPE_UPPER(type))
-
 
 #define OVL_XATTR_PREFIX XATTR_TRUSTED_PREFIX "overlay."
 #define OVL_XATTR_OPAQUE OVL_XATTR_PREFIX "opaque"