{
  "slug": "cachestat",
  "term": "cachestat",
  "aliases": [
    "cachestat(2)",
    "file page-cache statistics"
  ],
  "definition": "cachestat is a Linux system call that samples cached, dirty, writeback and eviction-related page counts for a file range.",
  "note": "Available since Linux 6.5, the interface takes a file descriptor, byte offset and length, and flags set to zero. Its counts can become stale before return; hugetlbfs is unsupported. [cachestat-man]\n\nCached, dirty and writeback are overlapping categories. Linux v6.16 increments nr_cache before independently inspecting dirty and writeback marks. Eviction counters sample retained metadata rather than a lifetime total; recently evicted uses a working-set test, not a fixed number of elapsed seconds. [filemap-616]\n\nFor positive, non-overflowing lengths, the v6.8 implementation selects pages through floor((off + len - 1) / page_size). A zero length selects the suffix, not an empty range. Five two-page, memory-locked trials on Linux 6.8.0-146-generic observed one cached page for offset 4095 and length 1, but two for length 2, with 4096-byte pages. These are bounded API observations, not cache-hit ratios or a workload benchmark. [filemap-68] [range-probe]\n\nLinux v6.16 permits disclosure for a writable descriptor, inode ownership or relevant capability, or a successful file write-permission check; otherwise it returns EPERM. The existing mincore interface can instead mask information with all-one bytes. [filemap-616] [mincore-source]\n\nThe NDSS 2026 study Eviction Notice reports that cachestat disclosure was restricted in February 2025 (CVE-2025-21691); its artifact appendix says the mitigated syscall no longer supports the paper's cross-user scenario. Check distribution backports, not only the kernel release label. The self-owned-file observations above do not assess cross-user exposure. [eviction-notice]",
  "advantages": [
    {
      "text": "Reports file-range dirty and writeback counts without first creating a user-space mapping.",
      "citationIds": [
        "filemap-616"
      ]
    }
  ],
  "limitations": [
    "Zero dirty pages do not certify an application's persistence protocol or replace checking synchronization errors.",
    "A sample cannot establish which process accessed a shared file or how many accesses hit its cached pages."
  ],
  "related": [
    "page-cache",
    "mincore",
    "process-io-accounting",
    "fsync",
    "working-set"
  ],
  "citations": [
    {
      "id": "cachestat-man",
      "title": "Linux man-pages 6.19: cachestat(2), API, history and snapshot caveat",
      "url": "https://man7.org/linux/man-pages/man2/cachestat.2.html",
      "accessed": "2026-11-06"
    },
    {
      "id": "filemap-616",
      "title": "Linux v6.16 mm/filemap.c: filemap_cachestat and cachestat syscall",
      "url": "https://raw.githubusercontent.com/torvalds/linux/v6.16/mm/filemap.c",
      "accessed": "2026-11-06"
    },
    {
      "id": "filemap-68",
      "title": "Linux v6.8 mm/filemap.c: cachestat range calculation and independent counter increments",
      "url": "https://raw.githubusercontent.com/torvalds/linux/v6.8/mm/filemap.c",
      "accessed": "2026-11-06"
    },
    {
      "id": "range-probe",
      "title": "Hesela: five self-owned, locked-file cachestat trials with source hashes and environment",
      "url": "https://hesela.dev/research/cachestat-range/results.json",
      "accessed": "2026-11-06"
    },
    {
      "id": "mincore-source",
      "title": "Linux v6.16 mm/mincore.c: can_do_mincore and all-one masking",
      "url": "https://raw.githubusercontent.com/torvalds/linux/v6.16/mm/mincore.c",
      "accessed": "2026-11-06"
    },
    {
      "id": "eviction-notice",
      "title": "Neela et al. Eviction Notice: Reviving and Advancing Page Cache Attacks. NDSS 2026; artifact appendix. DOI: 10.14722/ndss.2026.240006",
      "url": "https://gruss.cc/files/eviction-notice.pdf",
      "accessed": "2026-11-06"
    }
  ],
  "status": "shipping",
  "supersedes": [],
  "supersededBy": [],
  "firstSeen": null,
  "lastSeen": null,
  "updated": "2026-11-06",
  "provenance": [
    "API manual and version-pinned v6.8/v6.16 implementations reviewed 2026-11-06; the manual's inclusive-looking range notation differs from the actual len - 1 endpoint.",
    "Native experiment uses fresh two-page files and mlock; all five trials and error controls are preserved. Filesystem magic 0xef53 does not identify an ext-family version.",
    "No permission-bypass, side-channel, eviction, race, performance or power-loss experiment. Current permission behavior is sourced to v6.16, not inferred from the older test kernel."
  ]
}
