Merge branch 'work.mount' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs
[linux-2.6-microblaze.git] / fs / overlayfs / super.c
index 22ee2a9..fd5ea4f 100644 (file)
@@ -70,20 +70,20 @@ static int ovl_check_append_only(struct inode *inode, int flag)
 
 static struct dentry *ovl_d_real(struct dentry *dentry,
                                 const struct inode *inode,
-                                unsigned int open_flags)
+                                unsigned int open_flags, unsigned int flags)
 {
        struct dentry *real;
        int err;
 
+       if (flags & D_REAL_UPPER)
+               return ovl_dentry_upper(dentry);
+
        if (!d_is_reg(dentry)) {
                if (!inode || inode == d_inode(dentry))
                        return dentry;
                goto bug;
        }
 
-       if (d_is_negative(dentry))
-               return dentry;
-
        if (open_flags) {
                err = ovl_open_maybe_copy_up(dentry, open_flags);
                if (err)
@@ -105,7 +105,7 @@ static struct dentry *ovl_d_real(struct dentry *dentry,
                goto bug;
 
        /* Handle recursion */
-       real = d_real(real, inode, open_flags);
+       real = d_real(real, inode, open_flags, 0);
 
        if (!inode || inode == d_inode(real))
                return real;
@@ -198,6 +198,7 @@ static void ovl_destroy_inode(struct inode *inode)
 
        dput(oi->__upperdentry);
        kfree(oi->redirect);
+       ovl_dir_cache_free(inode);
        mutex_destroy(&oi->lock);
 
        call_rcu(&inode->i_rcu, ovl_i_callback);
@@ -692,7 +693,7 @@ ovl_posix_acl_xattr_get(const struct xattr_handler *handler,
                        struct dentry *dentry, struct inode *inode,
                        const char *name, void *buffer, size_t size)
 {
-       return ovl_xattr_get(dentry, handler->name, buffer, size);
+       return ovl_xattr_get(dentry, inode, handler->name, buffer, size);
 }
 
 static int __maybe_unused
@@ -742,7 +743,7 @@ ovl_posix_acl_xattr_set(const struct xattr_handler *handler,
                        return err;
        }
 
-       err = ovl_xattr_set(dentry, handler->name, value, size, flags);
+       err = ovl_xattr_set(dentry, inode, handler->name, value, size, flags);
        if (!err)
                ovl_copyattr(ovl_inode_real(inode), inode);
 
@@ -772,7 +773,7 @@ static int ovl_other_xattr_get(const struct xattr_handler *handler,
                               struct dentry *dentry, struct inode *inode,
                               const char *name, void *buffer, size_t size)
 {
-       return ovl_xattr_get(dentry, name, buffer, size);
+       return ovl_xattr_get(dentry, inode, name, buffer, size);
 }
 
 static int ovl_other_xattr_set(const struct xattr_handler *handler,
@@ -780,7 +781,7 @@ static int ovl_other_xattr_set(const struct xattr_handler *handler,
                               const char *name, const void *value,
                               size_t size, int flags)
 {
-       return ovl_xattr_set(dentry, name, value, size, flags);
+       return ovl_xattr_set(dentry, inode, name, value, size, flags);
 }
 
 static const struct xattr_handler __maybe_unused
@@ -1058,10 +1059,6 @@ static int ovl_fill_super(struct super_block *sb, void *data, int silent)
 
                ufs->indexdir = ovl_workdir_create(sb, ufs, workpath.dentry,
                                                   OVL_INDEXDIR_NAME, true);
-               err = PTR_ERR(ufs->indexdir);
-               if (IS_ERR(ufs->indexdir))
-                       goto out_put_lower_mnt;
-
                if (ufs->indexdir) {
                        /* Verify upper root is index dir origin */
                        err = ovl_verify_origin(ufs->indexdir, ufs->upper_mnt,
@@ -1090,6 +1087,7 @@ static int ovl_fill_super(struct super_block *sb, void *data, int silent)
        else
                sb->s_d_op = &ovl_dentry_operations;
 
+       err = -ENOMEM;
        ufs->creator_cred = cred = prepare_creds();
        if (!cred)
                goto out_put_indexdir;