From: Dominique Martinet cache=mmap is a mode that doesn't cache metadata, but still has writeback cache. In commit 290434474c33 ("fs/9p: Refresh metadata in d_revalidate for uncached mode too") we considered metadata cache to be enough to not look at the server, but in writeback cache too looking at the server size would make the vfs consider the file has been truncated before the data has been flushed out, making the following repro fail (nothing is ever read back, the resulting file ends up with no data written) --- I was suspecting cache=mmap when I saw vmtest used that, and it's confirmed with Song's reproducer... This makes the repro work, would one of you be able to confirm this? Once confirmed I'll send this to Linus directly Thanks again and sorry for lack of cache=mmap tests :/ Signed-off-by: Dominique Martinet --- #include #include #include #include char buf[4096]; int main(int argc, char *argv[]) { int ret, i; int fdw, fdr; if (argc < 2) return 1; fdw = openat(AT_FDCWD, argv[1], O_RDWR|O_CREAT|O_EXCL|O_CLOEXEC, 0600); if (fdw < 0) { fprintf(stderr, "cannot open fdw\n"); return 1; } write(fdw, buf, sizeof(buf)); fdr = openat(AT_FDCWD, argv[1], O_RDONLY|O_CLOEXEC); if (fdr < 0) { fprintf(stderr, "cannot open fdr\n"); close(fdw); return 1; } for (i = 0; i < 10; i++) { ret = read(fdr, buf, sizeof(buf)); fprintf(stderr, "i: %d, read returns %d\n", i, ret); } close(fdr); close(fdw); return 0; } --- Reported-by: Song Liu Link: https://lkml.kernel.org/r/CAHzjS_u_SYdt5=2gYO_dxzMKXzGMt-TfdE_ueowg-Hq5tRCAiw@mail.gmail.com Reported-by: Andrii Nakryiko Link: https://lore.kernel.org/bpf/CAEf4BzZbCE4tLoDZyUf_aASpgAGFj75QMfSXX4a4dLYixnOiLg@mail.gmail.com/ Fixes: 290434474c33 ("fs/9p: Refresh metadata in d_revalidate for uncached mode too") Signed-off-by: Dominique Martinet --- fs/9p/vfs_dentry.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/fs/9p/vfs_dentry.c b/fs/9p/vfs_dentry.c index f3248a3e54023489054337bf98e87a1d7b1fbafc..2f3654bf6275ffa802dc25b9a84bd61a62d5723c 100644 --- a/fs/9p/vfs_dentry.c +++ b/fs/9p/vfs_dentry.c @@ -78,7 +78,11 @@ static int __v9fs_lookup_revalidate(struct dentry *dentry, unsigned int flags) v9inode = V9FS_I(inode); struct v9fs_session_info *v9ses = v9fs_inode2v9ses(inode); - cached = v9ses->cache & (CACHE_META | CACHE_LOOSE); + /* We also don't want to refresh attr here in writeback cache mode, + * otherwise a write that hasn't been propagated to server would + * incorrectly get the old size back and truncate the file before + * the write happens */ + cached = v9ses->cache & (CACHE_META | CACHE_WRITEBACK | CACHE_LOOSE); if (!cached || v9inode->cache_validity & V9FS_INO_INVALID_ATTR) { int retval; --- base-commit: 211ddde0823f1442e4ad052a2f30f050145ccada change-id: 20251022-mmap-regression-f0f40d51046d Best regards, -- Dominique Martinet