* [PATCH v2] readdir: require opt-in for d_type flags
@ 2026-01-08 7:45 Amir Goldstein
2026-01-12 9:58 ` Christian Brauner
0 siblings, 1 reply; 2+ messages in thread
From: Amir Goldstein @ 2026-01-08 7:45 UTC (permalink / raw)
To: Christian Brauner
Cc: Miklos Szeredi, Al Viro, linux-fsdevel, linux-unionfs,
Chunsheng Luo
Commit c31f91c6af96 ("fuse: don't allow signals to interrupt getdents
copying") introduced the use of high bits in d_type as flags. However,
overlayfs was not adapted to handle this change.
In ovl_cache_entry_new(), the code checks if d_type == DT_CHR to
determine if an entry might be a whiteout. When fuse is used as the
lower layer and sets high bits in d_type, this comparison fails,
causing whiteout files to not be recognized properly and resulting in
incorrect overlayfs behavior.
Fix this by requiring callers of iterate_dir() to opt-in for getting
flag bits in d_type outside of S_DT_MASK.
Fixes: c31f91c6af96 ("fuse: don't allow signals to interrupt getdents copying")
Link: https://lore.kernel.org/all/20260107034551.439-1-luochunsheng@ustc.edu/
Link: https://github.com/containerd/stargz-snapshotter/issues/2214
Reported-by: Chunsheng Luo <luochunsheng@ustc.edu>
Reviewed-by: Chunsheng Luo <luochunsheng@ustc.edu>
Tested-by: Chunsheng Luo <luochunsheng@ustc.edu>
Signed-off-by: Amir Goldstein <amir73il@gmail.com>
---
Christian,
"Not pretty, but fine." [0]
This is what you had to say on the Fixes commit ;)
Maybe this will be finer...
I was considering whether or not a mention in porting.rst is due.
My conclusion was that the regressing commit might have needed to
mention a change of vfs API, but this fix brings the vfs API back to
conform to pre v6.16 semantics, so no porting instructions apply.
Thanks,
Amir.
Chages sinse v1:
- Rename s/dt_flag_mask/dt_flags_mask/
- Add Test/Reviewd-by
[0] https://lore.kernel.org/linux-fsdevel/20250515-antlitz-aufzwingen-cdba155ce864@brauner/
fs/readdir.c | 3 +++
include/linux/fs.h | 6 +++++-
2 files changed, 8 insertions(+), 1 deletion(-)
diff --git a/fs/readdir.c b/fs/readdir.c
index 7764b86389788..73707b6816e9a 100644
--- a/fs/readdir.c
+++ b/fs/readdir.c
@@ -316,6 +316,7 @@ SYSCALL_DEFINE3(getdents, unsigned int, fd,
struct getdents_callback buf = {
.ctx.actor = filldir,
.ctx.count = count,
+ .ctx.dt_flags_mask = FILLDIR_FLAG_NOINTR,
.current_dir = dirent
};
int error;
@@ -400,6 +401,7 @@ SYSCALL_DEFINE3(getdents64, unsigned int, fd,
struct getdents_callback64 buf = {
.ctx.actor = filldir64,
.ctx.count = count,
+ .ctx.dt_flags_mask = FILLDIR_FLAG_NOINTR,
.current_dir = dirent
};
int error;
@@ -569,6 +571,7 @@ COMPAT_SYSCALL_DEFINE3(getdents, unsigned int, fd,
struct compat_getdents_callback buf = {
.ctx.actor = compat_filldir,
.ctx.count = count,
+ .ctx.dt_flags_mask = FILLDIR_FLAG_NOINTR,
.current_dir = dirent,
};
int error;
diff --git a/include/linux/fs.h b/include/linux/fs.h
index f5c9cf28c4dcf..a01621fa636a6 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -1855,6 +1855,8 @@ struct dir_context {
* INT_MAX unlimited
*/
int count;
+ /* @actor supports these flags in d_type high bits */
+ unsigned int dt_flags_mask;
};
/* If OR-ed with d_type, pending signals are not checked */
@@ -3524,7 +3526,9 @@ static inline bool dir_emit(struct dir_context *ctx,
const char *name, int namelen,
u64 ino, unsigned type)
{
- return ctx->actor(ctx, name, namelen, ctx->pos, ino, type);
+ unsigned int dt_mask = S_DT_MASK | ctx->dt_flags_mask;
+
+ return ctx->actor(ctx, name, namelen, ctx->pos, ino, type & dt_mask);
}
static inline bool dir_emit_dot(struct file *file, struct dir_context *ctx)
{
--
2.52.0
^ permalink raw reply related [flat|nested] 2+ messages in thread* Re: [PATCH v2] readdir: require opt-in for d_type flags
2026-01-08 7:45 [PATCH v2] readdir: require opt-in for d_type flags Amir Goldstein
@ 2026-01-12 9:58 ` Christian Brauner
0 siblings, 0 replies; 2+ messages in thread
From: Christian Brauner @ 2026-01-12 9:58 UTC (permalink / raw)
To: Amir Goldstein
Cc: Christian Brauner, Miklos Szeredi, Al Viro, linux-fsdevel,
linux-unionfs, Chunsheng Luo
On Thu, 08 Jan 2026 08:45:22 +0100, Amir Goldstein wrote:
> Commit c31f91c6af96 ("fuse: don't allow signals to interrupt getdents
> copying") introduced the use of high bits in d_type as flags. However,
> overlayfs was not adapted to handle this change.
>
> In ovl_cache_entry_new(), the code checks if d_type == DT_CHR to
> determine if an entry might be a whiteout. When fuse is used as the
> lower layer and sets high bits in d_type, this comparison fails,
> causing whiteout files to not be recognized properly and resulting in
> incorrect overlayfs behavior.
>
> [...]
Applied to the vfs.fixes branch of the vfs/vfs.git tree.
Patches in the vfs.fixes branch should appear in linux-next soon.
Please report any outstanding bugs that were missed during review in a
new review to the original patch series allowing us to drop it.
It's encouraged to provide Acked-bys and Reviewed-bys even though the
patch has now been applied. If possible patch trailers will be updated.
Note that commit hashes shown below are subject to change due to rebase,
trailer updates or similar. If in doubt, please check the listed branch.
tree: https://git.kernel.org/pub/scm/linux/kernel/git/vfs/vfs.git
branch: vfs.fixes
[1/1] readdir: require opt-in for d_type flags
https://git.kernel.org/vfs/vfs/c/c644bce62b9c
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2026-01-12 9:58 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-01-08 7:45 [PATCH v2] readdir: require opt-in for d_type flags Amir Goldstein
2026-01-12 9:58 ` Christian Brauner
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox