On Tue, Apr 03, 2018 at 04:43:17PM +0200, Martin Pieuchot wrote:
> Here's another refactoring to properly reference count a 'struct file *'
> just after calling fd_getfile().
> 
> Instead of incrementing `f_count' by hand, give the current reference
> to finishdup() like it is done in other places in the same file.
> 
> Ok?

OK bluhm@

> Index: kern/kern_descrip.c
> ===================================================================
> RCS file: /cvs/src/sys/kern/kern_descrip.c,v
> retrieving revision 1.144
> diff -u -p -r1.144 kern_descrip.c
> --- kern/kern_descrip.c       3 Apr 2018 09:00:03 -0000       1.144
> +++ kern/kern_descrip.c       3 Apr 2018 13:30:47 -0000
> @@ -1274,6 +1274,8 @@ dupfdopen(struct proc *p, int indx, int 
>       struct filedesc *fdp = p->p_fd;
>       int dupfd = p->p_dupfd;
>       struct file *wfp;
> +     int error, flags;
> +     register_t dummy;
>  
>       fdpassertlocked(fdp);
>  
> @@ -1297,24 +1299,26 @@ dupfdopen(struct proc *p, int indx, int 
>        */
>       if ((wfp = fd_getfile(fdp, dupfd)) == NULL)
>               return (EBADF);
> +     FREF(wfp);
>  
>       /*
>        * Check that the mode the file is being opened for is a
>        * subset of the mode of the existing descriptor.
>        */
> -     if (((mode & (FREAD|FWRITE)) | wfp->f_flag) != wfp->f_flag)
> +     if (((mode & (FREAD|FWRITE)) | wfp->f_flag) != wfp->f_flag) {
> +             FRELE(wfp, p);
>               return (EACCES);
> -     if (wfp->f_count == LONG_MAX-2)
> -             return (EDEADLK);
> +     }
>  
> -     fdp->fd_ofiles[indx] = wfp;
> -     fdp->fd_ofileflags[indx] = (fdp->fd_ofileflags[indx] & UF_EXCLOSE) |
> -         (fdp->fd_ofileflags[dupfd] & ~UF_EXCLOSE);
> +     flags = fdp->fd_ofileflags[indx] & UF_EXCLOSE;
>       if (ISSET(p->p_p->ps_flags, PS_PLEDGE))
> -             fdp->fd_ofileflags[indx] |= UF_PLEDGED;
> -     wfp->f_count++;
> -     fd_used(fdp, indx);
> -     return (0);
> +             flags |= UF_PLEDGED;
> +
> +     /* finishdup() does FRELE */
> +     error = finishdup(p, wfp, dupfd, indx, &dummy, 1);
> +     if (error == 0)
> +             fdp->fd_ofileflags[indx] |= flags;
> +     return (error);
>  }
>  
>  /*

Reply via email to