* Remove all entries from and to a particular vnode. */
| 2621 | * Remove all entries from and to a particular vnode. |
| 2622 | */ |
| 2623 | static void |
| 2624 | cache_purge_impl(struct vnode *vp) |
| 2625 | { |
| 2626 | struct cache_freebatch batch; |
| 2627 | struct namecache *ncp; |
| 2628 | struct mtx *vlp, *vlp2; |
| 2629 | |
| 2630 | TAILQ_INIT(&batch); |
| 2631 | vlp = VP2VNODELOCK(vp); |
| 2632 | vlp2 = NULL; |
| 2633 | mtx_lock(vlp); |
| 2634 | retry: |
| 2635 | while (!LIST_EMPTY(&vp->v_cache_src)) { |
| 2636 | ncp = LIST_FIRST(&vp->v_cache_src); |
| 2637 | if (!cache_zap_locked_vnode_kl2(ncp, vp, &vlp2)) |
| 2638 | goto retry; |
| 2639 | TAILQ_INSERT_TAIL(&batch, ncp, nc_dst); |
| 2640 | } |
| 2641 | while (!TAILQ_EMPTY(&vp->v_cache_dst)) { |
| 2642 | ncp = TAILQ_FIRST(&vp->v_cache_dst); |
| 2643 | if (!cache_zap_locked_vnode_kl2(ncp, vp, &vlp2)) |
| 2644 | goto retry; |
| 2645 | TAILQ_INSERT_TAIL(&batch, ncp, nc_dst); |
| 2646 | } |
| 2647 | ncp = vp->v_cache_dd; |
| 2648 | if (ncp != NULL) { |
| 2649 | KASSERT(ncp->nc_flag & NCF_ISDOTDOT, |
| 2650 | ("lost dotdot link")); |
| 2651 | if (!cache_zap_locked_vnode_kl2(ncp, vp, &vlp2)) |
| 2652 | goto retry; |
| 2653 | TAILQ_INSERT_TAIL(&batch, ncp, nc_dst); |
| 2654 | } |
| 2655 | KASSERT(vp->v_cache_dd == NULL, ("incomplete purge")); |
| 2656 | mtx_unlock(vlp); |
| 2657 | if (vlp2 != NULL) |
| 2658 | mtx_unlock(vlp2); |
| 2659 | cache_free_batch(&batch); |
| 2660 | } |
| 2661 | |
| 2662 | /* |
| 2663 | * Opportunistic check to see if there is anything to do. |
no test coverage detected