-current build on amd64 fails in libkvm:

===> libkvm
cc -O2 -pipe -g -D_LIBKVM   -c -fpic -DPIC /usr/src/lib/libkvm/kvm_proc2.c -o 
kvm_proc2.so
cc -O2 -pipe -g -D_LIBKVM   -c -p /usr/src/lib/libkvm/kvm_proc2.c -o 
kvm_proc2.po
cc -O2 -pipe -g -D_LIBKVM   -c /usr/src/lib/libkvm/kvm_proc2.c -o kvm_proc2.o
cc -O2 -pipe -g -D_LIBKVM   -c -fpic -DPIC /usr/src/lib/libkvm/kvm_proc.c -o 
kvm_proc.so
cc -O2 -pipe -g -D_LIBKVM   -c -p /usr/src/lib/libkvm/kvm_proc.c -o kvm_proc.po
cc -O2 -pipe -g -D_LIBKVM   -c /usr/src/lib/libkvm/kvm_proc.c -o kvm_proc.o
cc -O2 -pipe -g -D_LIBKVM   -c -fpic -DPIC /usr/src/lib/libkvm/kvm_getloadavg.c 
-o kvm_getloadavg.so
cc -O2 -pipe -g -D_LIBKVM   -c -p /usr/src/lib/libkvm/kvm_getloadavg.c -o 
kvm_getloadavg.po
cc -O2 -pipe -g -D_LIBKVM   -c /usr/src/lib/libkvm/kvm_getloadavg.c -o 
kvm_getloadavg.o
cc -O2 -pipe -g -D_LIBKVM   -c -fpic -DPIC /usr/src/lib/libkvm/kvm.c -o kvm.so
cc -O2 -pipe -g -D_LIBKVM   -c -p /usr/src/lib/libkvm/kvm.c -o kvm.po
cc -O2 -pipe -g -D_LIBKVM   -c /usr/src/lib/libkvm/kvm.c -o kvm.o
cc -O2 -pipe -g -D_LIBKVM   -c -p /usr/src/lib/libkvm/kvm_amd64.c -o 
kvm_amd64.po
cc -O2 -pipe -g -D_LIBKVM   -c -fpic -DPIC /usr/src/lib/libkvm/kvm_amd64.c -o 
kvm_amd64.so
cc -O2 -pipe -g -D_LIBKVM   -c /usr/src/lib/libkvm/kvm_amd64.c -o kvm_amd64.o
cc -O2 -pipe -g -D_LIBKVM   -c -p /usr/src/lib/libkvm/kvm_ntfs.c -o kvm_ntfs.po
cc -O2 -pipe -g -D_LIBKVM   -c -fpic -DPIC /usr/src/lib/libkvm/kvm_ntfs.c -o 
kvm_ntfs.so
cc -O2 -pipe -g -D_LIBKVM   -c /usr/src/lib/libkvm/kvm_ntfs.c -o kvm_ntfs.o
cc -O2 -pipe -g -D_LIBKVM   -c -fpic -DPIC /usr/src/lib/libkvm/kvm_udf.c -o 
kvm_udf.so
cc -O2 -pipe -g -D_LIBKVM   -c -p /usr/src/lib/libkvm/kvm_udf.c -o kvm_udf.po
cc -O2 -pipe -g -D_LIBKVM   -c /usr/src/lib/libkvm/kvm_udf.c -o kvm_udf.o
cc -O2 -pipe -g -D_LIBKVM   -c -fpic -DPIC /usr/src/lib/libkvm/kvm_cd9660.c -o 
kvm_cd9660.so
cc -O2 -pipe -g -D_LIBKVM   -c -p /usr/src/lib/libkvm/kvm_cd9660.c -o 
kvm_cd9660.po
cc -O2 -pipe -g -D_LIBKVM   -c /usr/src/lib/libkvm/kvm_cd9660.c -o kvm_cd9660.o
cc -O2 -pipe -g -D_LIBKVM   -c -p /usr/src/lib/libkvm/kvm_file2.c -o 
kvm_file2.po
cc -O2 -pipe -g -D_LIBKVM   -c /usr/src/lib/libkvm/kvm_file2.c -o kvm_file2.o
cc -O2 -pipe -g -D_LIBKVM   -c -fpic -DPIC /usr/src/lib/libkvm/kvm_file2.c -o 
kvm_file2.so
mandoc -Tlint -Wfatal /usr/src/lib/libkvm/kvm.3
/usr/src/lib/libkvm/kvm_file2.c: In function 'kvm_deadfile_byid':
/usr/src/lib/libkvm/kvm_file2.c:356: error: 'struct filedesc0' has no member 
named 'fd_dfiles'
/usr/src/lib/libkvm/kvm_file2.c:357: error: 'struct filedesc' has no member 
named 'fd_ofiles'
/usr/src/lib/libkvm/kvm_file2.c:358: error: 'struct filedesc' has no member 
named 'fd_ofiles'
/usr/src/lib/libkvm/kvm_file2.c:358: error: 'struct filedesc0' has no member 
named 'fd_dfiles'
/usr/src/lib/libkvm/kvm_file2.c:359: error: 'struct filedesc' has no member 
named 'fd_ofileflags'
/usr/src/lib/libkvm/kvm_file2.c:359: error: 'struct filedesc0' has no member 
named 'fd_dfileflags'
/usr/src/lib/libkvm/kvm_file2.c:369: error: 'struct filedesc' has no member 
named 'fd_ofiles'
/usr/src/lib/libkvm/kvm_file2.c:375: error: 'struct filedesc' has no member 
named 'fd_ofiles'
/usr/src/lib/libkvm/kvm_file2.c:376: error: 'struct filedesc' has no member 
named 'fd_ofileflags'
/usr/src/lib/libkvm/kvm_file2.c:438: error: 'struct filedesc' has no member 
named 'fd_ofiles'
/usr/src/lib/libkvm/kvm_file2.c: In function 'fill_file':
/usr/src/lib/libkvm/kvm_file2.c:693: error: 'struct filedesc' has no member 
named 'fd_ofileflags'
mandoc -Tlint -Wfatal /usr/src/lib/libkvm/kvm_dump.3
/usr/src/lib/libkvm/kvm_file2.c: In function 'kvm_deadfile_byid':
*** Error 1 in target 'kvm_file2.o'
/usr/src/lib/libkvm/kvm_file2.c:356: error: 'struct filedesc0' has no member 
named 'fd_dfiles'
/usr/src/lib/libkvm/kvm_file2.c:357: error: 'struct filedesc' has no member 
named 'fd_ofiles'
/usr/src/lib/libkvm/kvm_file2.c:358: error: 'struct filedesc' has no member 
named 'fd_ofiles'
/usr/src/lib/libkvm/kvm_file2.c:358: error: 'struct filedesc0' has no member 
named 'fd_dfiles'
/usr/src/lib/libkvm/kvm_file2.c:359: error: 'struct filedesc' has no member 
named 'fd_ofileflags'
/usr/src/lib/libkvm/kvm_file2.c:359: error: 'struct filedesc0' has no member 
named 'fd_dfileflags'
/usr/src/lib/libkvm/kvm_file2.c:369: error: 'struct filedesc' has no member 
named 'fd_ofiles'
/usr/src/lib/libkvm/kvm_file2.c:375: error: 'struct filedesc' has no member 
named 'fd_ofiles'
/usr/src/lib/libkvm/kvm_file2.c:376: error: 'struct filedesc' has no member 
named 'fd_ofileflags'
/usr/src/lib/libkvm/kvm_file2.c: In function 'kvm_deadfile_byid':
/usr/src/lib/libkvm/kvm_file2.c:356: error: 'struct filedesc0' has no member 
named 'fd_dfiles'
/usr/src/lib/libkvm/kvm_file2.c:357: error: 'struct filedesc' has no member 
named 'fd_ofiles'
/usr/src/lib/libkvm/kvm_file2.c:358: error: 'struct filedesc' has no member 
named 'fd_ofiles'
/usr/src/lib/libkvm/kvm_file2.c:358: error: 'struct filedesc0' has no member 
named 'fd_dfiles'
/usr/src/lib/libkvm/kvm_file2.c:359: error: 'struct filedesc' has no member 
named 'fd_ofileflags'
/usr/src/lib/libkvm/kvm_file2.c:359: error: 'struct filedesc0' has no member 
named 'fd_dfileflags'
/usr/src/lib/libkvm/kvm_file2.c:369: error: 'struct filedesc' has no member 
named 'fd_ofiles'
/usr/src/lib/libkvm/kvm_file2.c:375: error: 'struct filedesc' has no member 
named 'fd_ofiles'
/usr/src/lib/libkvm/kvm_file2.c:376: error: 'struct filedesc' has no member 
named 'fd_ofileflags'
/usr/src/lib/libkvm/kvm_file2.c:438: error: 'struct filedesc' has no member 
named 'fd_ofiles'
/usr/src/lib/libkvm/kvm_file2.c:438: error: 'struct filedesc' has no member 
named 'fd_ofiles'
/usr/src/lib/libkvm/kvm_file2.c: In function 'fill_file':
/usr/src/lib/libkvm/kvm_file2.c:693: error: 'struct filedesc' has no member 
named 'fd_ofileflags'
/usr/src/lib/libkvm/kvm_file2.c: In function 'fill_file':
/usr/src/lib/libkvm/kvm_file2.c:693: error: 'struct filedesc' has no member 
named 'fd_ofileflags'
*** Error 1 in target 'kvm_file2.so'
*** Error 1 in target 'kvm_file2.po'
*** Error 1 in lib/libkvm (<bsd.lib.mk>:52 'kvm_file2.po': @cc -O2 -pipe -g 
-D_LIBKVM   -c -p /usr/src/lib/libkvm/kvm_file2.c -o kvm_file2.p...)
*** Error 1 (<bsd.lib.mk>:58 'kvm_file2.so': @cc -O2 -pipe -g -D_LIBKVM   -c 
-fpic -DPIC /usr/src/lib/libkvm/kvm_file2.c -o kvm_file2.so.o)
*** Error 1 (<bsd.lib.mk>:40 'kvm_file2.o': @cc -O2 -pipe -g -D_LIBKVM   -c 
/usr/src/lib/libkvm/kvm_file2.c  -o kvm_file2.o.o)
*** Error 2 in lib (<bsd.subdir.mk>:48 'all')
*** Error 2 in /usr/src (Makefile:79 'build')
      506.55 real       487.24 user       367.82 sys


