[PATCH 2/3] ovl: support cachestat() syscall on overlayfs files

From: Pavel Tikhomirov

Date: Tue Jun 23 2026 - 07:16:33 EST


Overlayfs forwards data I/O to the real (upper/lower) file, so the page
cache lives in the real inode's mapping and cachestat() on an overlay
fd returned all zeroes.

Implement the ->cachestat() file operation by forwarding to the real
file via vfs_cachestat(), the same way ovl_fadvise() forwards
for fadvise.

Signed-off-by: Pavel Tikhomirov <ptikhomirov@xxxxxxxxxxxxx>
---
fs/overlayfs/file.c | 18 ++++++++++++++++++
1 file changed, 18 insertions(+)

diff --git a/fs/overlayfs/file.c b/fs/overlayfs/file.c
index 27cc07738f33b..a7e252a91ea43 100644
--- a/fs/overlayfs/file.c
+++ b/fs/overlayfs/file.c
@@ -518,6 +518,21 @@ static int ovl_fadvise(struct file *file, loff_t offset, loff_t len, int advice)
return vfs_fadvise(realfile, offset, len, advice);
}

+#ifdef CONFIG_CACHESTAT_SYSCALL
+static int ovl_cachestat(struct file *file, struct cachestat_range *csr,
+ struct cachestat *cs)
+{
+ struct file *realfile;
+
+ realfile = ovl_real_file(file);
+ if (IS_ERR(realfile))
+ return PTR_ERR(realfile);
+
+ with_ovl_creds(file_inode(file)->i_sb)
+ return vfs_cachestat(realfile, csr, cs);
+}
+#endif
+
enum ovl_copyop {
OVL_COPY,
OVL_CLONE,
@@ -642,6 +657,9 @@ const struct file_operations ovl_file_operations = {
.mmap = ovl_mmap,
.fallocate = ovl_fallocate,
.fadvise = ovl_fadvise,
+#ifdef CONFIG_CACHESTAT_SYSCALL
+ .cachestat = ovl_cachestat,
+#endif
.flush = ovl_flush,
.splice_read = ovl_splice_read,
.splice_write = ovl_splice_write,
--
2.54.0