diff options
author | Al Viro <viro@zeniv.linux.org.uk> | 2019-10-24 02:06:45 +0100 |
---|---|---|
committer | Miklos Szeredi <mszeredi@redhat.com> | 2020-03-17 15:04:23 +0100 |
commit | 504f38410a51f513606c3c18c7f6a32c1ca2afb5 (patch) | |
tree | e8a2e54e38b055cb5bf7b5db33834a294b77837e /fs | |
parent | d80172c2d85947efe285693c5cea9c8976f478bf (diff) | |
download | linux-504f38410a51f513606c3c18c7f6a32c1ca2afb5.tar.bz2 |
ovl: ovl_obtain_alias(): don't call d_instantiate_anon() for old
The situation is the same as for __d_obtain_alias() (which is what that
thing is parallel to) - if we find a preexisting alias, we want to grab it,
drop the inode and return the alias we'd found.
The only thing d_instantiate_anon() does compared to that is spurious
security_d_instiate() that has already been done to that dentry with exact
same arguments.
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Signed-off-by: Miklos Szeredi <mszeredi@redhat.com>
Diffstat (limited to 'fs')
-rw-r--r-- | fs/overlayfs/export.c | 38 |
1 files changed, 21 insertions, 17 deletions
diff --git a/fs/overlayfs/export.c b/fs/overlayfs/export.c index a58b3d9b06b9..475c61f53f0f 100644 --- a/fs/overlayfs/export.c +++ b/fs/overlayfs/export.c @@ -308,31 +308,35 @@ static struct dentry *ovl_obtain_alias(struct super_block *sb, ovl_set_flag(OVL_UPPERDATA, inode); dentry = d_find_any_alias(inode); - if (!dentry) { - dentry = d_alloc_anon(inode->i_sb); - if (!dentry) - goto nomem; - oe = ovl_alloc_entry(lower ? 1 : 0); - if (!oe) - goto nomem; - - if (lower) { - oe->lowerstack->dentry = dget(lower); - oe->lowerstack->layer = lowerpath->layer; - } - dentry->d_fsdata = oe; - if (upper_alias) - ovl_dentry_set_upper_alias(dentry); + if (dentry) + goto out_iput; + + dentry = d_alloc_anon(inode->i_sb); + if (unlikely(!dentry)) + goto nomem; + oe = ovl_alloc_entry(lower ? 1 : 0); + if (!oe) + goto nomem; + + if (lower) { + oe->lowerstack->dentry = dget(lower); + oe->lowerstack->layer = lowerpath->layer; } + dentry->d_fsdata = oe; + if (upper_alias) + ovl_dentry_set_upper_alias(dentry); + ovl_dentry_update_reval(dentry, upper, DCACHE_OP_REVALIDATE | DCACHE_OP_WEAK_REVALIDATE); return d_instantiate_anon(dentry, inode); nomem: - iput(inode); dput(dentry); - return ERR_PTR(-ENOMEM); + dentry = ERR_PTR(-ENOMEM); +out_iput: + iput(inode); + return dentry; } /* Get the upper or lower dentry in stach whose on layer @idx */ |