Changeset View
Changeset View
Standalone View
Standalone View
sys/kern/vfs_subr.c
Show First 20 Lines • Show All 3,305 Lines • ▼ Show 20 Lines | vget_finish(struct vnode *vp, int flags, enum vgetstate vs) | ||||
vget_finish_ref(vp, vs); | vget_finish_ref(vp, vs); | ||||
return (0); | return (0); | ||||
} | } | ||||
void | void | ||||
vget_finish_ref(struct vnode *vp, enum vgetstate vs) | vget_finish_ref(struct vnode *vp, enum vgetstate vs) | ||||
{ | { | ||||
int old; | int old; | ||||
struct mount *mp; | |||||
uint64_t *fsvninusep; | |||||
VNPASS(vs == VGET_HOLDCNT || vs == VGET_USECOUNT, vp); | VNPASS(vs == VGET_HOLDCNT || vs == VGET_USECOUNT, vp); | ||||
VNPASS(vp->v_holdcnt > 0, vp); | VNPASS(vp->v_holdcnt > 0, vp); | ||||
VNPASS(vs == VGET_HOLDCNT || vp->v_usecount > 0, vp); | VNPASS(vs == VGET_HOLDCNT || vp->v_usecount > 0, vp); | ||||
if (vs == VGET_USECOUNT) | if (vs == VGET_USECOUNT) | ||||
return; | return; | ||||
/* | /* | ||||
* We hold the vnode. If the usecount is 0 it will be utilized to keep | * We hold the vnode. If the usecount is 0 it will be utilized to keep | ||||
* the vnode around. Otherwise someone else lended their hold count and | * the vnode around. Otherwise someone else lended their hold count and | ||||
* we have to drop ours. | * we have to drop ours. | ||||
*/ | */ | ||||
old = atomic_fetchadd_int(&vp->v_usecount, 1); | old = atomic_fetchadd_int(&vp->v_usecount, 1); | ||||
VNASSERT(old >= 0, vp, ("%s: wrong use count %d", __func__, old)); | VNASSERT(old >= 0, vp, ("%s: wrong use count %d", __func__, old)); | ||||
if (old != 0) { | if (old != 0) { | ||||
#ifdef INVARIANTS | #ifdef INVARIANTS | ||||
old = atomic_fetchadd_int(&vp->v_holdcnt, -1); | old = atomic_fetchadd_int(&vp->v_holdcnt, -1); | ||||
VNASSERT(old > 1, vp, ("%s: wrong hold count %d", __func__, old)); | VNASSERT(old > 1, vp, ("%s: wrong hold count %d", __func__, old)); | ||||
#else | #else | ||||
refcount_release(&vp->v_holdcnt); | refcount_release(&vp->v_holdcnt); | ||||
#endif | #endif | ||||
} else { | |||||
mp = vp->v_mount; | |||||
if (NULL != mp) { | |||||
fsvninusep = mp->mnt_fsvninusep; | |||||
if (NULL != fsvninusep) | |||||
atomic_add_rel_64(fsvninusep, 1); | |||||
} | } | ||||
} | } | ||||
} | |||||
void | void | ||||
vref(struct vnode *vp) | vref(struct vnode *vp) | ||||
{ | { | ||||
enum vgetstate vs; | enum vgetstate vs; | ||||
CTR2(KTR_VFS, "%s: vp %p", __func__, vp); | CTR2(KTR_VFS, "%s: vp %p", __func__, vp); | ||||
vs = vget_prep(vp); | vs = vget_prep(vp); | ||||
▲ Show 20 Lines • Show All 139 Lines • ▼ Show 20 Lines | |||||
* happens with UFS which adds half-constructed vnodes to the hash, where they | * happens with UFS which adds half-constructed vnodes to the hash, where they | ||||
* can be found by other code. | * can be found by other code. | ||||
*/ | */ | ||||
static void | static void | ||||
vput_final(struct vnode *vp, enum vput_op func) | vput_final(struct vnode *vp, enum vput_op func) | ||||
{ | { | ||||
int error; | int error; | ||||
bool want_unlock; | bool want_unlock; | ||||
struct mount *mp; | |||||
uint64_t *fsvninusep; | |||||
CTR2(KTR_VFS, "%s: vp %p", __func__, vp); | CTR2(KTR_VFS, "%s: vp %p", __func__, vp); | ||||
VNPASS(vp->v_holdcnt > 0, vp); | VNPASS(vp->v_holdcnt > 0, vp); | ||||
mp = vp->v_mount; | |||||
/* | |||||
* The filesystem-local in-use vnode count is not incremented if | |||||
* insmntque() fails. vp->v_data is set to NULL in such the case. | |||||
*/ | |||||
if ((NULL != mp) && (NULL != vp->v_data)) { | |||||
fsvninusep = mp->mnt_fsvninusep; | |||||
if (NULL != fsvninusep) | |||||
atomic_subtract_rel_64(fsvninusep, 1); | |||||
} | |||||
VI_LOCK(vp); | VI_LOCK(vp); | ||||
/* | /* | ||||
* By the time we got here someone else might have transitioned | * By the time we got here someone else might have transitioned | ||||
* the count back to > 0. | * the count back to > 0. | ||||
*/ | */ | ||||
if (vp->v_usecount > 0) | if (vp->v_usecount > 0) | ||||
▲ Show 20 Lines • Show All 3,798 Lines • Show Last 20 Lines |