VOP_READ_PGCACHE(9)

πŸ“¦ version 15.1, in freebsd 14.5, freebsd 15.1, nixpkgs unstable

πŸ’… VOP_READ_PGCACHE(9) β€” from the Kernel Developer's Manual, section 9, bestie

Okay so real talk, this one is a kernel vnode op, and the vibe is chef's kiss because the whole point is "read a file, fast" β€” that's literally the NAME, no cap.


✨ NAME ✨

VOP_READ_PGCACHE β€” read a file, fast πŸ”₯


πŸ¦‹ SYNOPSIS πŸ¦‹

#include <sys/param.h>
#include <sys/vnode.h>
#include <sys/uio.h>

int
VOP_READ_PGCACHE(struct vnode *vp, struct uio *uio, int ioflag,
    struct ucred *cred);

🌸 DESCRIPTION 🌸

So this entry point reads the contents of a file, but like… the glow-up version. The whole intent is to hand you the data straight out of caches β€” the kind that don't require expensive operations or any disk IO. Iconic behavior, honestly.

For instance? If a filesystem uses the normal VM page cache and maintains v_object lifetime, it can use the vn_read_from_obj(9) helper to return data from the resident vp->v_object pages. Slay.

A filesystem tells everyone it supports VOP_READ_PGCACHE on a specific vnode by setting the VIRF_PGREAD flag in vp->v_irflag. That's the little "I'm built for this" badge πŸ’….

Now, important: the function does not need to satisfy the whole request β€” it also might choose to not provide any data at all. Lowkey valid. In these cases, the uio must be advanced by the amount of read data, VOP_READ_PGCACHE should return EJUSTRETURN, and VFS would handle the rest of the read operation using the VOP_READ(9). Like, it hands off the leftovers to its bestie, fr fr.

The VFS layer does the same deadlock avoidance for accessing userspace pages from VOP_READ_PGCACHE as for VOP_READ(9). Same safety energy, different function πŸ’–.

Vnode is not locked on the call entry and should not be locked on return. And listen β€” for a filesystem that requires the vnode lock to return any data, it does not make sense to implement VOP_READ_PGCACHE (and set the VIRF_PGREAD flag), since VFS arranges the call to VOP_READ(9) as needed anyway. Don't do all that for nothing, bestie 😭.

The arguments are:

  • vp β€” the vnode of the file. The main character of this whole operation 🫢
  • uio β€” the location of the data to be read. That's where the goodies go ✨
  • ioflag β€” various flags, see VOP_READ(9) for the list.
  • cred β€” the credentials of the caller. Gotta know who's asking πŸ‘‘
Heads up! VOP_READ_PGCACHE does not handle a non-zero ioflag argument. Like, zero or nothing, bestie πŸ’€

πŸ”’ LOCKS πŸ”’

The file should be referenced on entry and will still be referenced on exit. Rangelock covering the whole read range should be owned around the call. Hold onto it the whole time, no letting go mid-read πŸ™ˆ


⭐ RETURN VALUES ⭐

Zero is returned on success β€” when the whole request is satisfied, and no more data cannot be provided for it by any means. Full send, complete, ate πŸ’…

If more data can be returned, but VOP_READ_PGCACHE was unable to provide it, EJUSTRETURN must be returned. The uio records should be updated according to the partial operation done. (Partial credit is still credit ✨)

Otherwise an error code is returned, same as from VOP_READ(9). Copy that energy, copy that error 🌈


πŸŽ€ SEE ALSO πŸŽ€


That's the whole page, bestie β€” no skips, no summaries, we read the entire thing πŸ¦‹

Little sign-off from the source, for the record: this is the Debian version, dated February 28, 2021, filed under VOP_READ_PGCACHE(9). Periodt πŸ’œ

πŸ“¦ where this page comes from