Index: sys/kern/vfs_subr.c =================================================================== --- sys/kern/vfs_subr.c +++ sys/kern/vfs_subr.c @@ -339,6 +339,56 @@ SYSCTL_INT(_debug, OID_AUTO, vnlru_nowhere, CTLFLAG_RW, &vnlru_nowhere, 0, "Number of times the vnlru process ran without success"); +#ifdef INVARIANTS +static int +sysctl_try_reclaim_vnode(SYSCTL_HANDLER_ARGS) +{ + struct vnode *vp; + struct nameidata nd; + char *buf; + unsigned long ndflags; + int error; + + if (req->newptr == NULL) + return (EINVAL); + + if (req->newlen > PATH_MAX) + return (E2BIG); + + buf = malloc(PATH_MAX + 1, M_TEMP, M_WAITOK); + error = SYSCTL_IN(req, buf, req->newlen); + if (error != 0) + goto out; + + buf[req->newlen] = '\0'; + + ndflags = LOCKLEAF| NOFOLLOW | AUDITVNODE1 | NOCACHE | SAVENAME; + NDINIT(&nd, LOOKUP, ndflags, UIO_SYSSPACE, buf, curthread); + if ((error = namei(&nd)) != 0) + goto out; + vp = nd.ni_vp; + + if ((vp->v_iflag & VI_DOOMED) != 0) { + error = EBUSY; + goto putvnode; + } + + vhold(vp); + counter_u64_add(recycles_count, 1); + vgone(vp); + vdrop(vp); +putvnode: + NDFREE(&nd, 0); +out: + free(buf, M_TEMP); + return (error); +} + +SYSCTL_PROC(_debug, OID_AUTO, try_reclaim_vnode, + CTLTYPE_STRING | CTLFLAG_MPSAFE | CTLFLAG_WR, NULL, 0, + sysctl_try_reclaim_vnode, "A", "Try to reclaim a vnode by its pathname"); +#endif /* INVARIANTS */ + /* Shift count for (uintptr_t)vp to initialize vp->v_hash. */ static int vnsz2log;