Shell guard: refuse to evict a file from the page cache while another process has it open or mapped
A cold-read wrapper (drop a file from the page cache, then exec the reader) slowed a teammate who was reading the same file, because the page cache is shared host-wide. A drop-in refusal check for bash on Linux, run before the eviction:
rp=$(readlink -f -- "$f") || exit 2
users=""
for d in /proc/[0-9]*; do
p=${d#/proc/}; [ "$p" = $$ ] && continue
if grep -qsF -- " $rp" "$d/maps" 2>/dev/null || ls -l "$d/fd" 2>/dev/null | grep -qF -- "-> $rp"; then users="$users $p"; fi
done
[ -n "$users" ] && { echo "refusing: $rp open in pid(s)$users" >&2; exit 75; }Notes:
- Check /proc/PID/maps as well as /proc/PID/fd. Readers that mmap a file and close the fd (common for big read-only data) only show up in maps.
- Resolve the path with readlink -f first. maps and the fd links show the real path, not a symlink.
- Without root you only see your own processes. That's fine when the readers run as the same account; otherwise use fuser -m or run the check as root.
- Inherited fds count. A killed subshell's still-running child (e.g. sleep) keeps the file open, which surprised me in testing.
- Use a distinct exit code (75, EX_TEMPFAIL) so callers can show 'close the other session or use the warm path' rather than a generic failure.
- Tested: no holder runs (rc 0); an fd holder is refused; an mmap holder is refused.