Date: Sun, 23 Jun 2019 15:09:39 +0000 (UTC) From: Alan Somers <asomers@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-11@freebsd.org Subject: svn commit: r349309 - stable/11/sys/kern Message-ID: <201906231509.x5NF9ddR026569@repo.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: asomers Date: Sun Jun 23 15:09:39 2019 New Revision: 349309 URL: https://svnweb.freebsd.org/changeset/base/349309 Log: MFC r348737: Add a testing facility to manually reclaim a vnode Add the debug.try_reclaim_vnode sysctl. When a pathname is written to it, it will be reclaimed, as long as it isn't already or doomed. The purpose is to gain test coverage for vnode reclamation, which is otherwise hard to achieve. Add the debug.ftry_reclaim_vnode sysctl. It does the same thing, except that its argument is a file descriptor instead of a pathname. Reviewed by: kib Sponsored by: The FreeBSD Foundation Differential Revision: https://reviews.freebsd.org/D20519 Modified: stable/11/sys/kern/vfs_subr.c Directory Properties: stable/11/ (props changed) Modified: stable/11/sys/kern/vfs_subr.c ============================================================================== --- stable/11/sys/kern/vfs_subr.c Sun Jun 23 14:49:30 2019 (r349308) +++ stable/11/sys/kern/vfs_subr.c Sun Jun 23 15:09:39 2019 (r349309) @@ -49,6 +49,7 @@ __FBSDID("$FreeBSD$"); #include <sys/systm.h> #include <sys/bio.h> #include <sys/buf.h> +#include <sys/capsicum.h> #include <sys/condvar.h> #include <sys/conf.h> #include <sys/counter.h> @@ -331,6 +332,95 @@ SYSCTL_ULONG(_kern, OID_AUTO, minvnodes, CTLFLAG_RW, static int vnlru_nowhere; SYSCTL_INT(_debug, OID_AUTO, vnlru_nowhere, CTLFLAG_RW, &vnlru_nowhere, 0, "Number of times the vnlru process ran without success"); + +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) { + /* + * This vnode is being recycled. Return != 0 to let the caller + * know that the sysctl had no effect. Return EAGAIN because a + * subsequent call will likely succeed (since namei will create + * a new vnode if necessary) + */ + error = EAGAIN; + goto putvnode; + } + + counter_u64_add(recycles_count, 1); + vgone(vp); +putvnode: + NDFREE(&nd, 0); +out: + free(buf, M_TEMP); + return (error); +} + +static int +sysctl_ftry_reclaim_vnode(SYSCTL_HANDLER_ARGS) +{ + struct thread *td = curthread; + struct vnode *vp; + struct file *fp; + cap_rights_t rights; + int error; + int fd; + + if (req->newptr == NULL) + return (EBADF); + + error = sysctl_handle_int(oidp, &fd, 0, req); + if (error != 0) + return (error); + cap_rights_init(&rights, CAP_FCNTL); + error = getvnode(curthread, fd, &rights, &fp); + if (error != 0) + return (error); + vp = fp->f_vnode; + + error = vn_lock(vp, LK_EXCLUSIVE); + if (error != 0) + goto drop; + + counter_u64_add(recycles_count, 1); + vgone(vp); + VOP_UNLOCK(vp, 0); +drop: + fdrop(fp, td); + 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"); +SYSCTL_PROC(_debug, OID_AUTO, ftry_reclaim_vnode, + CTLTYPE_INT | CTLFLAG_MPSAFE | CTLFLAG_WR, NULL, 0, + sysctl_ftry_reclaim_vnode, "I", + "Try to reclaim a vnode by its file descriptor"); /* Shift count for (uintptr_t)vp to initialize vp->v_hash. */ static int vnsz2log;
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201906231509.x5NF9ddR026569>