svn commit: r348737 - head/sys/kern
Rodney W. Grimes
freebsd at gndrsh.dnsmgr.net
Thu Jun 6 17:35:25 UTC 2019
> Author: asomers
> Date: Thu Jun 6 15:04:50 2019
> New Revision: 348737
> URL: https://svnweb.freebsd.org/changeset/base/348737
>
> Log:
> 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.
Should not this all be wrapped in some #ifdef or other protection,
is it really a good idea to have this on every single box running
FreeBSD?
>
> Reviewed by: kib
> MFC after: 2 weeks
> Sponsored by: The FreeBSD Foundation
> Differential Revision: https://reviews.freebsd.org/D20519
>
> Modified:
> head/sys/kern/vfs_subr.c
>
> Modified: head/sys/kern/vfs_subr.c
> ==============================================================================
> --- head/sys/kern/vfs_subr.c Thu Jun 6 12:44:43 2019 (r348736)
> +++ head/sys/kern/vfs_subr.c Thu Jun 6 15:04:50 2019 (r348737)
> @@ -50,6 +50,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>
> @@ -338,6 +339,93 @@ 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;
> + int error;
> + int fd;
> +
> + if (req->newptr == NULL)
> + return (EBADF);
> +
> + error = sysctl_handle_int(oidp, &fd, 0, req);
> + if (error != 0)
> + return (error);
> + error = getvnode(curthread, fd, &cap_fcntl_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;
>
>
--
Rod Grimes rgrimes at freebsd.org
More information about the svn-src-all
mailing list