On Sun, Sep 07, 2014 at 03:19:23PM -0400, Jean-Philippe Ouellet wrote:
> On Wed, Sep 03, 2014 at 03:31:50PM -0500, Kent R. Spillner wrote:
> > Need to re-roll for -current?
> 
> Yep, sorry. I knew the the dup3 changes would break it when I saw them
> go in but I've been busy with classes and stuff.
> 
> Here's a new version. This one considerably less tested than previous
> versions, I just made sure it still built and that build built itself
> too.
> 
> Capsicum is still blocking on this patch (or one like it).
> 
> Any/all feedback welcome.
> 
> On Thu, Jul 10, 2014 at 04:13:38PM -0400, Jean-Philippe Ouellet wrote:
> > This diff adds another struct between filedesc and file to store
> > process-local per-descriptor information. Currently, the only thing in
> > this struct is the file pointer and some flags, however I have another
> > patch on top of this that adds capsicum capabilities to it. (And
> > another that uses mallocarray(9) where applicable. One thing at a time.)
> > 
> > The data is currently stored in one big allocation with all the file *s
> > in front, and all the flags after. When that allocation grows, there are
> > two copies and two zeroings. This is fine when we only have two fields
> > (fd_ofiles and fd_ofileflags), but adding more is ugly.
> > 
> > Instead, I propose we have a struct for each file descriptor table entry
> > (filedescent) and put the files, flags, and capabilities in that.
> > 
> > The immediate impact is some memory waste due to padding (3 or 7 bytes
> > per file descriptor, depending on the arch), however once capabilities
> > are added it will be negligible. I discussed it with matthew@ and
> > guenther@ and concluded this was the saner way. For what it's worth,
> > FreeBSD and NetBSD have done the same thing.
> > 
> > I've been running different versions of this for about a month or so,
> > no issues noticed so far.
> > 
> > A similar earlier version was reviewed by matthew@ and guenther@.
> 
> 
> Index: sys/filedesc.h
> ===================================================================
> RCS file: /cvs/src/sys/sys/filedesc.h,v
> retrieving revision 1.28
> diff -u -p -r1.28 filedesc.h
> --- sys/filedesc.h    15 May 2014 03:52:25 -0000      1.28
> +++ sys/filedesc.h    7 Sep 2014 19:04:20 -0000
> @@ -34,9 +34,6 @@
>  
>  #include <sys/rwlock.h>
>  /*
> - * This structure is used for the management of descriptors.  It may be
> - * shared by multiple processes.
> - *
>   * A process is initially started out with NDFILE descriptors stored within
>   * this structure, selected to be enough for typical applications based on
>   * the historical limit of 20 open files (and the usage of descriptors by
> @@ -56,22 +53,33 @@
>  #define NDHISLOTS(x) (NDREDUCE(NDREDUCE(x)))
>  #define NDLOSLOTS(x) (NDHISLOTS(x) << NDENTRYSHIFT)
>  
> +/*
> + * File wrapper for per-process per-file data.
> + */
> +struct filedescent {
> +     struct  file *fde_file;         /* file structure for open file */
> +     char    fde_flags;              /* process-local file flags */
> +};
> +
> +/*
> + * This structure is used for the management of descriptors.  It may be
> + * shared by multiple processes.
> + */
>  struct filedesc {
> -     struct  file **fd_ofiles;       /* file structures for open files */
> -     char    *fd_ofileflags;         /* per-process open file flags */
> +     struct  filedescent *fd_fdents; /* per-process file wrappers */
>       struct  vnode *fd_cdir;         /* current directory */
>       struct  vnode *fd_rdir;         /* root directory */
>       int     fd_nfiles;              /* number of open files allocated */
>       int     fd_openfd;              /* number of files currently open */
>       u_int   *fd_himap;              /* each bit points to 32 fds */
>       u_int   *fd_lomap;              /* bitmap of free fds */
> -     int     fd_lastfile;            /* high-water mark of fd_ofiles */
> +     int     fd_lastfile;            /* high-water mark of fd_fdents */
>       int     fd_freefile;            /* approx. next free file */
>       u_short fd_cmask;               /* mask for file creation */
>       u_short fd_refcnt;              /* reference count */
>       struct rwlock fd_lock;          /* lock for the file descs; must be */
> -                                     /* held when writing to fd_ofiles, */
> -                                     /* fd_ofileflags, or fd_{hi,lo}map */
> +                                     /* held when writing to fd_fdents */
> +                                     /* or fd_{hi,lo}map */
>  
>       int     fd_knlistsize;          /* size of knlist */
>       struct  klist *fd_knlist;       /* list of attached knotes */
> @@ -91,8 +99,7 @@ struct filedesc0 {
>        * These arrays are used when the number of open files is
>        * <= NDFILE, and are then pointed to by the pointers above.
>        */
> -     struct  file *fd_dfiles[NDFILE];
> -     char    fd_dfileflags[NDFILE];
> +     struct  filedescent fd_dfdents[NDFILE];
>       /*
>        * There arrays are used when the number of open files is
>        * <= 1024, and are then pointed to by the pointers above.
> Index: kern/kern_descrip.c
> ===================================================================
> RCS file: /cvs/src/sys/kern/kern_descrip.c,v
> retrieving revision 1.113
> diff -u -p -r1.113 kern_descrip.c
> --- kern/kern_descrip.c       31 Aug 2014 01:42:36 -0000      1.113
> +++ kern/kern_descrip.c       7 Sep 2014 19:04:20 -0000
> @@ -124,7 +124,7 @@ int
>  find_last_set(struct filedesc *fd, int last)
>  {
>       int off, i;
> -     struct file **ofiles = fd->fd_ofiles;
> +     struct filedescent *fdents = fd->fd_fdents;
>       u_int *bitmap = fd->fd_lomap;
>  
>       off = (last - 1) >> NDENTRYSHIFT;
> @@ -138,7 +138,7 @@ find_last_set(struct filedesc *fd, int l
>       if (i >= last)
>               i = last - 1;
>  
> -     while (i > 0 && ofiles[i] == NULL)
> +     while (i > 0 && fdents[i].fde_file == NULL)
>               i--;
>       return i;
>  }
> @@ -183,7 +183,11 @@ fd_getfile(struct filedesc *fdp, int fd)
>  {
>       struct file *fp;
>  
> -     if ((u_int)fd >= fdp->fd_nfiles || (fp = fdp->fd_ofiles[fd]) == NULL)
> +     if ((u_int)fd >= fdp->fd_nfiles)
> +             return (NULL);
> +
> +     fp = fdp->fd_fdents[fd].fde_file;
> +     if (fp == NULL)
>               return (NULL);
>  
>       if (!FILE_IS_USABLE(fp))
> @@ -305,7 +309,7 @@ restart:
>       /* finishdup() does FRELE */
>       error = finishdup(p, fp, old, new, retval, 1);
>       if (!error && flags & O_CLOEXEC)
> -             fdp->fd_ofileflags[new] |= UF_EXCLOSE;
> +             fdp->fd_fdents[new].fde_flags |= UF_EXCLOSE;
>  
>  out:
>       fdpunlock(fdp);
> @@ -359,22 +363,22 @@ restart:
>                       error = finishdup(p, fp, fd, i, retval, 0);
>  
>                       if (!error && SCARG(uap, cmd) == F_DUPFD_CLOEXEC)
> -                             fdp->fd_ofileflags[i] |= UF_EXCLOSE;
> +                             fdp->fd_fdents[i].fde_flags |= UF_EXCLOSE;
>               }
>  
>               fdpunlock(fdp);
>               return (error);
>  
>       case F_GETFD:
> -             *retval = fdp->fd_ofileflags[fd] & UF_EXCLOSE ? 1 : 0;
> +             *retval = fdp->fd_fdents[fd].fde_flags & UF_EXCLOSE ? 1 : 0;
>               break;
>  
>       case F_SETFD:
>               fdplock(fdp);
>               if ((long)SCARG(uap, arg) & 1)
> -                     fdp->fd_ofileflags[fd] |= UF_EXCLOSE;
> +                     fdp->fd_fdents[fd].fde_flags |= UF_EXCLOSE;
>               else
> -                     fdp->fd_ofileflags[fd] &= ~UF_EXCLOSE;
> +                     fdp->fd_fdents[fd].fde_flags &= ~UF_EXCLOSE;
>               fdpunlock(fdp);
>               break;
>  
> @@ -549,6 +553,7 @@ finishdup(struct proc *p, struct file *f
>  {
>       struct file *oldfp;
>       struct filedesc *fdp = p->p_fd;
> +     struct filedescent *fdents = fdp->fd_fdents;
>  
>       fdpassertlocked(fdp);
>       if (fp->f_count == LONG_MAX-2) {
> @@ -560,12 +565,12 @@ finishdup(struct proc *p, struct file *f
>        * Don't fd_getfile here. We want to closef LARVAL files and
>        * closef can deal with that.
>        */
> -     oldfp = fdp->fd_ofiles[new];
> +     oldfp = fdents[new].fde_file;
>       if (oldfp != NULL)
>               FREF(oldfp);
>  
> -     fdp->fd_ofiles[new] = fp;
> -     fdp->fd_ofileflags[new] = fdp->fd_ofileflags[old] & ~UF_EXCLOSE;
> +     fdents[new].fde_file = fp;
> +     fdents[new].fde_flags = fdents[old].fde_flags & ~UF_EXCLOSE;
>       fp->f_count++;
>       FRELE(fp, p);
>       if (dup2 && oldfp == NULL)
> @@ -585,7 +590,7 @@ void
>  fdremove(struct filedesc *fdp, int fd)
>  {
>       fdpassertlocked(fdp);
> -     fdp->fd_ofiles[fd] = NULL;
> +     fdp->fd_fdents[fd].fde_file = NULL;
>       fd_unused(fdp, fd);
>  }
>  
> @@ -593,7 +598,8 @@ int
>  fdrelease(struct proc *p, int fd)
>  {
>       struct filedesc *fdp = p->p_fd;
> -     struct file **fpp, *fp;
> +     struct filedescent *fde;
> +     struct file *fp;
>  
>       fdpassertlocked(fdp);
>  
> @@ -601,12 +607,12 @@ fdrelease(struct proc *p, int fd)
>        * Don't fd_getfile here. We want to closef LARVAL files and closef
>        * can deal with that.
>        */
> -     fpp = &fdp->fd_ofiles[fd];
> -     fp = *fpp;
> +     fde = &fdp->fd_fdents[fd];
> +     fp = fde->fde_file;
>       if (fp == NULL)
>               return (EBADF);
>       FREF(fp);
> -     *fpp = NULL;
> +     fde->fde_file = NULL;
>       fd_unused(fdp, fd);
>       if (fd < fdp->fd_knlistsize)
>               knote_fdclose(p, fd);
> @@ -732,7 +738,7 @@ fdalloc(struct proc *p, int want, int *r
>       /*
>        * Search for a free descriptor starting at the higher
>        * of want or fd_freefile.  If that fails, consider
> -      * expanding the ofile array.
> +      * expanding the fdents array.
>        */
>  restart:
>       lim = min((int)p->p_rlimit[RLIMIT_NOFILE].rlim_cur, maxfiles);
> @@ -760,7 +766,7 @@ restart:
>                       if (want <= fdp->fd_freefile)
>                               fdp->fd_freefile = i;
>                       *result = i;
> -                     fdp->fd_ofileflags[i] = 0;
> +                     fdp->fd_fdents[i].fde_flags = 0;
>                       return (0);
>               }
>       }
> @@ -775,9 +781,8 @@ fdexpand(struct proc *p)
>  {
>       struct filedesc *fdp = p->p_fd;
>       int nfiles;
> -     size_t copylen;
> -     struct file **newofile;
> -     char *newofileflags;
> +     size_t copylen, newsize;
> +     struct filedescent *newfdents;
>       u_int *newhimap, *newlomap;
>  
>       fdpassertlocked(fdp);
> @@ -790,23 +795,22 @@ fdexpand(struct proc *p)
>       else
>               nfiles = 2 * fdp->fd_nfiles;
>  
> -     newofile = mallocarray(nfiles, OFILESIZE, M_FILEDESC, M_WAITOK);
> -     newofileflags = (char *) &newofile[nfiles];
> +     if (nfiles < fdp->fd_nfiles)
> +             panic("fdp->fd_nfiles overflow");
>  
> -     /*
> -      * Copy the existing ofile and ofileflags arrays
> -      * and zero the new portion of each array.
> -      */
> -     copylen = sizeof(struct file *) * fdp->fd_nfiles;
> -     memcpy(newofile, fdp->fd_ofiles, copylen);
> -     memset((char *)newofile + copylen, 0,
> -         nfiles * sizeof(struct file *) - copylen);
> -     copylen = sizeof(char) * fdp->fd_nfiles;
> -     memcpy(newofileflags, fdp->fd_ofileflags, copylen);
> -     memset(newofileflags + copylen, 0, nfiles * sizeof(char) - copylen);
> +     newfdents = mallocarray(nfiles, sizeof(struct filedescent),
> +         M_FILEDESC, M_WAITOK);
> +
> +     /* If mallocarray() works, these won't overflow. */
> +     newsize = nfiles * sizeof(struct filedescent);
> +     copylen = fdp->fd_nfiles * sizeof(struct filedescent);
> +
> +     /* Copy existing fdents and zero new ones. */
> +     memcpy(newfdents, fdp->fd_fdents, copylen);
> +     memset((char *)newfdents + copylen, 0, newsize - copylen);
>  
>       if (fdp->fd_nfiles > NDFILE)
> -             free(fdp->fd_ofiles, M_FILEDESC, 0);
> +             free(fdp->fd_fdents, M_FILEDESC, 0);
>  
>       if (NDHISLOTS(nfiles) > NDHISLOTS(fdp->fd_nfiles)) {
>               newhimap = mallocarray(NDHISLOTS(nfiles), sizeof(u_int),
> @@ -831,8 +835,7 @@ fdexpand(struct proc *p)
>               fdp->fd_himap = newhimap;
>               fdp->fd_lomap = newlomap;
>       }
> -     fdp->fd_ofiles = newofile;
> -     fdp->fd_ofileflags = newofileflags;
> +     fdp->fd_fdents = newfdents;
>       fdp->fd_nfiles = nfiles;        
>  }
>  
> @@ -869,12 +872,12 @@ restart:
>       nfiles++;
>       fp = pool_get(&file_pool, PR_WAITOK|PR_ZERO);
>       fp->f_iflags = FIF_LARVAL;
> -     if ((fq = p->p_fd->fd_ofiles[0]) != NULL) {
> +     if ((fq = p->p_fd->fd_fdents[0].fde_file) != NULL) {
>               LIST_INSERT_AFTER(fq, fp, f_list);
>       } else {
>               LIST_INSERT_HEAD(&filehead, fp, f_list);
>       }
> -     p->p_fd->fd_ofiles[i] = fp;
> +     p->p_fd->fd_fdents[i].fde_file = fp;
>       fp->f_count = 1;
>       fp->f_cred = p->p_ucred;
>       crhold(fp->f_cred);
> @@ -901,8 +904,7 @@ fdinit(void)
>       /* Create the file descriptor table. */
>       newfdp->fd_fd.fd_refcnt = 1;
>       newfdp->fd_fd.fd_cmask = cmask;
> -     newfdp->fd_fd.fd_ofiles = newfdp->fd_dfiles;
> -     newfdp->fd_fd.fd_ofileflags = newfdp->fd_dfileflags;
> +     newfdp->fd_fd.fd_fdents = newfdp->fd_dfdents;
>       newfdp->fd_fd.fd_nfiles = NDFILE;
>       newfdp->fd_fd.fd_himap = newfdp->fd_dhimap;
>       newfdp->fd_fd.fd_lomap = newfdp->fd_dlomap;
> @@ -931,7 +933,7 @@ struct filedesc *
>  fdcopy(struct process *pr)
>  {
>       struct filedesc *newfdp, *fdp = pr->ps_fd;
> -     struct file **fpp;
> +     struct file *fp;
>       int i;
>  
>       fdplock(fdp);
> @@ -951,9 +953,7 @@ fdcopy(struct process *pr)
>        * in use.
>        */
>       if (newfdp->fd_lastfile < NDFILE) {
> -             newfdp->fd_ofiles = ((struct filedesc0 *) newfdp)->fd_dfiles;
> -             newfdp->fd_ofileflags =
> -                 ((struct filedesc0 *) newfdp)->fd_dfileflags;
> +             newfdp->fd_fdents = ((struct filedesc0 *) newfdp)->fd_dfdents;
>               i = NDFILE;
>       } else {
>               /*
> @@ -964,8 +964,8 @@ fdcopy(struct process *pr)
>               i = newfdp->fd_nfiles;
>               while (i >= 2 * NDEXTENT && i > newfdp->fd_lastfile * 2)
>                       i /= 2;
> -             newfdp->fd_ofiles = mallocarray(i, OFILESIZE, M_FILEDESC, 
> M_WAITOK);
> -             newfdp->fd_ofileflags = (char *) &newfdp->fd_ofiles[i];
> +             newfdp->fd_fdents = mallocarray(i, sizeof(struct filedescent),
> +                 M_FILEDESC, M_WAITOK);
>       }
>       if (NDHISLOTS(i) <= NDHISLOTS(NDFILE)) {
>               newfdp->fd_himap =
> @@ -979,16 +979,16 @@ fdcopy(struct process *pr)
>                   M_FILEDESC, M_WAITOK);
>       }
>       newfdp->fd_nfiles = i;
> -     memcpy(newfdp->fd_ofiles, fdp->fd_ofiles, i * sizeof(struct file *));
> -     memcpy(newfdp->fd_ofileflags, fdp->fd_ofileflags, i * sizeof(char));
> +     memcpy(newfdp->fd_fdents, fdp->fd_fdents,
> +         i * sizeof(struct filedescent));
>       memcpy(newfdp->fd_himap, fdp->fd_himap, NDHISLOTS(i) * sizeof(u_int));
>       memcpy(newfdp->fd_lomap, fdp->fd_lomap, NDLOSLOTS(i) * sizeof(u_int));
>       fdpunlock(fdp);
>  
>       fdplock(newfdp);
> -     fpp = newfdp->fd_ofiles;
> -     for (i = 0; i <= newfdp->fd_lastfile; i++, fpp++)
> -             if (*fpp != NULL) {
> +     for (i = 0; i <= newfdp->fd_lastfile; i++) {
> +             fp = newfdp->fd_fdents[i].fde_file;
> +             if (fp != NULL) {
>                       /*
>                        * XXX Gruesome hack. If count gets too high, fail
>                        * to copy an fd, since fdcopy()'s callers do not
> @@ -997,13 +997,14 @@ fdcopy(struct process *pr)
>                        * tied to the process that opened them to enforce
>                        * their internal consistency, so close them here.
>                        */
> -                     if ((*fpp)->f_count == LONG_MAX-2 ||
> -                         (*fpp)->f_type == DTYPE_KQUEUE ||
> -                         (*fpp)->f_type == DTYPE_SYSTRACE)
> +                     if (fp->f_count == LONG_MAX-2 ||
> +                         fp->f_type == DTYPE_KQUEUE ||
> +                         fp->f_type == DTYPE_SYSTRACE)
>                               fdremove(newfdp, i);
>                       else
> -                             (*fpp)->f_count++;
> +                             fp->f_count++;
>               }
> +     }
>  
>       /* finish cleaning up kq bits */
>       if (newfdp->fd_knlistsize != -1) {
> @@ -1029,8 +1030,8 @@ fdfree(struct proc *p)
>  
>       if (--fdp->fd_refcnt > 0)
>               return;
> -     fpp = fdp->fd_ofiles;
> -     for (i = fdp->fd_lastfile; i >= 0; i--, fpp++) {
> +     for (i = fdp->fd_lastfile; i >= 0; i--) {
> +             fpp = &fdp->fd_fdents[i].fde_file;
>               fp = *fpp;
>               if (fp != NULL) {
>                       FREF(fp);
> @@ -1040,7 +1041,7 @@ fdfree(struct proc *p)
>       }
>       p->p_fd = NULL;
>       if (fdp->fd_nfiles > NDFILE)
> -             free(fdp->fd_ofiles, M_FILEDESC, 0);
> +             free(fdp->fd_fdents, M_FILEDESC, 0);
>       if (NDHISLOTS(fdp->fd_nfiles) > NDHISLOTS(NDFILE)) {
>               free(fdp->fd_himap, M_FILEDESC, 0);
>               free(fdp->fd_lomap, M_FILEDESC, 0);
> @@ -1214,6 +1215,7 @@ int
>  dupfdopen(struct filedesc *fdp, int indx, int dfd, int mode)
>  {
>       struct file *wfp;
> +     struct filedescent *fdentp;
>  
>       fdpassertlocked(fdp);
>  
> @@ -1247,9 +1249,10 @@ dupfdopen(struct filedesc *fdp, int indx
>       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[dfd] & ~UF_EXCLOSE);
> +     fdentp = &fdp->fd_fdents[indx];
> +     fdentp->fde_file = wfp;
> +     fdentp->fde_flags &= UF_EXCLOSE;
> +     fdentp->fde_flags |= fdp->fd_fdents[dfd].fde_flags & ~UF_EXCLOSE;
>       wfp->f_count++;
>       fd_used(fdp, indx);
>       return (0);
> @@ -1266,7 +1269,7 @@ fdcloseexec(struct proc *p)
>  
>       fdplock(fdp);
>       for (fd = 0; fd <= fdp->fd_lastfile; fd++)
> -             if (fdp->fd_ofileflags[fd] & UF_EXCLOSE)
> +             if (fdp->fd_fdents[fd].fde_flags & UF_EXCLOSE)
>                       (void) fdrelease(p, fd);
>       fdpunlock(fdp);
>  }
> Index: kern/kern_sysctl.c
> ===================================================================
> RCS file: /cvs/src/sys/kern/kern_sysctl.c,v
> retrieving revision 1.263
> diff -u -p -r1.263 kern_sysctl.c
> --- kern/kern_sysctl.c        4 Sep 2014 19:14:47 -0000       1.263
> +++ kern/kern_sysctl.c        7 Sep 2014 19:04:21 -0000
> @@ -1167,8 +1167,11 @@ fill_file(struct kinfo_file *kf, struct 
>               strlcpy(kf->p_comm, pr->ps_mainproc->p_comm,
>                   sizeof(kf->p_comm));
>       }
> -     if (fdp != NULL)
> -             kf->fd_ofileflags = fdp->fd_ofileflags[fd];
> +     if (fdp != NULL) {
> +             KASSERT(fd < fdp->fd_nfiles);
> +             KASSERT(fdp->fd_fdents[fd].fde_file != NULL);
> +             kf->fd_ofileflags = fdp->fd_fdents[fd].fde_flags;
> +     }
>  }
>  
>  /*
> @@ -1260,7 +1263,7 @@ sysctl_file(int *name, u_int namelen, ch
>                       if (pr->ps_tracevp)
>                               FILLIT(NULL, NULL, KERN_FILE_TRACE, 
> pr->ps_tracevp, pr);
>                       for (i = 0; i < fdp->fd_nfiles; i++) {
> -                             if ((fp = fdp->fd_ofiles[i]) == NULL)
> +                             if ((fp = fdp->fd_fdents[i].fde_file) == NULL)
>                                       continue;
>                               if (!FILE_IS_USABLE(fp))
>                                       continue;
> @@ -1288,7 +1291,7 @@ sysctl_file(int *name, u_int namelen, ch
>                       if (pr->ps_tracevp)
>                               FILLIT(NULL, NULL, KERN_FILE_TRACE, 
> pr->ps_tracevp, pr);
>                       for (i = 0; i < fdp->fd_nfiles; i++) {
> -                             if ((fp = fdp->fd_ofiles[i]) == NULL)
> +                             if ((fp = fdp->fd_fdents[i].fde_file) == NULL)
>                                       continue;
>                               if (!FILE_IS_USABLE(fp))
>                                       continue;
> Index: kern/sys_generic.c
> ===================================================================
> RCS file: /cvs/src/sys/kern/sys_generic.c,v
> retrieving revision 1.92
> diff -u -p -r1.92 sys_generic.c
> --- kern/sys_generic.c        13 Jul 2014 15:48:41 -0000      1.92
> +++ kern/sys_generic.c        7 Sep 2014 19:04:21 -0000
> @@ -414,9 +414,9 @@ sys_ioctl(struct proc *p, void *v, regis
>       case FIOCLEX:
>               fdplock(fdp);
>               if (com == FIONCLEX)
> -                     fdp->fd_ofileflags[SCARG(uap, fd)] &= ~UF_EXCLOSE;
> +                     fdp->fd_fdents[SCARG(uap, fd)].fde_flags &= ~UF_EXCLOSE;
>               else
> -                     fdp->fd_ofileflags[SCARG(uap, fd)] |= UF_EXCLOSE;
> +                     fdp->fd_fdents[SCARG(uap, fd)].fde_flags |= UF_EXCLOSE;
>               fdpunlock(fdp);
>               return (0);
>       }
> Index: kern/sys_pipe.c
> ===================================================================
> RCS file: /cvs/src/sys/kern/sys_pipe.c,v
> retrieving revision 1.66
> diff -u -p -r1.66 sys_pipe.c
> --- kern/sys_pipe.c   31 Aug 2014 01:42:36 -0000      1.66
> +++ kern/sys_pipe.c   7 Sep 2014 19:04:21 -0000
> @@ -160,8 +160,8 @@ dopipe(struct proc *p, int *ufds, int fl
>       wf->f_ops = &pipeops;
>  
>       if (flags & O_CLOEXEC) {
> -             fdp->fd_ofileflags[fds[0]] |= UF_EXCLOSE;
> -             fdp->fd_ofileflags[fds[1]] |= UF_EXCLOSE;
> +             fdp->fd_fdents[fds[0]].fde_flags |= UF_EXCLOSE;
> +             fdp->fd_fdents[fds[1]].fde_flags |= UF_EXCLOSE;
>       }
>  
>       rpipe->pipe_peer = wpipe;
> Index: kern/uipc_syscalls.c
> ===================================================================
> RCS file: /cvs/src/sys/kern/uipc_syscalls.c,v
> retrieving revision 1.92
> diff -u -p -r1.92 uipc_syscalls.c
> --- kern/uipc_syscalls.c      31 Aug 2014 01:42:36 -0000      1.92
> +++ kern/uipc_syscalls.c      7 Sep 2014 19:04:21 -0000
> @@ -84,7 +84,7 @@ sys_socket(struct proc *p, void *v, regi
>       fdplock(fdp);
>       error = falloc(p, &fp, &fd);
>       if (type & SOCK_CLOEXEC)
> -             fdp->fd_ofileflags[fd] |= UF_EXCLOSE;
> +             fdp->fd_fdents[fd].fde_flags |= UF_EXCLOSE;
>       fdpunlock(fdp);
>       if (error != 0)
>               goto out;
> @@ -241,7 +241,7 @@ redo:
>       fdplock(fdp);
>       error = falloc(p, &fp, &tmpfd);
>       if (flags & SOCK_CLOEXEC)
> -             fdp->fd_ofileflags[tmpfd] |= UF_EXCLOSE;
> +             fdp->fd_fdents[tmpfd].fde_flags |= UF_EXCLOSE;
>       fdpunlock(fdp);
>       if (error != 0) {
>               /*
> @@ -401,8 +401,8 @@ sys_socketpair(struct proc *p, void *v, 
>       fp2->f_ops = &socketops;
>       fp2->f_data = so2;
>       if (flags & SOCK_CLOEXEC) {
> -             fdp->fd_ofileflags[sv[0]] |= UF_EXCLOSE;
> -             fdp->fd_ofileflags[sv[1]] |= UF_EXCLOSE;
> +             fdp->fd_fdents[sv[0]].fde_flags |= UF_EXCLOSE;
> +             fdp->fd_fdents[sv[1]].fde_flags |= UF_EXCLOSE;
>       }
>       if ((error = soconnect2(so1, so2)) != 0)
>               goto free4;
> Index: kern/uipc_usrreq.c
> ===================================================================
> RCS file: /cvs/src/sys/kern/uipc_usrreq.c,v
> retrieving revision 1.77
> diff -u -p -r1.77 uipc_usrreq.c
> --- kern/uipc_usrreq.c        31 Aug 2014 01:42:36 -0000      1.77
> +++ kern/uipc_usrreq.c        7 Sep 2014 19:04:21 -0000
> @@ -743,10 +743,10 @@ restart:
>                * fdalloc() works properly.. We finalize it all
>                * in the loop below.
>                */
> -             p->p_fd->fd_ofiles[fdp[i]] = *rp++;
> +             p->p_fd->fd_fdents[fdp[i]].fde_file = *rp++;
>  
>               if (flags & MSG_CMSG_CLOEXEC)
> -                     p->p_fd->fd_ofileflags[fdp[i]] |= UF_EXCLOSE;
> +                     p->p_fd->fd_fdents[fdp[i]].fde_flags |= UF_EXCLOSE;
>       }
>  
>       /*
> Index: kern/vfs_syscalls.c
> ===================================================================
> RCS file: /cvs/src/sys/kern/vfs_syscalls.c,v
> retrieving revision 1.208
> diff -u -p -r1.208 vfs_syscalls.c
> --- kern/vfs_syscalls.c       12 Jul 2014 18:43:32 -0000      1.208
> +++ kern/vfs_syscalls.c       7 Sep 2014 19:04:21 -0000
> @@ -849,7 +849,7 @@ doopenat(struct proc *p, int fd, const c
>               goto out;
>       flags = FFLAGS(oflags);
>       if (flags & O_CLOEXEC)
> -             fdp->fd_ofileflags[indx] |= UF_EXCLOSE;
> +             fdp->fd_fdents[indx].fde_flags |= UF_EXCLOSE;
>  
>       cmode = ((mode &~ fdp->fd_cmask) & ALLPERMS) &~ S_ISTXT;
>       NDINITAT(&nd, LOOKUP, FOLLOW, UIO_USERSPACE, fd, path, p);
> @@ -1008,7 +1008,7 @@ sys_fhopen(struct proc *p, void *v, regi
>               goto bad;
>       }
>       if (flags & O_CLOEXEC)
> -             fdp->fd_ofileflags[indx] |= UF_EXCLOSE;
> +             fdp->fd_fdents[indx].fde_flags |= UF_EXCLOSE;
>  
>       if ((error = copyin(SCARG(uap, fhp), &fh, sizeof(fhandle_t))) != 0)
>               goto bad;

Reply via email to