FBSD: Add osi_fbsd_checkinuse
[openafs.git] / src / afs / FBSD / osi_vcache.c
index 07c3327..8f4df57 100644 (file)
 #endif
 
 int
-osi_TryEvictVCache(struct vcache *avc, int *slept, int defersleep) {
-
-    /*
-     * essentially all we want to do here is check that the
-     * vcache is not in use, then call vgone() (which will call
-     * inactive and reclaim as needed).  This requires some
-     * kind of complicated locking, which we already need to implement
-     * for FlushVCache, so just call that routine here and check
-     * its return value for whether the vcache was evict-able.
-     */
-    if (osi_VM_FlushVCache(avc, slept) != 0)
+osi_TryEvictVCache(struct vcache *avc, int *slept, int defersleep)
+{
+    struct vnode *vp;
+    int code;
+
+    vp = AFSTOV(avc);
+
+    if (!VI_TRYLOCK(vp))
        return 0;
-    else
+    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;
 }
 
 struct vcache *