HomeFreeBSD

vfs: fix vnode reclaim races against getnwevnode

Description

vfs: fix vnode reclaim races against getnwevnode

All vnodes allocated by UMA are present on the global list used by
vnlru. getnewvnode modifies the state of the vnode (most notably
altering v_holdcnt) but never locks it. Moreover filesystems also
modify it in arbitrary manners sometimes before taking the vnode
lock or adding any other indicator that the vnode can be used.

Picking up such a vnode by vnlru would be problematic.

To that end there are 2 fixes:

  • vlrureclaim, not recycling v_holdcnt == 0 vnodes, takes the

interlock and verifies that v_mount has been set. It is an
invariant that the vnode lock is held by that point, providing
the necessary serialisation against locking after vhold.

  • vnlru_free_locked, only wanting to free v_holdcnt == 0 vnodes,

now makes sure to only transition the count 0->1 and newly allocated
vnodes start with v_holdcnt == VHOLD_NO_SMR. getnewvnode will only
transition VHOLD_NO_SMR->1 once more making the hold fail

Tested by: pho

Details

Provenance
mjgAuthored on
Parents
rS367088: refcount: make it atomic-clean
Branches
Unknown
Tags
Unknown