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-head mailing list