Currently sys_fchdir() doesn't need to use FREF()/FRELE() because it can't sleep until after vref(9). But since our goal is to have some syscalls manipulating 'struct file *' running without the KERNEL_LOCK(), we need to make sure the refcounts are always correct. That's why the diff below introduces a FREF() right after fd_getfile().
Ok? Index: kern/vfs_syscalls.c =================================================================== RCS file: /cvs/src/sys/kern/vfs_syscalls.c,v retrieving revision 1.277 diff -u -p -r1.277 vfs_syscalls.c --- kern/vfs_syscalls.c 28 Mar 2018 09:47:52 -0000 1.277 +++ kern/vfs_syscalls.c 2 Apr 2018 10:36:10 -0000 @@ -745,10 +745,14 @@ sys_fchdir(struct proc *p, void *v, regi if ((fp = fd_getfile(fdp, SCARG(uap, fd))) == NULL) return (EBADF); + FREF(fp); vp = fp->f_data; - if (fp->f_type != DTYPE_VNODE || vp->v_type != VDIR) + if (fp->f_type != DTYPE_VNODE || vp->v_type != VDIR) { + FRELE(fp, p); return (ENOTDIR); + } vref(vp); + FRELE(fp, p); vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, p); error = VOP_ACCESS(vp, VEXEC, p->p_ucred, p);