> 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                                                 rgri...@freebsd.org
_______________________________________________
svn-src-head@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"

Reply via email to