diff options
| author | Chris Mason <mason@kernel.org> | 2026-10-16 21:17:23 +0000 |
|---|---|---|
| committer | Amir Goldstein <amir73il@gmail.com> | 2026-10-29 13:24:00 +0100 |
| commit | 75e89c0055c1d7f7eeb462995f11253ca5864f79 (patch) | |
| tree | 198170a7930abf6d4bc1f99c363a7fe0dcb79f51 /scripts/Makefile.thinlto | |
| parent | 949f9d8a5580c77a45fa759123367682aba4d173 (diff) | |
| download | linux-75e89c0055c1d7f7eeb462995f11253ca5864f79.tar.gz linux-75e89c0055c1d7f7eeb462995f11253ca5864f79.zip | |
ovl: set the revalidate flags after d_instantiate()
stat() of a file on an overlayfs mount triggers a kernel warning and
fails with ECHILD if another task is creating that file at the same
time. This happens on an overlay with a FUSE upper layer, which is the
layer where overlayfs creates new files. Write access to a directory on
such an overlay is all a user needs to run the two tasks.
The revalidate flags are DCACHE_OP_REVALIDATE and
DCACHE_OP_WEAK_REVALIDATE. They tell path walk to call ->d_revalidate()
or ->d_weak_revalidate() on a dentry, so that the filesystem can check
that the cached dentry is still valid. An overlay dentry only has one of
these flags if a dentry in one of its layers has it. FUSE dentries have
the first one.
When a flag is set on an overlay dentry, path walk calls
ovl_dentry_revalidate_common(). That function only expects a dentry
without an inode in RCU walk, while the dentry is being destroyed. For
such a dentry outside of RCU walk, it hits a WARN_ON() and
returns -ECHILD. So a negative overlay dentry must never have the flags
set.
ovl_instantiate() breaks this rule. When a task creates a file, the
overlay dentry for the new name is hashed but still negative.
ovl_instantiate() then works in this order:
- It copies the flags from the new upper dentry to the overlay dentry.
- It calls ovl_get_inode(), which can sleep in a getxattr request to the
FUSE server.
- Only then does it call d_instantiate().
A second task that looks up the name between the first step and the last
finds a negative dentry with the flags set and revalidates it.
Reproduced with a FUSE server that delays its getxattr reply: stat() of
a name that was being created hit the WARN_ON() and failed with ECHILD.
Fix this by setting the flags after d_instantiate().
Fixes: bccece1ead36 ("ovl: allow remote upper")
Cc: stable@vger.kernel.org
Signed-off-by: Chris Mason <mason@kernel.org>
Signed-off-by: Amir Goldstein <amir73il@gmail.com>
Diffstat (limited to 'scripts/Makefile.thinlto')
0 files changed, 0 insertions, 0 deletions
