Skip to content

Commit f428884

Browse files
author
Miklos Szeredi
committed
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 <[email protected]>
1 parent 7925dad commit f428884

File tree

6 files changed

+30
-16
lines changed

6 files changed

+30
-16
lines changed

fs/overlayfs/dir.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -243,6 +243,9 @@ static int ovl_instantiate(struct dentry *dentry, struct inode *inode,
243243

244244
ovl_dir_modified(dentry->d_parent, false);
245245
ovl_dentry_set_upper_alias(dentry);
246+
ovl_dentry_update_reval(dentry, newdentry,
247+
DCACHE_OP_REVALIDATE | DCACHE_OP_WEAK_REVALIDATE);
248+
246249
if (!hardlink) {
247250
/*
248251
* ovl_obtain_alias() can be called after ovl_create_real()

fs/overlayfs/export.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -324,6 +324,8 @@ static struct dentry *ovl_obtain_alias(struct super_block *sb,
324324
if (upper_alias)
325325
ovl_dentry_set_upper_alias(dentry);
326326
}
327+
ovl_dentry_update_reval(dentry, upper,
328+
DCACHE_OP_REVALIDATE | DCACHE_OP_WEAK_REVALIDATE);
327329

328330
return d_instantiate_anon(dentry, inode);
329331

fs/overlayfs/namei.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1077,6 +1077,9 @@ struct dentry *ovl_lookup(struct inode *dir, struct dentry *dentry,
10771077
goto out_free_oe;
10781078
}
10791079

1080+
ovl_dentry_update_reval(dentry, upperdentry,
1081+
DCACHE_OP_REVALIDATE | DCACHE_OP_WEAK_REVALIDATE);
1082+
10801083
revert_creds(old_cred);
10811084
if (origin_path) {
10821085
dput(origin_path->dentry);

fs/overlayfs/overlayfs.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -230,6 +230,8 @@ bool ovl_index_all(struct super_block *sb);
230230
bool ovl_verify_lower(struct super_block *sb);
231231
struct ovl_entry *ovl_alloc_entry(unsigned int numlower);
232232
bool ovl_dentry_remote(struct dentry *dentry);
233+
void ovl_dentry_update_reval(struct dentry *dentry, struct dentry *upperdentry,
234+
unsigned int mask);
233235
bool ovl_dentry_weird(struct dentry *dentry);
234236
enum ovl_path_type ovl_path_type(struct dentry *dentry);
235237
void ovl_path_upper(struct dentry *dentry, struct path *path);

fs/overlayfs/super.c

Lines changed: 5 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -158,11 +158,6 @@ static int ovl_dentry_weak_revalidate(struct dentry *dentry, unsigned int flags)
158158
static const struct dentry_operations ovl_dentry_operations = {
159159
.d_release = ovl_dentry_release,
160160
.d_real = ovl_d_real,
161-
};
162-
163-
static const struct dentry_operations ovl_reval_dentry_operations = {
164-
.d_release = ovl_dentry_release,
165-
.d_real = ovl_d_real,
166161
.d_revalidate = ovl_dentry_revalidate,
167162
.d_weak_revalidate = ovl_dentry_weak_revalidate,
168163
};
@@ -779,7 +774,7 @@ static int ovl_check_namelen(struct path *path, struct ovl_fs *ofs,
779774
}
780775

781776
static int ovl_lower_dir(const char *name, struct path *path,
782-
struct ovl_fs *ofs, int *stack_depth, bool *remote)
777+
struct ovl_fs *ofs, int *stack_depth)
783778
{
784779
int fh_type;
785780
int err;
@@ -794,9 +789,6 @@ static int ovl_lower_dir(const char *name, struct path *path,
794789

795790
*stack_depth = max(*stack_depth, path->mnt->mnt_sb->s_stack_depth);
796791

797-
if (ovl_dentry_remote(path->dentry))
798-
*remote = true;
799-
800792
/*
801793
* The inodes index feature and NFS export need to encode and decode
802794
* 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,
14411433
char *lowertmp, *lower;
14421434
struct path *stack = NULL;
14431435
unsigned int stacklen, numlower = 0, i;
1444-
bool remote = false;
14451436
struct ovl_entry *oe;
14461437

14471438
err = -ENOMEM;
@@ -1473,7 +1464,7 @@ static struct ovl_entry *ovl_get_lowerstack(struct super_block *sb,
14731464
lower = lowertmp;
14741465
for (numlower = 0; numlower < stacklen; numlower++) {
14751466
err = ovl_lower_dir(lower, &stack[numlower], ofs,
1476-
&sb->s_stack_depth, &remote);
1467+
&sb->s_stack_depth);
14771468
if (err)
14781469
goto out_err;
14791470

@@ -1501,11 +1492,6 @@ static struct ovl_entry *ovl_get_lowerstack(struct super_block *sb,
15011492
oe->lowerstack[i].layer = &ofs->layers[i+1];
15021493
}
15031494

1504-
if (remote)
1505-
sb->s_d_op = &ovl_reval_dentry_operations;
1506-
else
1507-
sb->s_d_op = &ovl_dentry_operations;
1508-
15091495
out:
15101496
for (i = 0; i < numlower; i++)
15111497
path_put(&stack[i]);
@@ -1623,6 +1609,7 @@ static struct dentry *ovl_get_root(struct super_block *sb,
16231609
ovl_dentry_set_flag(OVL_E_CONNECTED, root);
16241610
ovl_set_upperdata(d_inode(root));
16251611
ovl_inode_init(d_inode(root), &oip, ino, fsid);
1612+
ovl_dentry_update_reval(root, upperdentry, DCACHE_OP_WEAK_REVALIDATE);
16261613

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

1626+
sb->s_d_op = &ovl_dentry_operations;
1627+
16391628
err = -ENOMEM;
16401629
ofs = kzalloc(sizeof(struct ovl_fs), GFP_KERNEL);
16411630
if (!ofs)

fs/overlayfs/util.c

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,21 @@ bool ovl_dentry_remote(struct dentry *dentry)
9696
(DCACHE_OP_REVALIDATE | DCACHE_OP_WEAK_REVALIDATE);
9797
}
9898

99+
void ovl_dentry_update_reval(struct dentry *dentry, struct dentry *upperdentry,
100+
unsigned int mask)
101+
{
102+
struct ovl_entry *oe = OVL_E(dentry);
103+
unsigned int i, flags = 0;
104+
105+
for (i = 0; i < oe->numlower; i++)
106+
flags |= oe->lowerstack[i].dentry->d_flags;
107+
108+
spin_lock(&dentry->d_lock);
109+
dentry->d_flags &= ~mask;
110+
dentry->d_flags |= flags & mask;
111+
spin_unlock(&dentry->d_lock);
112+
}
113+
99114
bool ovl_dentry_weird(struct dentry *dentry)
100115
{
101116
return dentry->d_flags & (DCACHE_NEED_AUTOMOUNT |

0 commit comments

Comments
 (0)