diff options
| author | NeilBrown <neil@brown.name> | 2026-09-05 07:48:12 +1000 |
|---|---|---|
| committer | Christian Brauner <brauner@kernel.org> | 2026-09-25 16:27:19 +0200 |
| commit | 17c7d109d8c9a6744b40ded06cc596cd6a80ec49 (patch) | |
| tree | 8559f2cf8000c20ceaa9622b0d575293941386c0 /include | |
| parent | f1ac607f786f5216d40ffbbc557d0cf87e21bfd9 (diff) | |
| download | linux-next-17c7d109d8c9a6744b40ded06cc596cd6a80ec49.tar.gz linux-next-17c7d109d8c9a6744b40ded06cc596cd6a80ec49.zip | |
VFS: introduce d_alloc_trylock()
Several filesystems use the results of readdir to prime the dcache.
These filesystems use d_alloc_parallel() which can block if there is a
concurrent lookup. Blocking in that case is pointless as the lookup
will add info to the dcache and there is no value in the readdir waiting
to see if it should add the info too.
Also these calls to d_alloc_parallel() are made while the parent
directory is locked. A proposed change to locking will lock the parent
later, after d_alloc_parallel(). This means it won't be safe to wait in
d_alloc_parallel() while holding the directory lock.
So this patch introduces d_alloc_trylock() which doesn't block but
instead returns ERR_PTR(-EWOULDBLOCK). Filesystems that prime the
dcache (smb/client, nfs, fuse, cephfs) can now use that and ignore
-EWOULDBLOCK errors as harmless.
Unlike d_alloc_parallel(), d_alloc_trylock() calculates the hash and
performs a lookup before an allocation, as that is what all callers
want. This is done using try_lookup_noperm(), necessitating the
inclusion of namei.h in dcache.c.
Signed-off-by: NeilBrown <neil@brown.name>
Link: https://patch.msgid.link/20260904215142.1060510-4-neilb@ownmail.net
Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
Diffstat (limited to 'include')
| -rw-r--r-- | include/linux/dcache.h | 1 |
1 files changed, 1 insertions, 0 deletions
diff --git a/include/linux/dcache.h b/include/linux/dcache.h index 4b1ff99608e0..7afe16d4664d 100644 --- a/include/linux/dcache.h +++ b/include/linux/dcache.h @@ -257,6 +257,7 @@ extern void d_delete(struct dentry *); extern struct dentry * d_alloc(struct dentry *, const struct qstr *); extern struct dentry * d_alloc_anon(struct super_block *); extern struct dentry * d_alloc_parallel(struct dentry *, const struct qstr *); +extern struct dentry * d_alloc_trylock(struct dentry *, struct qstr *); extern struct dentry * d_splice_alias(struct inode *, struct dentry *); /* weird procfs mess; *NOT* exported */ extern struct dentry * d_splice_alias_ops(struct inode *, struct dentry *, |
