* Try to recycle a freed vnode. We abort if anyone picks up a reference * before we actually vgone(). This function must be called with the vnode * held to prevent the vnode from being returned to the free list midway * through vgone(). */
| 1575 | * through vgone(). |
| 1576 | */ |
| 1577 | static int |
| 1578 | vtryrecycle(struct vnode *vp) |
| 1579 | { |
| 1580 | struct mount *vnmp; |
| 1581 | |
| 1582 | CTR2(KTR_VFS, "%s: vp %p", __func__, vp); |
| 1583 | VNASSERT(vp->v_holdcnt, vp, |
| 1584 | ("vtryrecycle: Recycling vp %p without a reference.", vp)); |
| 1585 | /* |
| 1586 | * This vnode may found and locked via some other list, if so we |
| 1587 | * can't recycle it yet. |
| 1588 | */ |
| 1589 | if (VOP_LOCK(vp, LK_EXCLUSIVE | LK_NOWAIT) != 0) { |
| 1590 | CTR2(KTR_VFS, |
| 1591 | "%s: impossible to recycle, vp %p lock is already held", |
| 1592 | __func__, vp); |
| 1593 | vdrop(vp); |
| 1594 | return (EWOULDBLOCK); |
| 1595 | } |
| 1596 | /* |
| 1597 | * Don't recycle if its filesystem is being suspended. |
| 1598 | */ |
| 1599 | if (vn_start_write(vp, &vnmp, V_NOWAIT) != 0) { |
| 1600 | VOP_UNLOCK(vp); |
| 1601 | CTR2(KTR_VFS, |
| 1602 | "%s: impossible to recycle, cannot start the write for %p", |
| 1603 | __func__, vp); |
| 1604 | vdrop(vp); |
| 1605 | return (EBUSY); |
| 1606 | } |
| 1607 | /* |
| 1608 | * If we got this far, we need to acquire the interlock and see if |
| 1609 | * anyone picked up this vnode from another list. If not, we will |
| 1610 | * mark it with DOOMED via vgonel() so that anyone who does find it |
| 1611 | * will skip over it. |
| 1612 | */ |
| 1613 | VI_LOCK(vp); |
| 1614 | if (vp->v_usecount) { |
| 1615 | VOP_UNLOCK(vp); |
| 1616 | vdropl(vp); |
| 1617 | vn_finished_write(vnmp); |
| 1618 | CTR2(KTR_VFS, |
| 1619 | "%s: impossible to recycle, %p is already referenced", |
| 1620 | __func__, vp); |
| 1621 | return (EBUSY); |
| 1622 | } |
| 1623 | if (!VN_IS_DOOMED(vp)) { |
| 1624 | counter_u64_add(recycles_free_count, 1); |
| 1625 | vgonel(vp); |
| 1626 | } |
| 1627 | VOP_UNLOCK(vp); |
| 1628 | vdropl(vp); |
| 1629 | vn_finished_write(vnmp); |
| 1630 | return (0); |
| 1631 | } |
| 1632 | |
| 1633 | /* |
| 1634 | * Allocate a new vnode. |
no test coverage detected