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 --- 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