Allow vdrop() of a vnode not yet on the per-mount list after r306512.
The old code allowed calling vdrop() before insmntque() to place the vnode back onto the freelist for later recycling. Some downstream consumers may rely on this support. Normally insmntque() failing is fine since is uses vgone() and immediately frees the vnode rather than attempting to add it to the freelist if vdrop() were used instead. Also assert that vhold() cannot be used on such a vnode. Reviewed by: kib, cem, markj Sponsored by: Dell EMC Isilon Differential Revision: https://reviews.freebsd.org/D12126
This commit is contained in:
parent
dfcd3e3b61
commit
79ee71cc38
@ -2861,6 +2861,8 @@ _vhold(struct vnode *vp, bool locked)
|
||||
* Remove a vnode from the free list, mark it as in use,
|
||||
* and put it on the active list.
|
||||
*/
|
||||
VNASSERT(vp->v_mount != NULL, vp,
|
||||
("_vhold: vnode not on per mount vnode list"));
|
||||
mp = vp->v_mount;
|
||||
mtx_lock(&mp->mnt_listmtx);
|
||||
if ((vp->v_mflag & VMP_TMPMNTFREELIST) != 0) {
|
||||
@ -2935,21 +2937,35 @@ _vdrop(struct vnode *vp, bool locked)
|
||||
if ((vp->v_iflag & VI_OWEINACT) == 0) {
|
||||
vp->v_iflag &= ~VI_ACTIVE;
|
||||
mp = vp->v_mount;
|
||||
mtx_lock(&mp->mnt_listmtx);
|
||||
if (active) {
|
||||
TAILQ_REMOVE(&mp->mnt_activevnodelist, vp,
|
||||
if (mp != NULL) {
|
||||
mtx_lock(&mp->mnt_listmtx);
|
||||
if (active) {
|
||||
TAILQ_REMOVE(&mp->mnt_activevnodelist,
|
||||
vp, v_actfreelist);
|
||||
mp->mnt_activevnodelistsize--;
|
||||
}
|
||||
TAILQ_INSERT_TAIL(&mp->mnt_tmpfreevnodelist,
|
||||
vp, v_actfreelist);
|
||||
mp->mnt_tmpfreevnodelistsize++;
|
||||
vp->v_iflag |= VI_FREE;
|
||||
vp->v_mflag |= VMP_TMPMNTFREELIST;
|
||||
VI_UNLOCK(vp);
|
||||
if (mp->mnt_tmpfreevnodelistsize >=
|
||||
mnt_free_list_batch)
|
||||
vnlru_return_batch_locked(mp);
|
||||
mtx_unlock(&mp->mnt_listmtx);
|
||||
} else {
|
||||
VNASSERT(active == 0, vp,
|
||||
("vdropl: active vnode not on per mount "
|
||||
"vnode list"));
|
||||
mtx_lock(&vnode_free_list_mtx);
|
||||
TAILQ_INSERT_TAIL(&vnode_free_list, vp,
|
||||
v_actfreelist);
|
||||
mp->mnt_activevnodelistsize--;
|
||||
freevnodes++;
|
||||
vp->v_iflag |= VI_FREE;
|
||||
VI_UNLOCK(vp);
|
||||
mtx_unlock(&vnode_free_list_mtx);
|
||||
}
|
||||
TAILQ_INSERT_TAIL(&mp->mnt_tmpfreevnodelist, vp,
|
||||
v_actfreelist);
|
||||
mp->mnt_tmpfreevnodelistsize++;
|
||||
vp->v_iflag |= VI_FREE;
|
||||
vp->v_mflag |= VMP_TMPMNTFREELIST;
|
||||
VI_UNLOCK(vp);
|
||||
if (mp->mnt_tmpfreevnodelistsize >= mnt_free_list_batch)
|
||||
vnlru_return_batch_locked(mp);
|
||||
mtx_unlock(&mp->mnt_listmtx);
|
||||
} else {
|
||||
VI_UNLOCK(vp);
|
||||
counter_u64_add(free_owe_inact, 1);
|
||||
|
Loading…
Reference in New Issue
Block a user