summaryrefslogtreecommitdiff
path: root/fs/overlayfs/super.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/overlayfs/super.c')
-rw-r--r--fs/overlayfs/super.c24
1 files changed, 11 insertions, 13 deletions
diff --git a/fs/overlayfs/super.c b/fs/overlayfs/super.c
index 22ee2a9ee784..fd5ea4facc62 100644
--- a/fs/overlayfs/super.c
+++ b/fs/overlayfs/super.c
@@ -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;