Most frequently used vops boil down to checking SDT probes, doing the call and checking again. There is no vop_post/pre in their case. The check after the call prevents tail call optimisation from taking place. Instead, check once upfront. Kernels with debug or vops with vop_post still don't short circuit.
Generated code:
```int
VOP_LOCK1_APV(struct vop_vector *vop, struct vop_lock1_args *a)
{
int rc;
VNASSERT(a->a_gen.a_desc == &vop_lock1_desc, a->a_vp,
("Wrong a_desc in vop_lock1(%p, %p)", a->a_vp, a));
VNASSERT(vop != NULL, a->a_vp, ("No vop_lock1(%p, %p)", a->a_vp, a));
KTR_START4(KTR_VOP, "VOP", "VOP_LOCK1", (uintptr_t)a,
"vp:0x%jX", (uintptr_t)a->a_vp, "flags:0x%jX", a->a_flags, "file:0x%jX", a->a_file, "line:0x%jX", a->a_line);
vop_lock_pre(a);
if (__predict_true(!SDT_PROBES_ENABLED() && vop->vop_lock1 != NULL)) {
rc = vop->vop_lock1(a);
} else {
SDT_PROBE2(vfs, vop, vop_lock1, entry, a->a_vp, a);
if (vop->vop_lock1 != NULL)
rc = vop->vop_lock1(a);
else
rc = vop->vop_bypass(&a->a_gen);
SDT_PROBE3(vfs, vop, vop_lock1, return, a->a_vp, a, rc);
}
if (rc == 0) {
} else {
}
vop_lock_post(a, rc);
KTR_STOP4(KTR_VOP, "VOP", "VOP_LOCK1", (uintptr_t)a,
"vp:0x%jX", (uintptr_t)a->a_vp, "flags:0x%jX", a->a_flags, "file:0x%jX", a->a_file, "line:0x%jX", a->a_line);
return (rc);
}
```
I verified that at least on amd64 tail call is indeed used.