mirror of
https://github.com/Fishwaldo/Star64_linux.git
synced 2025-03-30 19:15:14 +00:00
ovl: decide if revalidate needed on a per-dentry basis
Allow completely skipping ->revalidate() on a per-dentry basis, in case the underlying layers used for a dentry do not themselves have ->revalidate(). E.g. negative overlay dentry has no underlying layers, hence revalidate is unnecessary. Or if lower layer is remote but overlay dentry is pure-upper, then can skip revalidate. The following places need to update whether the dentry needs revalidate or not: - fill-super (root dentry) - lookup - create - fh_to_dentry Signed-off-by: Miklos Szeredi <mszeredi@redhat.com>
This commit is contained in:
parent
7925dad839
commit
f428884456
6 changed files with 30 additions and 16 deletions
|
@ -243,6 +243,9 @@ static int ovl_instantiate(struct dentry *dentry, struct inode *inode,
|
||||||
|
|
||||||
ovl_dir_modified(dentry->d_parent, false);
|
ovl_dir_modified(dentry->d_parent, false);
|
||||||
ovl_dentry_set_upper_alias(dentry);
|
ovl_dentry_set_upper_alias(dentry);
|
||||||
|
ovl_dentry_update_reval(dentry, newdentry,
|
||||||
|
DCACHE_OP_REVALIDATE | DCACHE_OP_WEAK_REVALIDATE);
|
||||||
|
|
||||||
if (!hardlink) {
|
if (!hardlink) {
|
||||||
/*
|
/*
|
||||||
* ovl_obtain_alias() can be called after ovl_create_real()
|
* ovl_obtain_alias() can be called after ovl_create_real()
|
||||||
|
|
|
@ -324,6 +324,8 @@ static struct dentry *ovl_obtain_alias(struct super_block *sb,
|
||||||
if (upper_alias)
|
if (upper_alias)
|
||||||
ovl_dentry_set_upper_alias(dentry);
|
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);
|
return d_instantiate_anon(dentry, inode);
|
||||||
|
|
||||||
|
|
|
@ -1077,6 +1077,9 @@ struct dentry *ovl_lookup(struct inode *dir, struct dentry *dentry,
|
||||||
goto out_free_oe;
|
goto out_free_oe;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ovl_dentry_update_reval(dentry, upperdentry,
|
||||||
|
DCACHE_OP_REVALIDATE | DCACHE_OP_WEAK_REVALIDATE);
|
||||||
|
|
||||||
revert_creds(old_cred);
|
revert_creds(old_cred);
|
||||||
if (origin_path) {
|
if (origin_path) {
|
||||||
dput(origin_path->dentry);
|
dput(origin_path->dentry);
|
||||||
|
|
|
@ -230,6 +230,8 @@ bool ovl_index_all(struct super_block *sb);
|
||||||
bool ovl_verify_lower(struct super_block *sb);
|
bool ovl_verify_lower(struct super_block *sb);
|
||||||
struct ovl_entry *ovl_alloc_entry(unsigned int numlower);
|
struct ovl_entry *ovl_alloc_entry(unsigned int numlower);
|
||||||
bool ovl_dentry_remote(struct dentry *dentry);
|
bool ovl_dentry_remote(struct dentry *dentry);
|
||||||
|
void ovl_dentry_update_reval(struct dentry *dentry, struct dentry *upperdentry,
|
||||||
|
unsigned int mask);
|
||||||
bool ovl_dentry_weird(struct dentry *dentry);
|
bool ovl_dentry_weird(struct dentry *dentry);
|
||||||
enum ovl_path_type ovl_path_type(struct dentry *dentry);
|
enum ovl_path_type ovl_path_type(struct dentry *dentry);
|
||||||
void ovl_path_upper(struct dentry *dentry, struct path *path);
|
void ovl_path_upper(struct dentry *dentry, struct path *path);
|
||||||
|
|
|
@ -158,11 +158,6 @@ static int ovl_dentry_weak_revalidate(struct dentry *dentry, unsigned int flags)
|
||||||
static const struct dentry_operations ovl_dentry_operations = {
|
static const struct dentry_operations ovl_dentry_operations = {
|
||||||
.d_release = ovl_dentry_release,
|
.d_release = ovl_dentry_release,
|
||||||
.d_real = ovl_d_real,
|
.d_real = ovl_d_real,
|
||||||
};
|
|
||||||
|
|
||||||
static const struct dentry_operations ovl_reval_dentry_operations = {
|
|
||||||
.d_release = ovl_dentry_release,
|
|
||||||
.d_real = ovl_d_real,
|
|
||||||
.d_revalidate = ovl_dentry_revalidate,
|
.d_revalidate = ovl_dentry_revalidate,
|
||||||
.d_weak_revalidate = ovl_dentry_weak_revalidate,
|
.d_weak_revalidate = ovl_dentry_weak_revalidate,
|
||||||
};
|
};
|
||||||
|
@ -779,7 +774,7 @@ static int ovl_check_namelen(struct path *path, struct ovl_fs *ofs,
|
||||||
}
|
}
|
||||||
|
|
||||||
static int ovl_lower_dir(const char *name, struct path *path,
|
static int ovl_lower_dir(const char *name, struct path *path,
|
||||||
struct ovl_fs *ofs, int *stack_depth, bool *remote)
|
struct ovl_fs *ofs, int *stack_depth)
|
||||||
{
|
{
|
||||||
int fh_type;
|
int fh_type;
|
||||||
int err;
|
int err;
|
||||||
|
@ -794,9 +789,6 @@ static int ovl_lower_dir(const char *name, struct path *path,
|
||||||
|
|
||||||
*stack_depth = max(*stack_depth, path->mnt->mnt_sb->s_stack_depth);
|
*stack_depth = max(*stack_depth, path->mnt->mnt_sb->s_stack_depth);
|
||||||
|
|
||||||
if (ovl_dentry_remote(path->dentry))
|
|
||||||
*remote = true;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The inodes index feature and NFS export need to encode and decode
|
* The inodes index feature and NFS export need to encode and decode
|
||||||
* file handles, so they require that all layers support them.
|
* file handles, so they require that all layers support them.
|
||||||
|
@ -1441,7 +1433,6 @@ static struct ovl_entry *ovl_get_lowerstack(struct super_block *sb,
|
||||||
char *lowertmp, *lower;
|
char *lowertmp, *lower;
|
||||||
struct path *stack = NULL;
|
struct path *stack = NULL;
|
||||||
unsigned int stacklen, numlower = 0, i;
|
unsigned int stacklen, numlower = 0, i;
|
||||||
bool remote = false;
|
|
||||||
struct ovl_entry *oe;
|
struct ovl_entry *oe;
|
||||||
|
|
||||||
err = -ENOMEM;
|
err = -ENOMEM;
|
||||||
|
@ -1473,7 +1464,7 @@ static struct ovl_entry *ovl_get_lowerstack(struct super_block *sb,
|
||||||
lower = lowertmp;
|
lower = lowertmp;
|
||||||
for (numlower = 0; numlower < stacklen; numlower++) {
|
for (numlower = 0; numlower < stacklen; numlower++) {
|
||||||
err = ovl_lower_dir(lower, &stack[numlower], ofs,
|
err = ovl_lower_dir(lower, &stack[numlower], ofs,
|
||||||
&sb->s_stack_depth, &remote);
|
&sb->s_stack_depth);
|
||||||
if (err)
|
if (err)
|
||||||
goto out_err;
|
goto out_err;
|
||||||
|
|
||||||
|
@ -1501,11 +1492,6 @@ static struct ovl_entry *ovl_get_lowerstack(struct super_block *sb,
|
||||||
oe->lowerstack[i].layer = &ofs->layers[i+1];
|
oe->lowerstack[i].layer = &ofs->layers[i+1];
|
||||||
}
|
}
|
||||||
|
|
||||||
if (remote)
|
|
||||||
sb->s_d_op = &ovl_reval_dentry_operations;
|
|
||||||
else
|
|
||||||
sb->s_d_op = &ovl_dentry_operations;
|
|
||||||
|
|
||||||
out:
|
out:
|
||||||
for (i = 0; i < numlower; i++)
|
for (i = 0; i < numlower; i++)
|
||||||
path_put(&stack[i]);
|
path_put(&stack[i]);
|
||||||
|
@ -1623,6 +1609,7 @@ static struct dentry *ovl_get_root(struct super_block *sb,
|
||||||
ovl_dentry_set_flag(OVL_E_CONNECTED, root);
|
ovl_dentry_set_flag(OVL_E_CONNECTED, root);
|
||||||
ovl_set_upperdata(d_inode(root));
|
ovl_set_upperdata(d_inode(root));
|
||||||
ovl_inode_init(d_inode(root), &oip, ino, fsid);
|
ovl_inode_init(d_inode(root), &oip, ino, fsid);
|
||||||
|
ovl_dentry_update_reval(root, upperdentry, DCACHE_OP_WEAK_REVALIDATE);
|
||||||
|
|
||||||
return root;
|
return root;
|
||||||
}
|
}
|
||||||
|
@ -1636,6 +1623,8 @@ static int ovl_fill_super(struct super_block *sb, void *data, int silent)
|
||||||
struct cred *cred;
|
struct cred *cred;
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
|
sb->s_d_op = &ovl_dentry_operations;
|
||||||
|
|
||||||
err = -ENOMEM;
|
err = -ENOMEM;
|
||||||
ofs = kzalloc(sizeof(struct ovl_fs), GFP_KERNEL);
|
ofs = kzalloc(sizeof(struct ovl_fs), GFP_KERNEL);
|
||||||
if (!ofs)
|
if (!ofs)
|
||||||
|
|
|
@ -96,6 +96,21 @@ bool ovl_dentry_remote(struct dentry *dentry)
|
||||||
(DCACHE_OP_REVALIDATE | DCACHE_OP_WEAK_REVALIDATE);
|
(DCACHE_OP_REVALIDATE | DCACHE_OP_WEAK_REVALIDATE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ovl_dentry_update_reval(struct dentry *dentry, struct dentry *upperdentry,
|
||||||
|
unsigned int mask)
|
||||||
|
{
|
||||||
|
struct ovl_entry *oe = OVL_E(dentry);
|
||||||
|
unsigned int i, flags = 0;
|
||||||
|
|
||||||
|
for (i = 0; i < oe->numlower; i++)
|
||||||
|
flags |= oe->lowerstack[i].dentry->d_flags;
|
||||||
|
|
||||||
|
spin_lock(&dentry->d_lock);
|
||||||
|
dentry->d_flags &= ~mask;
|
||||||
|
dentry->d_flags |= flags & mask;
|
||||||
|
spin_unlock(&dentry->d_lock);
|
||||||
|
}
|
||||||
|
|
||||||
bool ovl_dentry_weird(struct dentry *dentry)
|
bool ovl_dentry_weird(struct dentry *dentry)
|
||||||
{
|
{
|
||||||
return dentry->d_flags & (DCACHE_NEED_AUTOMOUNT |
|
return dentry->d_flags & (DCACHE_NEED_AUTOMOUNT |
|
||||||
|
|
Loading…
Add table
Reference in a new issue