Diff below adds a FREF()/FRELE() dance after fd_getfile() in sys_fcntl(). This will help upcoing diff moving FREF() inside fd_getfile().
ok? Index: kern/kern_descrip.c =================================================================== RCS file: /cvs/src/sys/kern/kern_descrip.c,v retrieving revision 1.150 diff -u -p -r1.150 kern_descrip.c --- kern/kern_descrip.c 12 Apr 2018 10:30:18 -0000 1.150 +++ kern/kern_descrip.c 16 Apr 2018 08:13:53 -0000 @@ -344,7 +344,7 @@ sys_fcntl(struct proc *p, void *v, regis } */ *uap = v; int fd = SCARG(uap, fd); struct filedesc *fdp = p->p_fd; - struct file *fp; + struct file *fp, *fp2; struct vnode *vp; int i, tmp, newmin, flg = F_POSIX; struct flock fl; @@ -530,7 +530,10 @@ restart: goto out; } - if (fp != fd_getfile(fdp, fd)) { + fp2 = fd_getfile(fdp, fd); + if (fp2 != NULL) + FREF(fp2); + if (fp != fp2) { /* * We have lost the race with close() or dup2(); * unlock, pretend that we've won the race and that @@ -542,6 +545,8 @@ restart: VOP_ADVLOCK(vp, fdp, F_UNLCK, &fl, F_POSIX); fl.l_type = F_UNLCK; } + if (fp2 != NULL) + FRELE(fp2, p); goto out;