More changes to improve kern_descrip.c.

- Avoid atomics in more places.
- Remove the per-descriptor mutex, and just use filedesc_t::fd_lock.
  It was only being used to synchronize close, and in any case we needed
  to take fd_lock to free the descriptor slot.
- Optimize certain paths for the <NDFDFILE case.
- Sprinkle more comments and assertions.
- Cache more stuff in filedesc_t.
- Fix numerous minor bugs spotted along the way.
- Restructure how the open files array is maintained, for clarity and so
  that we can eliminate the membar_consumer() call in fd_getfile().  This is
  mostly syntactic sugar; the main functional change is that fd_nfiles now
  lives alongside the open file array.

Some measurements with libmicro:

- simple file syscalls are like close() are between 1 to 10% faster.
- some nice improvements, e.g. poll(1000) which is ~50% faster.
This commit is contained in:
ad 2009-05-24 21:41:25 +00:00
parent 13573078f8
commit d991fcb3b6
21 changed files with 480 additions and 442 deletions

View File

@ -1,4 +1,4 @@
/* $NetBSD: sock.c,v 1.14 2008/05/20 07:08:06 darrenr Exp $ */ /* $NetBSD: sock.c,v 1.15 2009/05/24 21:41:44 ad Exp $ */
/* /*
* sock.c (C) 1995-1998 Darren Reed * sock.c (C) 1995-1998 Darren Reed
@ -329,12 +329,21 @@ struct tcpiphdr *ti;
t = NULL; t = NULL;
o = (struct file **)calloc(1, sizeof(*o) * (fd->fd_lastfile + 1)); o = (struct file **)calloc(1, sizeof(*o) * (fd->fd_lastfile + 1));
#if defined(__NetBSD_Version__) && __NetBSD__Version__ >= 599001200
if (KMCPY(o, fd->fd_ofiles, (fd->fd_lastfile + 1) * sizeof(*o)) == -1) if (KMCPY(o, fd->fd_ofiles, (fd->fd_lastfile + 1) * sizeof(*o)) == -1)
{ {
fprintf(stderr, "read(%#lx,%#lx,%lu) - u_ofile - failed\n", fprintf(stderr, "read(%#lx,%#lx,%lu) - u_ofile - failed\n",
(u_long)fd->fd_ofiles, (u_long)o, (u_long)sizeof(*o)); (u_long)fd->fd_ofiles, (u_long)o, (u_long)sizeof(*o));
goto finderror; goto finderror;
} }
#else
if (KMCPY(o, &fd->fd_dt->dt_ff, (fd->fd_lastfile + 1) * sizeof(*o)) == -1)
{
fprintf(stderr, "read(%#lx,%#lx,%lu) - u_ofile - failed\n",
(u_long)fd->fd_dt->dt_ff, (u_long)o, (u_long)sizeof(*o));
goto finderror;
}
#endif
f = (struct file *)calloc(1, sizeof(*f)); f = (struct file *)calloc(1, sizeof(*f));
if (KMCPY(f, o[tfd], sizeof(*f)) == -1) if (KMCPY(f, o[tfd], sizeof(*f)) == -1)
{ {

View File

@ -1,4 +1,4 @@
/* $NetBSD: netbsd32_ioctl.c,v 1.41 2008/07/02 16:45:20 matt Exp $ */ /* $NetBSD: netbsd32_ioctl.c,v 1.42 2009/05/24 21:41:25 ad Exp $ */
/* /*
* Copyright (c) 1998, 2001 Matthew R. Green * Copyright (c) 1998, 2001 Matthew R. Green
@ -31,7 +31,7 @@
*/ */
#include <sys/cdefs.h> #include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: netbsd32_ioctl.c,v 1.41 2008/07/02 16:45:20 matt Exp $"); __KERNEL_RCSID(0, "$NetBSD: netbsd32_ioctl.c,v 1.42 2009/05/24 21:41:25 ad Exp $");
#include <sys/param.h> #include <sys/param.h>
#include <sys/systm.h> #include <sys/systm.h>
@ -349,7 +349,7 @@ printf("netbsd32_ioctl(%d, %x, %x): %s group %c base %d len %d\n",
goto out; goto out;
} }
ff = fdp->fd_ofiles[SCARG(uap, fd)]; ff = fdp->fd_dt->dt_ff[SCARG(uap, fd)];
switch (com = SCARG(uap, com)) { switch (com = SCARG(uap, com)) {
case FIOCLEX: case FIOCLEX:
ff->ff_exclose = true; ff->ff_exclose = true;

View File

@ -1,4 +1,4 @@
/* $NetBSD: svr4_filio.c,v 1.22 2008/07/02 16:45:20 matt Exp $ */ /* $NetBSD: svr4_filio.c,v 1.23 2009/05/24 21:41:25 ad Exp $ */
/*- /*-
* Copyright (c) 1994, 2008 The NetBSD Foundation, Inc. * Copyright (c) 1994, 2008 The NetBSD Foundation, Inc.
@ -30,7 +30,7 @@
*/ */
#include <sys/cdefs.h> #include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: svr4_filio.c,v 1.22 2008/07/02 16:45:20 matt Exp $"); __KERNEL_RCSID(0, "$NetBSD: svr4_filio.c,v 1.23 2009/05/24 21:41:25 ad Exp $");
#include <sys/param.h> #include <sys/param.h>
#include <sys/proc.h> #include <sys/proc.h>
@ -73,7 +73,7 @@ svr4_fil_ioctl(file_t *fp, struct lwp *l, register_t *retval, int fd, u_long cmd
if ((fp = fd_getfile(fd)) == NULL) if ((fp = fd_getfile(fd)) == NULL)
return EBADF; return EBADF;
ff = fdp->fd_ofiles[fd]; ff = fdp->fd_dt->dt_ff[fd];
switch (cmd) { switch (cmd) {
case SVR4_FIOCLEX: case SVR4_FIOCLEX:
ff->ff_exclose = true; ff->ff_exclose = true;

View File

@ -1,7 +1,7 @@
/* $NetBSD: svr4_32_filio.c,v 1.16 2008/07/02 16:45:20 matt Exp $ */ /* $NetBSD: svr4_32_filio.c,v 1.17 2009/05/24 21:41:25 ad Exp $ */
/*- /*-
* Copyright (c) 1994, 2008 The NetBSD Foundation, Inc. * Copyright (c) 1994, 2008, 2009 The NetBSD Foundation, Inc.
* All rights reserved. * All rights reserved.
* *
* This code is derived from software contributed to The NetBSD Foundation * This code is derived from software contributed to The NetBSD Foundation
@ -30,7 +30,7 @@
*/ */
#include <sys/cdefs.h> #include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: svr4_32_filio.c,v 1.16 2008/07/02 16:45:20 matt Exp $"); __KERNEL_RCSID(0, "$NetBSD: svr4_32_filio.c,v 1.17 2009/05/24 21:41:25 ad Exp $");
#include <sys/param.h> #include <sys/param.h>
#include <sys/proc.h> #include <sys/proc.h>
@ -72,7 +72,7 @@ svr4_32_fil_ioctl(file_t *fp, struct lwp *l, register_t *retval, int fd, u_long
if ((fp = fd_getfile(fd)) == NULL) if ((fp = fd_getfile(fd)) == NULL)
return EBADF; return EBADF;
fdp = curlwp->l_fd; fdp = curlwp->l_fd;
ff = fdp->fd_ofiles[fd]; ff = fdp->fd_dt->dt_ff[fd];
error = 0; error = 0;
switch (cmd) { switch (cmd) {

View File

@ -1,4 +1,4 @@
/* $NetBSD: db_xxx.c,v 1.60 2009/03/21 13:06:39 ad Exp $ */ /* $NetBSD: db_xxx.c,v 1.61 2009/05/24 21:41:25 ad Exp $ */
/* /*
* Copyright (c) 1982, 1986, 1989, 1991, 1993 * Copyright (c) 1982, 1986, 1989, 1991, 1993
@ -37,7 +37,7 @@
*/ */
#include <sys/cdefs.h> #include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: db_xxx.c,v 1.60 2009/03/21 13:06:39 ad Exp $"); __KERNEL_RCSID(0, "$NetBSD: db_xxx.c,v 1.61 2009/05/24 21:41:25 ad Exp $");
#ifdef _KERNEL_OPT #ifdef _KERNEL_OPT
#include "opt_kgdb.h" #include "opt_kgdb.h"
@ -106,6 +106,7 @@ db_show_files_cmd(db_expr_t addr, bool haddr,
file_t *fp; file_t *fp;
struct vnode *vn; struct vnode *vn;
bool full = false; bool full = false;
fdtab_t *dt;
if (modif[0] == 'f') if (modif[0] == 'f')
full = true; full = true;
@ -113,8 +114,9 @@ db_show_files_cmd(db_expr_t addr, bool haddr,
p = (struct proc *) (uintptr_t) addr; p = (struct proc *) (uintptr_t) addr;
fdp = p->p_fd; fdp = p->p_fd;
for (i = 0; i < fdp->fd_nfiles; i++) { dt = fdp->fd_dt;
if ((ff = fdp->fd_ofiles[i]) == NULL) for (i = 0; i < dt->dt_nfiles; i++) {
if ((ff = dt->dt_ff[i]) == NULL)
continue; continue;
fp = ff->ff_file; fp = ff->ff_file;

View File

@ -1,7 +1,7 @@
/* $NetBSD: init_sysctl.c,v 1.163 2009/05/16 12:02:00 yamt Exp $ */ /* $NetBSD: init_sysctl.c,v 1.164 2009/05/24 21:41:26 ad Exp $ */
/*- /*-
* Copyright (c) 2003, 2007, 2008 The NetBSD Foundation, Inc. * Copyright (c) 2003, 2007, 2008, 2009 The NetBSD Foundation, Inc.
* All rights reserved. * All rights reserved.
* *
* This code is derived from software contributed to The NetBSD Foundation * This code is derived from software contributed to The NetBSD Foundation
@ -30,7 +30,7 @@
*/ */
#include <sys/cdefs.h> #include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: init_sysctl.c,v 1.163 2009/05/16 12:02:00 yamt Exp $"); __KERNEL_RCSID(0, "$NetBSD: init_sysctl.c,v 1.164 2009/05/24 21:41:26 ad Exp $");
#include "opt_sysv.h" #include "opt_sysv.h"
#include "opt_compat_netbsd32.h" #include "opt_compat_netbsd32.h"
@ -1970,6 +1970,7 @@ sysctl_kern_file2(SYSCTLFN_ARGS)
size_t len, needed, elem_size, out_size; size_t len, needed, elem_size, out_size;
int error, arg, elem_count; int error, arg, elem_count;
fdfile_t *ff; fdfile_t *ff;
fdtab_t *dt;
if (namelen == 1 && name[0] == CTL_QUERY) if (namelen == 1 && name[0] == CTL_QUERY)
return (sysctl_query(SYSCTLFN_CALL(rnode))); return (sysctl_query(SYSCTLFN_CALL(rnode)));
@ -2089,20 +2090,18 @@ sysctl_kern_file2(SYSCTLFN_ARGS)
/* XXX Do we need to check permission per file? */ /* XXX Do we need to check permission per file? */
fd = p->p_fd; fd = p->p_fd;
mutex_enter(&fd->fd_lock); mutex_enter(&fd->fd_lock);
for (i = 0; i < fd->fd_nfiles; i++) { dt = fd->fd_dt;
if ((ff = fd->fd_ofiles[i]) == NULL) { for (i = 0; i < dt->dt_nfiles; i++) {
if ((ff = dt->dt_ff[i]) == NULL) {
continue; continue;
} }
mutex_enter(&ff->ff_lock);
if ((fp = ff->ff_file) == NULL) { if ((fp = ff->ff_file) == NULL) {
mutex_exit(&ff->ff_lock);
continue; continue;
} }
if (len >= elem_size && elem_count > 0) { if (len >= elem_size && elem_count > 0) {
mutex_enter(&fp->f_lock); mutex_enter(&fp->f_lock);
fill_file(&kf, fp, ff, i, p->p_pid); fill_file(&kf, fp, ff, i, p->p_pid);
mutex_exit(&fp->f_lock); mutex_exit(&fp->f_lock);
mutex_exit(&ff->ff_lock);
mutex_exit(&fd->fd_lock); mutex_exit(&fd->fd_lock);
error = dcopyout(l, &kf, dp, out_size); error = dcopyout(l, &kf, dp, out_size);
mutex_enter(&fd->fd_lock); mutex_enter(&fd->fd_lock);
@ -2110,8 +2109,6 @@ sysctl_kern_file2(SYSCTLFN_ARGS)
break; break;
dp += elem_size; dp += elem_size;
len -= elem_size; len -= elem_size;
} else {
mutex_exit(&ff->ff_lock);
} }
needed += elem_size; needed += elem_size;
if (elem_count > 0 && elem_count != INT_MAX) if (elem_count > 0 && elem_count != INT_MAX)

File diff suppressed because it is too large Load Diff

View File

@ -1,4 +1,4 @@
/* $NetBSD: kern_event.c,v 1.64 2009/04/04 10:12:51 ad Exp $ */ /* $NetBSD: kern_event.c,v 1.65 2009/05/24 21:41:26 ad Exp $ */
/*- /*-
* Copyright (c) 2008, 2009 The NetBSD Foundation, Inc. * Copyright (c) 2008, 2009 The NetBSD Foundation, Inc.
@ -58,7 +58,7 @@
*/ */
#include <sys/cdefs.h> #include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: kern_event.c,v 1.64 2009/04/04 10:12:51 ad Exp $"); __KERNEL_RCSID(0, "$NetBSD: kern_event.c,v 1.65 2009/05/24 21:41:26 ad Exp $");
#include <sys/param.h> #include <sys/param.h>
#include <sys/systm.h> #include <sys/systm.h>
@ -879,7 +879,7 @@ kqueue_register(struct kqueue *kq, struct kevent *kev)
kmem_free(newkn, sizeof(*newkn)); kmem_free(newkn, sizeof(*newkn));
return EBADF; return EBADF;
} }
ff = fdp->fd_ofiles[fd]; ff = fdp->fd_dt->dt_ff[fd];
if (fd <= fdp->fd_lastkqfile) { if (fd <= fdp->fd_lastkqfile) {
SLIST_FOREACH(kn, &ff->ff_knlist, kn_link) { SLIST_FOREACH(kn, &ff->ff_knlist, kn_link) {
if (kq == kn->kn_kq && if (kq == kn->kn_kq &&
@ -944,7 +944,7 @@ kqueue_register(struct kqueue *kq, struct kevent *kev)
} else { } else {
/* Otherwise, knote is on an fd. */ /* Otherwise, knote is on an fd. */
list = (struct klist *) list = (struct klist *)
&fdp->fd_ofiles[kn->kn_id]->ff_knlist; &fdp->fd_dt->dt_ff[kn->kn_id]->ff_knlist;
if ((int)kn->kn_id > fdp->fd_lastkqfile) if ((int)kn->kn_id > fdp->fd_lastkqfile)
fdp->fd_lastkqfile = kn->kn_id; fdp->fd_lastkqfile = kn->kn_id;
} }
@ -1377,7 +1377,7 @@ kqueue_close(file_t *fp)
mutex_enter(&fdp->fd_lock); mutex_enter(&fdp->fd_lock);
for (i = 0; i <= fdp->fd_lastkqfile; i++) { for (i = 0; i <= fdp->fd_lastkqfile; i++) {
if ((ff = fdp->fd_ofiles[i]) == NULL) if ((ff = fdp->fd_dt->dt_ff[i]) == NULL)
continue; continue;
kqueue_doclose(kq, (struct klist *)&ff->ff_knlist, i); kqueue_doclose(kq, (struct klist *)&ff->ff_knlist, i);
} }
@ -1452,7 +1452,7 @@ knote_fdclose(int fd)
filedesc_t *fdp; filedesc_t *fdp;
fdp = curlwp->l_fd; fdp = curlwp->l_fd;
list = (struct klist *)&fdp->fd_ofiles[fd]->ff_knlist; list = (struct klist *)&fdp->fd_dt->dt_ff[fd]->ff_knlist;
mutex_enter(&fdp->fd_lock); mutex_enter(&fdp->fd_lock);
while ((kn = SLIST_FIRST(list)) != NULL) { while ((kn = SLIST_FIRST(list)) != NULL) {
knote_detach(kn, fdp, true); knote_detach(kn, fdp, true);
@ -1485,7 +1485,7 @@ knote_detach(struct knote *kn, filedesc_t *fdp, bool dofop)
/* Remove from descriptor table. */ /* Remove from descriptor table. */
if (kn->kn_fop->f_isfd) if (kn->kn_fop->f_isfd)
list = (struct klist *)&fdp->fd_ofiles[kn->kn_id]->ff_knlist; list = (struct klist *)&fdp->fd_dt->dt_ff[kn->kn_id]->ff_knlist;
else else
list = &fdp->fd_knhash[KN_HASH(kn->kn_id, fdp->fd_knhashmask)]; list = &fdp->fd_knhash[KN_HASH(kn->kn_id, fdp->fd_knhashmask)];

View File

@ -1,4 +1,4 @@
/* $NetBSD: kern_sig.c,v 1.297 2009/03/29 05:02:46 rmind Exp $ */ /* $NetBSD: kern_sig.c,v 1.298 2009/05/24 21:41:26 ad Exp $ */
/*- /*-
* Copyright (c) 2006, 2007, 2008 The NetBSD Foundation, Inc. * Copyright (c) 2006, 2007, 2008 The NetBSD Foundation, Inc.
@ -66,7 +66,7 @@
*/ */
#include <sys/cdefs.h> #include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: kern_sig.c,v 1.297 2009/03/29 05:02:46 rmind Exp $"); __KERNEL_RCSID(0, "$NetBSD: kern_sig.c,v 1.298 2009/05/24 21:41:26 ad Exp $");
#include "opt_ptrace.h" #include "opt_ptrace.h"
#include "opt_compat_sunos.h" #include "opt_compat_sunos.h"
@ -986,6 +986,7 @@ kpsignal(struct proc *p, ksiginfo_t *ksi, void *data)
{ {
fdfile_t *ff; fdfile_t *ff;
file_t *fp; file_t *fp;
fdtab_t *dt;
KASSERT(!cpu_intr_p()); KASSERT(!cpu_intr_p());
KASSERT(mutex_owned(proc_lock)); KASSERT(mutex_owned(proc_lock));
@ -996,8 +997,9 @@ kpsignal(struct proc *p, ksiginfo_t *ksi, void *data)
/* XXXSMP locking */ /* XXXSMP locking */
ksi->ksi_fd = -1; ksi->ksi_fd = -1;
for (fd = 0; fd < fdp->fd_nfiles; fd++) { dt = fdp->fd_dt;
if ((ff = fdp->fd_ofiles[fd]) == NULL) for (fd = 0; fd < dt->dt_nfiles; fd++) {
if ((ff = dt->dt_ff[fd]) == NULL)
continue; continue;
if ((fp = ff->ff_file) == NULL) if ((fp = ff->ff_file) == NULL)
continue; continue;

View File

@ -1,4 +1,4 @@
/* $NetBSD: subr_exec_fd.c,v 1.1 2008/11/18 13:01:41 pooka Exp $ */ /* $NetBSD: subr_exec_fd.c,v 1.2 2009/05/24 21:41:26 ad Exp $ */
/*- /*-
* Copyright (c) 2008 The NetBSD Foundation, Inc. * Copyright (c) 2008 The NetBSD Foundation, Inc.
@ -31,7 +31,7 @@
*/ */
#include <sys/cdefs.h> #include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: subr_exec_fd.c,v 1.1 2008/11/18 13:01:41 pooka Exp $"); __KERNEL_RCSID(0, "$NetBSD: subr_exec_fd.c,v 1.2 2009/05/24 21:41:26 ad Exp $");
#include <sys/param.h> #include <sys/param.h>
#include <sys/file.h> #include <sys/file.h>
@ -51,6 +51,7 @@ fd_closeexec(void)
filedesc_t *fdp; filedesc_t *fdp;
fdfile_t *ff; fdfile_t *ff;
lwp_t *l; lwp_t *l;
fdtab_t *dt;
int fd; int fd;
l = curlwp; l = curlwp;
@ -73,9 +74,10 @@ fd_closeexec(void)
return; return;
} }
fdp->fd_exclose = false; fdp->fd_exclose = false;
dt = fdp->fd_dt;
for (fd = 0; fd <= fdp->fd_lastfile; fd++) { for (fd = 0; fd <= fdp->fd_lastfile; fd++) {
if ((ff = fdp->fd_ofiles[fd]) == NULL) { if ((ff = dt->dt_ff[fd]) == NULL) {
KASSERT(fd >= NDFDFILE); KASSERT(fd >= NDFDFILE);
continue; continue;
} }
@ -111,6 +113,7 @@ fd_checkstd(void)
struct nameidata nd; struct nameidata nd;
filedesc_t *fdp; filedesc_t *fdp;
file_t *fp; file_t *fp;
fdtab_t *dt;
struct proc *pp; struct proc *pp;
int fd, i, error, flags = FREAD|FWRITE; int fd, i, error, flags = FREAD|FWRITE;
char closed[CHECK_UPTO * 3 + 1], which[3 + 1]; char closed[CHECK_UPTO * 3 + 1], which[3 + 1];
@ -119,10 +122,11 @@ fd_checkstd(void)
closed[0] = '\0'; closed[0] = '\0';
if ((fdp = p->p_fd) == NULL) if ((fdp = p->p_fd) == NULL)
return (0); return (0);
dt = fdp->fd_dt;
for (i = 0; i < CHECK_UPTO; i++) { for (i = 0; i < CHECK_UPTO; i++) {
KASSERT(i >= NDFDFILE || KASSERT(i >= NDFDFILE ||
fdp->fd_ofiles[i] == (fdfile_t *)fdp->fd_dfdfile[i]); dt->dt_ff[i] == (fdfile_t *)fdp->fd_dfdfile[i]);
if (fdp->fd_ofiles[i]->ff_file != NULL) if (dt->dt_ff[i]->ff_file != NULL)
continue; continue;
snprintf(which, sizeof(which), ",%d", i); snprintf(which, sizeof(which), ",%d", i);
strlcat(closed, which, sizeof(closed)); strlcat(closed, which, sizeof(closed));

View File

@ -1,4 +1,4 @@
/* $NetBSD: sys_aio.c,v 1.23 2009/02/22 20:28:06 ad Exp $ */ /* $NetBSD: sys_aio.c,v 1.24 2009/05/24 21:41:26 ad Exp $ */
/* /*
* Copyright (c) 2007, Mindaugas Rasiukevicius <rmind at NetBSD org> * Copyright (c) 2007, Mindaugas Rasiukevicius <rmind at NetBSD org>
@ -32,7 +32,7 @@
*/ */
#include <sys/cdefs.h> #include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: sys_aio.c,v 1.23 2009/02/22 20:28:06 ad Exp $"); __KERNEL_RCSID(0, "$NetBSD: sys_aio.c,v 1.24 2009/05/24 21:41:26 ad Exp $");
#ifdef _KERNEL_OPT #ifdef _KERNEL_OPT
#include "opt_ddb.h" #include "opt_ddb.h"
@ -622,15 +622,16 @@ sys_aio_cancel(struct lwp *l, const struct sys_aio_cancel_args *uap, register_t
struct lio_req *lio; struct lio_req *lio;
struct filedesc *fdp = p->p_fd; struct filedesc *fdp = p->p_fd;
unsigned int cn, errcnt, fildes; unsigned int cn, errcnt, fildes;
fdtab_t *dt;
TAILQ_HEAD(, aio_job) tmp_jobs_list; TAILQ_HEAD(, aio_job) tmp_jobs_list;
/* Check for invalid file descriptor */ /* Check for invalid file descriptor */
fildes = (unsigned int)SCARG(uap, fildes); fildes = (unsigned int)SCARG(uap, fildes);
if (fildes >= fdp->fd_nfiles) dt = fdp->fd_dt;
if (fildes >= dt->dt_nfiles)
return EBADF; return EBADF;
membar_consumer(); if (dt->dt_ff[fildes] == NULL || dt->dt_ff[fildes]->ff_file == NULL)
if (fdp->fd_ofiles[fildes] == NULL || fdp->fd_ofiles[fildes]->ff_file == NULL)
return EBADF; return EBADF;
/* Check if AIO structure is initialized */ /* Check if AIO structure is initialized */

View File

@ -1,4 +1,4 @@
/* $NetBSD: sys_descrip.c,v 1.12 2009/03/28 21:42:19 rmind Exp $ */ /* $NetBSD: sys_descrip.c,v 1.13 2009/05/24 21:41:26 ad Exp $ */
/*- /*-
* Copyright (c) 2008 The NetBSD Foundation, Inc. * Copyright (c) 2008 The NetBSD Foundation, Inc.
@ -67,7 +67,7 @@
*/ */
#include <sys/cdefs.h> #include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: sys_descrip.c,v 1.12 2009/03/28 21:42:19 rmind Exp $"); __KERNEL_RCSID(0, "$NetBSD: sys_descrip.c,v 1.13 2009/05/24 21:41:26 ad Exp $");
#include <sys/param.h> #include <sys/param.h>
#include <sys/systm.h> #include <sys/systm.h>
@ -356,7 +356,7 @@ sys_fcntl(struct lwp *l, const struct sys_fcntl_args *uap, register_t *retval)
if ((fp = fd_getfile(fd)) == NULL) if ((fp = fd_getfile(fd)) == NULL)
return (EBADF); return (EBADF);
ff = fdp->fd_ofiles[fd]; ff = fdp->fd_dt->dt_ff[fd];
if ((cmd & F_FSCTL)) { if ((cmd & F_FSCTL)) {
error = fcntl_forfs(fd, fp, cmd, SCARG(uap, arg)); error = fcntl_forfs(fd, fp, cmd, SCARG(uap, arg));

View File

@ -1,4 +1,4 @@
/* $NetBSD: sys_generic.c,v 1.122 2009/05/17 10:08:38 ad Exp $ */ /* $NetBSD: sys_generic.c,v 1.123 2009/05/24 21:41:26 ad Exp $ */
/*- /*-
* Copyright (c) 2007, 2008, 2009 The NetBSD Foundation, Inc. * Copyright (c) 2007, 2008, 2009 The NetBSD Foundation, Inc.
@ -70,7 +70,7 @@
*/ */
#include <sys/cdefs.h> #include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: sys_generic.c,v 1.122 2009/05/17 10:08:38 ad Exp $"); __KERNEL_RCSID(0, "$NetBSD: sys_generic.c,v 1.123 2009/05/24 21:41:26 ad Exp $");
#include <sys/param.h> #include <sys/param.h>
#include <sys/systm.h> #include <sys/systm.h>
@ -543,7 +543,7 @@ sys_ioctl(struct lwp *l, const struct sys_ioctl_args *uap, register_t *retval)
goto out; goto out;
} }
ff = fdp->fd_ofiles[SCARG(uap, fd)]; ff = fdp->fd_dt->dt_ff[SCARG(uap, fd)];
switch (com = SCARG(uap, com)) { switch (com = SCARG(uap, com)) {
case FIONCLEX: case FIONCLEX:
ff->ff_exclose = false; ff->ff_exclose = false;

View File

@ -1,4 +1,4 @@
/* $NetBSD: sys_select.c,v 1.14 2009/03/29 19:21:19 christos Exp $ */ /* $NetBSD: sys_select.c,v 1.15 2009/05/24 21:41:26 ad Exp $ */
/*- /*-
* Copyright (c) 2007, 2008, 2009 The NetBSD Foundation, Inc. * Copyright (c) 2007, 2008, 2009 The NetBSD Foundation, Inc.
@ -70,7 +70,7 @@
*/ */
#include <sys/cdefs.h> #include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: sys_select.c,v 1.14 2009/03/29 19:21:19 christos Exp $"); __KERNEL_RCSID(0, "$NetBSD: sys_select.c,v 1.15 2009/05/24 21:41:26 ad Exp $");
#include <sys/param.h> #include <sys/param.h>
#include <sys/systm.h> #include <sys/systm.h>
@ -218,7 +218,7 @@ selcommon(lwp_t *l, register_t *retval, int nd, fd_set *u_in,
sizeof(fd_mask) * 6]; sizeof(fd_mask) * 6];
proc_t * const p = l->l_proc; proc_t * const p = l->l_proc;
char *bits; char *bits;
int ncoll, error, timo; int ncoll, error, timo, nf;
size_t ni; size_t ni;
sigset_t oldmask; sigset_t oldmask;
struct timespec sleepts; struct timespec sleepts;
@ -228,9 +228,10 @@ selcommon(lwp_t *l, register_t *retval, int nd, fd_set *u_in,
error = 0; error = 0;
if (nd < 0) if (nd < 0)
return (EINVAL); return (EINVAL);
if (nd > p->p_fd->fd_nfiles) { nf = p->p_fd->fd_dt->dt_nfiles;
if (nd > nf) {
/* forgiving; slightly wrong */ /* forgiving; slightly wrong */
nd = p->p_fd->fd_nfiles; nd = nf;
} }
ni = howmany(nd, NFDBITS) * sizeof(fd_mask); ni = howmany(nd, NFDBITS) * sizeof(fd_mask);
if (ni * 6 > sizeof(smallbits)) { if (ni * 6 > sizeof(smallbits)) {
@ -427,14 +428,15 @@ pollcommon(lwp_t *l, register_t *retval, struct pollfd *u_fds, u_int nfds,
proc_t * const p = l->l_proc; proc_t * const p = l->l_proc;
sigset_t oldmask; sigset_t oldmask;
int ncoll, error, timo; int ncoll, error, timo;
size_t ni; size_t ni, nf;
struct timespec sleepts; struct timespec sleepts;
selcpu_t *sc; selcpu_t *sc;
kmutex_t *lock; kmutex_t *lock;
if (nfds > p->p_fd->fd_nfiles) { nf = p->p_fd->fd_dt->dt_nfiles;
if (nfds > nf) {
/* forgiving; slightly wrong */ /* forgiving; slightly wrong */
nfds = p->p_fd->fd_nfiles; nfds = nf;
} }
ni = nfds * sizeof(struct pollfd); ni = nfds * sizeof(struct pollfd);
if (ni > sizeof(smallfds)) { if (ni > sizeof(smallfds)) {

View File

@ -1,4 +1,4 @@
/* $NetBSD: uipc_usrreq.c,v 1.125 2009/05/04 06:02:40 yamt Exp $ */ /* $NetBSD: uipc_usrreq.c,v 1.126 2009/05/24 21:41:26 ad Exp $ */
/*- /*-
* Copyright (c) 1998, 2000, 2004, 2008, 2009 The NetBSD Foundation, Inc. * Copyright (c) 1998, 2000, 2004, 2008, 2009 The NetBSD Foundation, Inc.
@ -96,7 +96,7 @@
*/ */
#include <sys/cdefs.h> #include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: uipc_usrreq.c,v 1.125 2009/05/04 06:02:40 yamt Exp $"); __KERNEL_RCSID(0, "$NetBSD: uipc_usrreq.c,v 1.126 2009/05/24 21:41:26 ad Exp $");
#include <sys/param.h> #include <sys/param.h>
#include <sys/systm.h> #include <sys/systm.h>
@ -1338,7 +1338,7 @@ unp_internalize(struct mbuf **controlp)
fdp = (int *)CMSG_DATA(cm) + nfds; fdp = (int *)CMSG_DATA(cm) + nfds;
rp = files + nfds; rp = files + nfds;
for (i = 0; i < nfds; i++) { for (i = 0; i < nfds; i++) {
fp = fdescp->fd_ofiles[*--fdp]->ff_file; fp = fdescp->fd_dt->dt_ff[*--fdp]->ff_file;
KASSERT(fp != NULL); KASSERT(fp != NULL);
mutex_enter(&fp->f_lock); mutex_enter(&fp->f_lock);
*--rp = fp; *--rp = fp;

View File

@ -1,4 +1,4 @@
/* $NetBSD: fdesc_vfsops.c,v 1.79 2009/03/14 15:36:22 dsl Exp $ */ /* $NetBSD: fdesc_vfsops.c,v 1.80 2009/05/24 21:41:26 ad Exp $ */
/* /*
* Copyright (c) 1992, 1993, 1995 * Copyright (c) 1992, 1993, 1995
@ -41,7 +41,7 @@
*/ */
#include <sys/cdefs.h> #include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: fdesc_vfsops.c,v 1.79 2009/03/14 15:36:22 dsl Exp $"); __KERNEL_RCSID(0, "$NetBSD: fdesc_vfsops.c,v 1.80 2009/05/24 21:41:26 ad Exp $");
#if defined(_KERNEL_OPT) #if defined(_KERNEL_OPT)
#include "opt_compat_netbsd.h" #include "opt_compat_netbsd.h"
@ -164,13 +164,13 @@ fdesc_root(struct mount *mp, struct vnode **vpp)
int int
fdesc_statvfs(struct mount *mp, struct statvfs *sbp) fdesc_statvfs(struct mount *mp, struct statvfs *sbp)
{ {
struct lwp *l = curlwp; lwp_t *l = curlwp;
struct filedesc *fdp; proc_t *p;
struct proc *p;
int lim; int lim;
int i; int i;
int last; int last;
int freefd; int freefd;
fdtab_t *dt;
/* /*
* Compute number of free file descriptors. * Compute number of free file descriptors.
@ -179,20 +179,20 @@ fdesc_statvfs(struct mount *mp, struct statvfs *sbp)
* of open files... ] * of open files... ]
*/ */
p = l->l_proc; p = l->l_proc;
dt = l->l_fd->fd_dt;
lim = p->p_rlimit[RLIMIT_NOFILE].rlim_cur; lim = p->p_rlimit[RLIMIT_NOFILE].rlim_cur;
fdp = p->p_fd; last = min(dt->dt_nfiles, lim);
last = min(fdp->fd_nfiles, lim);
freefd = 0; freefd = 0;
for (i = fdp->fd_freefile; i < last; i++) for (i = l->l_fd->fd_freefile; i < last; i++)
if (fdp->fd_ofiles[i] == NULL) if (dt->dt_ff[i]->ff_file == NULL)
freefd++; freefd++;
/* /*
* Adjust for the fact that the fdesc array may not * Adjust for the fact that the fdesc array may not
* have been fully allocated yet. * have been fully allocated yet.
*/ */
if (fdp->fd_nfiles < lim) if (dt->dt_nfiles < lim)
freefd += (lim - fdp->fd_nfiles); freefd += (lim - dt->dt_nfiles);
sbp->f_bsize = DEV_BSIZE; sbp->f_bsize = DEV_BSIZE;
sbp->f_frsize = DEV_BSIZE; sbp->f_frsize = DEV_BSIZE;

View File

@ -1,4 +1,4 @@
/* $NetBSD: fdesc_vnops.c,v 1.106 2009/03/15 17:22:37 cegger Exp $ */ /* $NetBSD: fdesc_vnops.c,v 1.107 2009/05/24 21:41:26 ad Exp $ */
/* /*
* Copyright (c) 1992, 1993 * Copyright (c) 1992, 1993
@ -41,7 +41,7 @@
*/ */
#include <sys/cdefs.h> #include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: fdesc_vnops.c,v 1.106 2009/03/15 17:22:37 cegger Exp $"); __KERNEL_RCSID(0, "$NetBSD: fdesc_vnops.c,v 1.107 2009/05/24 21:41:26 ad Exp $");
#include <sys/param.h> #include <sys/param.h>
#include <sys/systm.h> #include <sys/systm.h>
@ -276,12 +276,13 @@ fdesc_lookup(void *v)
struct lwp *l = curlwp; struct lwp *l = curlwp;
const char *pname = cnp->cn_nameptr; const char *pname = cnp->cn_nameptr;
struct proc *p = l->l_proc; struct proc *p = l->l_proc;
filedesc_t *fdp = p->p_fd;
int numfiles = fdp->fd_nfiles;
unsigned fd = 0; unsigned fd = 0;
int error; int error;
struct vnode *fvp; struct vnode *fvp;
const char *ln; const char *ln;
fdtab_t *dt;
dt = curlwp->l_fd->fd_dt;
if (cnp->cn_namelen == 1 && *pname == '.') { if (cnp->cn_namelen == 1 && *pname == '.') {
*vpp = dvp; *vpp = dvp;
@ -370,7 +371,7 @@ fdesc_lookup(void *v)
fd = 0; fd = 0;
while (*pname >= '0' && *pname <= '9') { while (*pname >= '0' && *pname <= '9') {
fd = 10 * fd + *pname++ - '0'; fd = 10 * fd + *pname++ - '0';
if (fd >= numfiles) if (fd >= dt->dt_nfiles)
break; break;
} }
@ -379,14 +380,11 @@ fdesc_lookup(void *v)
goto bad; goto bad;
} }
mutex_enter(&fdp->fd_lock); if (fd >= dt->dt_nfiles || dt->dt_ff[fd] == NULL ||
if (fd >= numfiles ||fdp->fd_ofiles[fd] == NULL || dt->dt_ff[fd]->ff_file == NULL) {
fdp->fd_ofiles[fd]->ff_file == NULL) {
mutex_exit(&fdp->fd_lock);
error = EBADF; error = EBADF;
goto bad; goto bad;
} }
mutex_exit(&fdp->fd_lock);
error = fdesc_allocvp(Fdesc, FD_DESC+fd, dvp->v_mount, &fvp); error = fdesc_allocvp(Fdesc, FD_DESC+fd, dvp->v_mount, &fvp);
if (error) if (error)
@ -650,12 +648,12 @@ fdesc_readdir(void *v)
} */ *ap = v; } */ *ap = v;
struct uio *uio = ap->a_uio; struct uio *uio = ap->a_uio;
struct dirent d; struct dirent d;
filedesc_t *fdp;
off_t i; off_t i;
int j; int j;
int error; int error;
off_t *cookies = NULL; off_t *cookies = NULL;
int ncookies; int ncookies;
fdtab_t *dt;
switch (VTOFDESC(ap->a_vp)->fd_type) { switch (VTOFDESC(ap->a_vp)->fd_type) {
case Fctty: case Fctty:
@ -668,7 +666,7 @@ fdesc_readdir(void *v)
break; break;
} }
fdp = curproc->p_fd; dt = curlwp->l_fd->fd_dt;
if (uio->uio_resid < UIO_MX) if (uio->uio_resid < UIO_MX)
return EINVAL; return EINVAL;
@ -709,14 +707,11 @@ fdesc_readdir(void *v)
case FD_STDIN: case FD_STDIN:
case FD_STDOUT: case FD_STDOUT:
case FD_STDERR: case FD_STDERR:
if (fdp == NULL)
continue;
if ((ft->ft_fileno - FD_STDIN) >= if ((ft->ft_fileno - FD_STDIN) >=
fdp->fd_nfiles) dt->dt_nfiles)
continue; continue;
membar_consumer(); if (dt->dt_ff[ft->ft_fileno - FD_STDIN]
if (fdp->fd_ofiles[ft->ft_fileno - FD_STDIN] == NULL || dt->dt_ff[ft->ft_fileno -
== NULL || fdp->fd_ofiles[ft->ft_fileno -
FD_STDIN]->ff_file == NULL) FD_STDIN]->ff_file == NULL)
continue; continue;
break; break;
@ -733,16 +728,15 @@ fdesc_readdir(void *v)
*cookies++ = i + 1; *cookies++ = i + 1;
} }
} else { } else {
int nfdp = fdp ? fdp->fd_nfiles : 0;
membar_consumer(); membar_consumer();
if (ap->a_ncookies) { if (ap->a_ncookies) {
ncookies = min(ncookies, nfdp + 2); ncookies = min(ncookies, dt->dt_nfiles + 2);
cookies = malloc(ncookies * sizeof(off_t), cookies = malloc(ncookies * sizeof(off_t),
M_TEMP, M_WAITOK); M_TEMP, M_WAITOK);
*ap->a_cookies = cookies; *ap->a_cookies = cookies;
*ap->a_ncookies = ncookies; *ap->a_ncookies = ncookies;
} }
for (; i - 2 < nfdp && uio->uio_resid >= UIO_MX; i++) { for (; i - 2 < dt->dt_nfiles && uio->uio_resid >= UIO_MX; i++) {
switch (i) { switch (i) {
case 0: case 0:
case 1: case 1:
@ -754,10 +748,9 @@ fdesc_readdir(void *v)
break; break;
default: default:
KASSERT(fdp != NULL);
j = (int)i - 2; j = (int)i - 2;
if (fdp == NULL || fdp->fd_ofiles[j] == NULL || if (dt->dt_ff[j] == NULL ||
fdp->fd_ofiles[j]->ff_file == NULL) dt->dt_ff[j]->ff_file == NULL)
continue; continue;
d.d_fileno = j + FD_STDIN; d.d_fileno = j + FD_STDIN;
d.d_namlen = sprintf(d.d_name, "%d", j); d.d_namlen = sprintf(d.d_name, "%d", j);

View File

@ -1,4 +1,4 @@
/* $NetBSD: portal_vnops.c,v 1.82 2009/03/14 15:36:23 dsl Exp $ */ /* $NetBSD: portal_vnops.c,v 1.83 2009/05/24 21:41:26 ad Exp $ */
/* /*
* Copyright (c) 1992, 1993 * Copyright (c) 1992, 1993
@ -40,7 +40,7 @@
*/ */
#include <sys/cdefs.h> #include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: portal_vnops.c,v 1.82 2009/03/14 15:36:23 dsl Exp $"); __KERNEL_RCSID(0, "$NetBSD: portal_vnops.c,v 1.83 2009/05/24 21:41:26 ad Exp $");
#include <sys/param.h> #include <sys/param.h>
#include <sys/systm.h> #include <sys/systm.h>
@ -483,7 +483,7 @@ portal_open(void *v)
* Check that the mode the file is being opened for is a subset * Check that the mode the file is being opened for is a subset
* of the mode of the existing descriptor. * of the mode of the existing descriptor.
*/ */
fp = l->l_proc->p_fd->fd_ofiles[fd]->ff_file; fp = l->l_fd->fd_dt->dt_ff[fd]->ff_file;
if (((ap->a_mode & (FREAD|FWRITE)) | fp->f_flag) != fp->f_flag) { if (((ap->a_mode & (FREAD|FWRITE)) | fp->f_flag) != fp->f_flag) {
portal_closefd(l, fd); /* XXXNJWLWP */ portal_closefd(l, fd); /* XXXNJWLWP */
error = EACCES; error = EACCES;

View File

@ -1,4 +1,4 @@
/* $NetBSD: procfs_vnops.c,v 1.173 2008/12/17 20:51:36 cegger Exp $ */ /* $NetBSD: procfs_vnops.c,v 1.174 2009/05/24 21:41:26 ad Exp $ */
/*- /*-
* Copyright (c) 2006, 2007, 2008 The NetBSD Foundation, Inc. * Copyright (c) 2006, 2007, 2008 The NetBSD Foundation, Inc.
@ -105,7 +105,7 @@
*/ */
#include <sys/cdefs.h> #include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: procfs_vnops.c,v 1.173 2008/12/17 20:51:36 cegger Exp $"); __KERNEL_RCSID(0, "$NetBSD: procfs_vnops.c,v 1.174 2009/05/24 21:41:26 ad Exp $");
#include <sys/param.h> #include <sys/param.h>
#include <sys/systm.h> #include <sys/systm.h>
@ -1338,7 +1338,7 @@ procfs_readdir(void *v)
return ESRCH; return ESRCH;
} }
nfd = p->p_fd->fd_nfiles; nfd = p->p_fd->fd_dt->dt_nfiles;
lim = min((int)p->p_rlimit[RLIMIT_NOFILE].rlim_cur, maxfiles); lim = min((int)p->p_rlimit[RLIMIT_NOFILE].rlim_cur, maxfiles);
if (i >= lim) { if (i >= lim) {

View File

@ -1,4 +1,4 @@
/* $NetBSD: filedesc.h,v 1.54 2009/05/23 18:28:05 ad Exp $ */ /* $NetBSD: filedesc.h,v 1.55 2009/05/24 21:41:26 ad Exp $ */
/*- /*-
* Copyright (c) 2008 The NetBSD Foundation, Inc. * Copyright (c) 2008 The NetBSD Foundation, Inc.
@ -94,8 +94,8 @@
* in use. Locks: * in use. Locks:
* *
* : unlocked * : unlocked
* a atomic operations + filedesc_t::fd_lock in some cases
* d filedesc_t::fd_lock * d filedesc_t::fd_lock
* f fdfile_t::ff_lock, may be stable if reference held
* *
* Note that ff_exclose and ff_allocated are likely to be byte sized * Note that ff_exclose and ff_allocated are likely to be byte sized
* (bool). In general adjacent sub-word sized fields must be locked * (bool). In general adjacent sub-word sized fields must be locked
@ -104,19 +104,29 @@
* it's invalid. * it's invalid.
*/ */
typedef struct fdfile { typedef struct fdfile {
kmutex_t ff_lock; /* :: lock on structure */
bool ff_exclose; /* :: close on exec flag */ bool ff_exclose; /* :: close on exec flag */
bool ff_allocated; /* d: descriptor slot is allocated */ bool ff_allocated; /* d: descriptor slot is allocated */
u_int ff_refcnt; /* f: reference count on structure */ u_int ff_refcnt; /* a: reference count on structure */
struct file *ff_file; /* f: pointer to file if open */ struct file *ff_file; /* d: pointer to file if open */
SLIST_HEAD(,knote) ff_knlist; /* f: knotes attached to this fd */ SLIST_HEAD(,knote) ff_knlist; /* d: knotes attached to this fd */
kcondvar_t ff_closing; /* f: notifier for close */ kcondvar_t ff_closing; /* d: notifier for close */
} fdfile_t; } fdfile_t;
/* Reference count */ /* Reference count */
#define FR_CLOSING (0x80000000) /* closing: must interlock */ #define FR_CLOSING (0x80000000) /* closing: must interlock */
#define FR_MASK (~FR_CLOSING) /* reference count */ #define FR_MASK (~FR_CLOSING) /* reference count */
/*
* Open file table, potentially many 'active' tables per filedesc_t
* in a multi-threaded process, or with a shared filedesc_t (clone()).
* nfiles is first to avoid pointer arithmetic.
*/
typedef struct fdtab {
u_int dt_nfiles; /* number of open files allocated */
struct fdtab *dt_link; /* for lists of dtab */
fdfile_t *dt_ff[NDFILE]; /* file structures for open fds */
} fdtab_t;
typedef struct filedesc { typedef struct filedesc {
/* /*
* Built-in fdfile_t records first, since they have strict * Built-in fdfile_t records first, since they have strict
@ -127,29 +137,27 @@ typedef struct filedesc {
* All of the remaining fields are locked by fd_lock. * All of the remaining fields are locked by fd_lock.
*/ */
kmutex_t fd_lock; /* lock on structure */ kmutex_t fd_lock; /* lock on structure */
fdfile_t **fd_ofiles; /* file structures for open files */ fdtab_t * volatile fd_dt; /* active descriptor table */
uint32_t *fd_himap; /* each bit points to 32 fds */ uint32_t *fd_himap; /* each bit points to 32 fds */
uint32_t *fd_lomap; /* bitmap of free fds */ uint32_t *fd_lomap; /* bitmap of free fds */
void *fd_discard; /* old fd_ofiles tables to discard */
struct klist *fd_knhash; /* hash of attached non-fd knotes */ struct klist *fd_knhash; /* hash of attached non-fd knotes */
int fd_lastkqfile; /* max descriptor for kqueue */ int fd_lastkqfile; /* max descriptor for kqueue */
int fd_lastfile; /* high-water mark of fd_ofiles */ int fd_lastfile; /* high-water mark of fd_ofiles */
int fd_refcnt; /* reference count */ int fd_refcnt; /* reference count */
int fd_nfiles; /* number of open files allocated */
u_long fd_knhashmask; /* size of fd_knhash */ u_long fd_knhashmask; /* size of fd_knhash */
#define fd_startzero fd_freefile /* area to zero on return to cache */
int fd_freefile; /* approx. next free file */ int fd_freefile; /* approx. next free file */
int fd_nused; /* number of slots in use */ int fd_unused; /* unused */
bool fd_exclose; /* non-zero if >0 fd with EXCLOSE */ bool fd_exclose; /* non-zero if >0 fd with EXCLOSE */
/* /*
* These arrays are used when the number of open files is * This structure is used when the number of open files is
* <= NDFILE, and are then pointed to by the pointers above. * <= NDFILE, and are then pointed to by the pointers above.
*/ */
fdfile_t *fd_dfiles[NDFILE]; fdtab_t fd_dtbuiltin;
/* /*
* These arrays are used when the number of open files is * These arrays are used when the number of open files is
* <= 1024, and are then pointed to by the pointers above. * <= 1024, and are then pointed to by the pointers above.
*/ */
#define fd_startzero fd_dhimap /* area to zero on return to cache */
uint32_t fd_dhimap[NDENTRIES >> NDENTRYSHIFT]; uint32_t fd_dhimap[NDENTRIES >> NDENTRYSHIFT];
uint32_t fd_dlomap[NDENTRIES]; uint32_t fd_dlomap[NDENTRIES];
} filedesc_t; } filedesc_t;
@ -196,9 +204,6 @@ int fd_getsock(unsigned, struct socket **);
void fd_putvnode(unsigned); void fd_putvnode(unsigned);
void fd_putsock(unsigned); void fd_putsock(unsigned);
int fd_close(unsigned); int fd_close(unsigned);
void fd_used(filedesc_t *, unsigned);
void fd_unused(filedesc_t *, unsigned);
bool fd_isused(filedesc_t *, unsigned);
int fd_dup(file_t *, int, int *, bool); int fd_dup(file_t *, int, int *, bool);
int fd_dup2(file_t *, unsigned); int fd_dup2(file_t *, unsigned);
int fd_clone(file_t *, unsigned, int, const struct fileops *, void *); int fd_clone(file_t *, unsigned, int, const struct fileops *, void *);
@ -226,6 +231,7 @@ int do_fcntl_lock(int, int, struct flock *);
int do_posix_fadvise(int, off_t, off_t, int); int do_posix_fadvise(int, off_t, off_t, int);
extern kmutex_t filelist_lock; extern kmutex_t filelist_lock;
extern filedesc_t filedesc0;
#endif /* _KERNEL */ #endif /* _KERNEL */

View File

@ -1,4 +1,4 @@
/* $NetBSD: fstat.c,v 1.88 2009/04/12 06:36:12 lukem Exp $ */ /* $NetBSD: fstat.c,v 1.89 2009/05/24 21:41:44 ad Exp $ */
/*- /*-
* Copyright (c) 1988, 1993 * Copyright (c) 1988, 1993
@ -39,7 +39,7 @@ __COPYRIGHT("@(#) Copyright (c) 1988, 1993\
#if 0 #if 0
static char sccsid[] = "@(#)fstat.c 8.3 (Berkeley) 5/2/95"; static char sccsid[] = "@(#)fstat.c 8.3 (Berkeley) 5/2/95";
#else #else
__RCSID("$NetBSD: fstat.c,v 1.88 2009/04/12 06:36:12 lukem Exp $"); __RCSID("$NetBSD: fstat.c,v 1.89 2009/05/24 21:41:44 ad Exp $");
#endif #endif
#endif /* not lint */ #endif /* not lint */
@ -313,6 +313,7 @@ dofiles(struct kinfo_proc2 *p)
int i; int i;
struct filedesc filed; struct filedesc filed;
struct cwdinfo cwdi; struct cwdinfo cwdi;
struct fdtab dt;
Uname = user_from_uid(p->p_uid, 0); Uname = user_from_uid(p->p_uid, 0);
Pid = p->p_pid; Pid = p->p_pid;
@ -321,16 +322,20 @@ dofiles(struct kinfo_proc2 *p)
if (p->p_fd == 0 || p->p_cwdi == 0) if (p->p_fd == 0 || p->p_cwdi == 0)
return; return;
if (!KVM_READ(p->p_fd, &filed, sizeof (filed))) { if (!KVM_READ(p->p_fd, &filed, sizeof (filed))) {
warnx("can't read filedesc at %#llx for pid %d", (unsigned long long)p->p_fd, Pid); warnx("can't read filedesc at %p for pid %d", (void *)(uintptr_t)p->p_fd, Pid);
return; return;
} }
if (!KVM_READ(p->p_cwdi, &cwdi, sizeof(cwdi))) { if (!KVM_READ(p->p_cwdi, &cwdi, sizeof(cwdi))) {
warnx("can't read cwdinfo at %#llx for pid %d", (unsigned long long)p->p_cwdi, Pid); warnx("can't read cwdinfo at %p for pid %d", (void *)(uintptr_t)p->p_cwdi, Pid);
return; return;
} }
if (filed.fd_nfiles < 0 || filed.fd_lastfile >= filed.fd_nfiles || if (!KVM_READ(filed.fd_dt, &dt, sizeof(dt))) {
warnx("can't read dtab at %p for pid %d", filed.fd_dt, Pid);
return;
}
if ((unsigned)filed.fd_lastfile >= dt.dt_nfiles ||
filed.fd_freefile > filed.fd_lastfile + 1) { filed.fd_freefile > filed.fd_lastfile + 1) {
dprintf("filedesc corrupted at %#llx for pid %d", (unsigned long long)p->p_fd, Pid); dprintf("filedesc corrupted at %p for pid %d", (void *)(uintptr_t)p->p_fd, Pid);
return; return;
} }
/* /*
@ -355,10 +360,10 @@ dofiles(struct kinfo_proc2 *p)
*/ */
#define FPSIZE (sizeof (fdfile_t *)) #define FPSIZE (sizeof (fdfile_t *))
ALLOC_OFILES(filed.fd_lastfile+1); ALLOC_OFILES(filed.fd_lastfile+1);
if (!KVM_READ(filed.fd_ofiles, ofiles, if (!KVM_READ(&filed.fd_dt->dt_ff, ofiles,
(filed.fd_lastfile+1) * FPSIZE)) { (filed.fd_lastfile+1) * FPSIZE)) {
dprintf("can't read file structures at %p for pid %d", dprintf("can't read file structures at %p for pid %d",
filed.fd_ofiles, Pid); &filed.fd_dt->dt_ff, Pid);
return; return;
} }
for (i = 0; i <= filed.fd_lastfile; i++) { for (i = 0; i <= filed.fd_lastfile; i++) {