int osi_TryEvictVCache(struct vcache *avc, int *slept, int defersleep) { struct vnode *vp; int code; vp = AFSTOV(avc); if (!VI_TRYLOCK(vp)) return 0; code = osi_fbsd_checkinuse(avc); if (code != 0) { VI_UNLOCK(vp); return 0; } if ((vp->v_iflag & VI_DOOMED) != 0) { VI_UNLOCK(vp); return 1; } /* must hold the vnode before calling vgone() * This code largely copied from vfs_subr.c:vlrureclaim() */ vholdl(vp); AFS_GUNLOCK(); *slept = 1; /* use the interlock while locking, so no one else can DOOM this */ ma_vn_lock(vp, LK_INTERLOCK|LK_EXCLUSIVE|LK_RETRY, curthread); vgone(vp); MA_VOP_UNLOCK(vp, 0, curthread); vdrop(vp); AFS_GLOCK(); return 1; }
/* Try to discard pages, in order to recycle a vcache entry. * * We also make some sanity checks: ref count, open count, held locks. * * We also do some non-VM-related chores, such as releasing the cred pointer * (for AIX and Solaris) and releasing the gnode (for AIX). * * Locking: afs_xvcache lock is held. If it is dropped and re-acquired, * *slept should be set to warn the caller. * * Formerly, afs_xvcache was dropped and re-acquired for Solaris, but now it * is not dropped and re-acquired for any platform. It may be that *slept is * therefore obsolescent. * */ int osi_VM_FlushVCache(struct vcache *avc, int *slept) { struct vnode *vp; int code; vp = AFSTOV(avc); if (!VI_TRYLOCK(vp)) return EBUSY; code = osi_fbsd_checkinuse(avc); if (code) { VI_UNLOCK(vp); return code; } /* must hold the vnode before calling cache_purge() * This code largely copied from vfs_subr.c:vlrureclaim() */ vholdl(vp); VI_UNLOCK(vp); AFS_GUNLOCK(); cache_purge(vp); AFS_GLOCK(); vdrop(vp); return 0; }