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);
 

Reply via email to