Commit f4288844 authored by Miklos Szeredi's avatar Miklos Szeredi
Browse files

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: default avatarMiklos Szeredi <mszeredi@redhat.com>
parent 7925dad8
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -243,6 +243,9 @@ static int ovl_instantiate(struct dentry *dentry, struct inode *inode,

	ovl_dir_modified(dentry->d_parent, false);
	ovl_dentry_set_upper_alias(dentry);
	ovl_dentry_update_reval(dentry, newdentry,
			DCACHE_OP_REVALIDATE | DCACHE_OP_WEAK_REVALIDATE);

	if (!hardlink) {
		/*
		 * ovl_obtain_alias() can be called after ovl_create_real()
+2 −0
Original line number Diff line number Diff line
@@ -324,6 +324,8 @@ static struct dentry *ovl_obtain_alias(struct super_block *sb,
		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);

+3 −0
Original line number Diff line number Diff line
@@ -1077,6 +1077,9 @@ struct dentry *ovl_lookup(struct inode *dir, struct dentry *dentry,
			goto out_free_oe;
	}

	ovl_dentry_update_reval(dentry, upperdentry,
			DCACHE_OP_REVALIDATE | DCACHE_OP_WEAK_REVALIDATE);

	revert_creds(old_cred);
	if (origin_path) {
		dput(origin_path->dentry);
+2 −0
Original line number Diff line number Diff line
@@ -230,6 +230,8 @@ bool ovl_index_all(struct super_block *sb);
bool ovl_verify_lower(struct super_block *sb);
struct ovl_entry *ovl_alloc_entry(unsigned int numlower);
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);
enum ovl_path_type ovl_path_type(struct dentry *dentry);
void ovl_path_upper(struct dentry *dentry, struct path *path);
+5 −16
Original line number Diff line number Diff line
@@ -158,11 +158,6 @@ static int ovl_dentry_weak_revalidate(struct dentry *dentry, unsigned int flags)
static const struct dentry_operations ovl_dentry_operations = {
	.d_release = ovl_dentry_release,
	.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_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,
			 struct ovl_fs *ofs, int *stack_depth, bool *remote)
			 struct ovl_fs *ofs, int *stack_depth)
{
	int fh_type;
	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);

	if (ovl_dentry_remote(path->dentry))
		*remote = true;

	/*
	 * The inodes index feature and NFS export need to encode and decode
	 * 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;
	struct path *stack = NULL;
	unsigned int stacklen, numlower = 0, i;
	bool remote = false;
	struct ovl_entry *oe;

	err = -ENOMEM;
@@ -1473,7 +1464,7 @@ static struct ovl_entry *ovl_get_lowerstack(struct super_block *sb,
	lower = lowertmp;
	for (numlower = 0; numlower < stacklen; numlower++) {
		err = ovl_lower_dir(lower, &stack[numlower], ofs,
				    &sb->s_stack_depth, &remote);
				    &sb->s_stack_depth);
		if (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];
	}

	if (remote)
		sb->s_d_op = &ovl_reval_dentry_operations;
	else
		sb->s_d_op = &ovl_dentry_operations;

out:
	for (i = 0; i < numlower; 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_set_upperdata(d_inode(root));
	ovl_inode_init(d_inode(root), &oip, ino, fsid);
	ovl_dentry_update_reval(root, upperdentry, DCACHE_OP_WEAK_REVALIDATE);

	return root;
}
@@ -1636,6 +1623,8 @@ static int ovl_fill_super(struct super_block *sb, void *data, int silent)
	struct cred *cred;
	int err;

	sb->s_d_op = &ovl_dentry_operations;

	err = -ENOMEM;
	ofs = kzalloc(sizeof(struct ovl_fs), GFP_KERNEL);
	if (!ofs)
Loading