Commit 97c684cc authored by Amir Goldstein's avatar Amir Goldstein Committed by Miklos Szeredi

ovl: create directories inside merged parent opaque

The benefit of making directories opaque on creation is that lookups can
stop short when they reach the original created directory, instead of
continue lookup the entire depth of parent directory stack.

The best case is overlay with N layers, performing lookup for first level
directory, which exists only in upper.  In that case, there will be only
one lookup instead of N.
Signed-off-by: default avatarAmir Goldstein <amir73il@gmail.com>
Signed-off-by: default avatarMiklos Szeredi <mszeredi@redhat.com>
parent 5cf5b477
...@@ -184,6 +184,11 @@ static void ovl_instantiate(struct dentry *dentry, struct inode *inode, ...@@ -184,6 +184,11 @@ static void ovl_instantiate(struct dentry *dentry, struct inode *inode,
d_instantiate(dentry, inode); d_instantiate(dentry, inode);
} }
static bool ovl_type_merge(struct dentry *dentry)
{
return OVL_TYPE_MERGE(ovl_path_type(dentry));
}
static int ovl_create_upper(struct dentry *dentry, struct inode *inode, static int ovl_create_upper(struct dentry *dentry, struct inode *inode,
struct kstat *stat, const char *link, struct kstat *stat, const char *link,
struct dentry *hardlink) struct dentry *hardlink)
...@@ -206,6 +211,11 @@ static int ovl_create_upper(struct dentry *dentry, struct inode *inode, ...@@ -206,6 +211,11 @@ static int ovl_create_upper(struct dentry *dentry, struct inode *inode,
if (err) if (err)
goto out_dput; goto out_dput;
if (ovl_type_merge(dentry->d_parent)) {
/* Setting opaque here is just an optimization, allow to fail */
ovl_set_opaque(dentry, newdentry);
}
ovl_instantiate(dentry, inode, newdentry, !!hardlink); ovl_instantiate(dentry, inode, newdentry, !!hardlink);
newdentry = NULL; newdentry = NULL;
out_dput: out_dput:
...@@ -1006,7 +1016,7 @@ static int ovl_rename(struct inode *olddir, struct dentry *old, ...@@ -1006,7 +1016,7 @@ static int ovl_rename(struct inode *olddir, struct dentry *old,
if (is_dir) { if (is_dir) {
if (ovl_type_merge_or_lower(old)) if (ovl_type_merge_or_lower(old))
err = ovl_set_redirect(old, samedir); err = ovl_set_redirect(old, samedir);
else if (!old_opaque && ovl_lower_positive(new)) else if (!old_opaque && ovl_type_merge(new->d_parent))
err = ovl_set_opaque(old, olddentry); err = ovl_set_opaque(old, olddentry);
if (err) if (err)
goto out_dput; goto out_dput;
...@@ -1014,7 +1024,7 @@ static int ovl_rename(struct inode *olddir, struct dentry *old, ...@@ -1014,7 +1024,7 @@ static int ovl_rename(struct inode *olddir, struct dentry *old,
if (!overwrite && new_is_dir) { if (!overwrite && new_is_dir) {
if (ovl_type_merge_or_lower(new)) if (ovl_type_merge_or_lower(new))
err = ovl_set_redirect(new, samedir); err = ovl_set_redirect(new, samedir);
else if (!new_opaque && ovl_lower_positive(old)) else if (!new_opaque && ovl_type_merge(old->d_parent))
err = ovl_set_opaque(new, newdentry); err = ovl_set_opaque(new, newdentry);
if (err) if (err)
goto out_dput; goto out_dput;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment