Make updating a file's reference and use count MP-safe.
This commit is contained in:
parent
558032443d
commit
2931081a79
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: sunos_ioctl.c,v 1.43 2003/01/18 08:36:15 thorpej Exp $ */
|
||||
/* $NetBSD: sunos_ioctl.c,v 1.44 2003/02/23 14:37:32 pk Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1993 Markus Wild.
|
||||
|
@ -27,7 +27,7 @@
|
|||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: sunos_ioctl.c,v 1.43 2003/01/18 08:36:15 thorpej Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: sunos_ioctl.c,v 1.44 2003/02/23 14:37:32 pk Exp $");
|
||||
|
||||
#if defined(_KERNEL_OPT)
|
||||
#include "opt_execfmt.h"
|
||||
|
@ -422,8 +422,10 @@ sunos_sys_ioctl(l, v, retval)
|
|||
if ((fp = fd_getfile(fdp, SCARG(uap, fd))) == NULL)
|
||||
return EBADF;
|
||||
|
||||
if ((fp->f_flag & (FREAD|FWRITE)) == 0)
|
||||
if ((fp->f_flag & (FREAD|FWRITE)) == 0) {
|
||||
simple_unlock(&fp->f_slock);
|
||||
return EBADF;
|
||||
}
|
||||
|
||||
ctl = fp->f_ops->fo_ioctl;
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: sunos_misc.c,v 1.119 2003/01/29 07:00:37 atatat Exp $ */
|
||||
/* $NetBSD: sunos_misc.c,v 1.120 2003/02/23 14:37:32 pk Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1992, 1993
|
||||
|
@ -54,7 +54,7 @@
|
|||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: sunos_misc.c,v 1.119 2003/01/29 07:00:37 atatat Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: sunos_misc.c,v 1.120 2003/02/23 14:37:32 pk Exp $");
|
||||
|
||||
#if defined(_KERNEL_OPT)
|
||||
#include "opt_nfsserver.h"
|
||||
|
@ -877,6 +877,7 @@ sunos_sys_open(l, v, retval)
|
|||
struct file *fp;
|
||||
|
||||
fp = fd_getfile(fdp, *retval);
|
||||
simple_unlock(&fp->f_slock);
|
||||
|
||||
/* ignore any error, just give it a try */
|
||||
if (fp != NULL && fp->f_type == DTYPE_VNODE)
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: svr4_fcntl.c,v 1.42 2003/01/18 08:44:26 thorpej Exp $ */
|
||||
/* $NetBSD: svr4_fcntl.c,v 1.43 2003/02/23 14:37:33 pk Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1994, 1997 The NetBSD Foundation, Inc.
|
||||
|
@ -37,7 +37,7 @@
|
|||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: svr4_fcntl.c,v 1.42 2003/01/18 08:44:26 thorpej Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: svr4_fcntl.c,v 1.43 2003/02/23 14:37:33 pk Exp $");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
|
@ -273,6 +273,7 @@ fd_revoke(l, fd, retval)
|
|||
if ((fp = fd_getfile(fdp, fd)) == NULL)
|
||||
return EBADF;
|
||||
|
||||
simple_unlock(&fp->f_slock);
|
||||
if (fp->f_type != DTYPE_VNODE)
|
||||
return EINVAL;
|
||||
|
||||
|
@ -320,6 +321,7 @@ fd_truncate(l, fd, flp, retval)
|
|||
if ((fp = fd_getfile(fdp, fd)) == NULL)
|
||||
return EBADF;
|
||||
|
||||
simple_unlock(&fp->f_slock);
|
||||
vp = (struct vnode *)fp->f_data;
|
||||
if (fp->f_type != DTYPE_VNODE || vp->v_type == VFIFO)
|
||||
return ESPIPE;
|
||||
|
@ -391,6 +393,7 @@ svr4_sys_open(l, v, retval)
|
|||
struct file *fp;
|
||||
|
||||
fp = fd_getfile(fdp, *retval);
|
||||
simple_unlock(&fp->f_slock);
|
||||
|
||||
/* ignore any error, just give it a try */
|
||||
if (fp != NULL && fp->f_type == DTYPE_VNODE)
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: svr4_ioctl.c,v 1.23 2003/01/18 08:44:26 thorpej Exp $ */
|
||||
/* $NetBSD: svr4_ioctl.c,v 1.24 2003/02/23 14:37:33 pk Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1994 The NetBSD Foundation, Inc.
|
||||
|
@ -37,7 +37,7 @@
|
|||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: svr4_ioctl.c,v 1.23 2003/01/18 08:44:26 thorpej Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: svr4_ioctl.c,v 1.24 2003/02/23 14:37:33 pk Exp $");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/proc.h>
|
||||
|
@ -127,6 +127,8 @@ svr4_sys_ioctl(l, v, retval)
|
|||
if ((fp = fd_getfile(fdp, SCARG(uap, fd))) == NULL)
|
||||
return EBADF;
|
||||
|
||||
simple_unlock(&fp->f_slock);
|
||||
|
||||
if ((fp->f_flag & (FREAD | FWRITE)) == 0)
|
||||
return EBADF;
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: svr4_stream.c,v 1.49 2003/01/18 08:44:27 thorpej Exp $ */
|
||||
/* $NetBSD: svr4_stream.c,v 1.50 2003/02/23 14:37:33 pk Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1994 The NetBSD Foundation, Inc.
|
||||
|
@ -44,7 +44,7 @@
|
|||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: svr4_stream.c,v 1.49 2003/01/18 08:44:27 thorpej Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: svr4_stream.c,v 1.50 2003/02/23 14:37:33 pk Exp $");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/kernel.h>
|
||||
|
@ -1524,6 +1524,8 @@ svr4_sys_putmsg(l, v, retval)
|
|||
if ((fp = fd_getfile(fdp, SCARG(uap, fd))) == NULL)
|
||||
return EBADF;
|
||||
|
||||
simple_unlock(&fp->f_slock);
|
||||
|
||||
if (SCARG(uap, ctl) != NULL) {
|
||||
if ((error = copyin(SCARG(uap, ctl), &ctl, sizeof(ctl))) != 0)
|
||||
return error;
|
||||
|
@ -1696,6 +1698,8 @@ svr4_sys_getmsg(l, v, retval)
|
|||
if ((fp = fd_getfile(fdp, SCARG(uap, fd))) == NULL)
|
||||
return EBADF;
|
||||
|
||||
simple_unlock(&fp->f_slock);
|
||||
|
||||
if (SCARG(uap, ctl) != NULL) {
|
||||
if ((error = copyin(SCARG(uap, ctl), &ctl, sizeof(ctl))) != 0)
|
||||
return error;
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: kern_descrip.c,v 1.102 2003/02/14 21:50:10 pk Exp $ */
|
||||
/* $NetBSD: kern_descrip.c,v 1.103 2003/02/23 14:37:33 pk Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1982, 1986, 1989, 1991, 1993
|
||||
|
@ -41,7 +41,7 @@
|
|||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: kern_descrip.c,v 1.102 2003/02/14 21:50:10 pk Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: kern_descrip.c,v 1.103 2003/02/23 14:37:33 pk Exp $");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
|
@ -122,6 +122,14 @@ fd_unused(struct filedesc *fdp, int fd)
|
|||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Lookup the file structure corresponding to a file descriptor
|
||||
* and return it locked.
|
||||
* Note: typical usage is: `fp = fd_getfile(..); FILE_USE(fp);'
|
||||
* The locking strategy has been optimised for this case, i.e.
|
||||
* fd_getfile() returns the file locked while FILE_USE() will increment
|
||||
* the file's use count and unlock.
|
||||
*/
|
||||
struct file *
|
||||
fd_getfile(struct filedesc *fdp, int fd)
|
||||
{
|
||||
|
@ -130,8 +138,11 @@ fd_getfile(struct filedesc *fdp, int fd)
|
|||
if ((u_int) fd >= fdp->fd_nfiles || (fp = fdp->fd_ofiles[fd]) == NULL)
|
||||
return (NULL);
|
||||
|
||||
if (FILE_IS_USABLE(fp) == 0)
|
||||
simple_lock(&fp->f_slock);
|
||||
if (FILE_IS_USABLE(fp) == 0) {
|
||||
simple_unlock(&fp->f_slock);
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
return (fp);
|
||||
}
|
||||
|
@ -205,10 +216,13 @@ sys_dup2(struct lwp *l, void *v, register_t *retval)
|
|||
return (EBADF);
|
||||
|
||||
if ((u_int)new >= p->p_rlimit[RLIMIT_NOFILE].rlim_cur ||
|
||||
(u_int)new >= maxfiles)
|
||||
(u_int)new >= maxfiles) {
|
||||
simple_unlock(&fp->f_slock);
|
||||
return (EBADF);
|
||||
}
|
||||
|
||||
if (old == new) {
|
||||
simple_unlock(&fp->f_slock);
|
||||
*retval = new;
|
||||
return (0);
|
||||
}
|
||||
|
@ -477,6 +491,7 @@ finishdup(struct proc *p, int old, int new, register_t *retval)
|
|||
FILE_UNUSE(fp, p);
|
||||
|
||||
if (delfp != NULL) {
|
||||
simple_lock(&delfp->f_slock);
|
||||
FILE_USE(delfp);
|
||||
if (new < fdp->fd_knlistsize)
|
||||
knote_fdclose(p, new);
|
||||
|
@ -505,6 +520,12 @@ fdrelease(struct proc *p, int fd)
|
|||
if (fp == NULL)
|
||||
return (EBADF);
|
||||
|
||||
simple_lock(&fp->f_slock);
|
||||
if (!FILE_IS_USABLE(fp)) {
|
||||
simple_unlock(&fp->f_slock);
|
||||
return (EBADF);
|
||||
}
|
||||
|
||||
FILE_USE(fp);
|
||||
|
||||
*fpp = NULL;
|
||||
|
@ -533,8 +554,12 @@ sys_close(struct lwp *l, void *v, register_t *retval)
|
|||
fd = SCARG(uap, fd);
|
||||
fdp = p->p_fd;
|
||||
|
||||
if ((u_int) fd >= fdp->fd_nfiles)
|
||||
return (NULL);
|
||||
#if 0
|
||||
if (fd_getfile(fdp, fd) == NULL)
|
||||
return (EBADF);
|
||||
#endif
|
||||
|
||||
return (fdrelease(p, fd));
|
||||
}
|
||||
|
@ -785,11 +810,12 @@ falloc(struct proc *p, struct file **resultfp, int *resultfd)
|
|||
}
|
||||
simple_unlock(&filelist_slock);
|
||||
p->p_fd->fd_ofiles[i] = fp;
|
||||
simple_lock_init(&fp->f_slock);
|
||||
fp->f_count = 1;
|
||||
fp->f_cred = p->p_ucred;
|
||||
crhold(fp->f_cred);
|
||||
if (resultfp) {
|
||||
FILE_USE(fp);
|
||||
fp->f_usecount = 1;
|
||||
*resultfp = fp;
|
||||
}
|
||||
if (resultfd)
|
||||
|
@ -813,7 +839,7 @@ ffree(struct file *fp)
|
|||
LIST_REMOVE(fp, f_list);
|
||||
crfree(fp->f_cred);
|
||||
#ifdef DIAGNOSTIC
|
||||
fp->f_count = 0;
|
||||
fp->f_count = 0; /* What's the point? */
|
||||
#endif
|
||||
nfiles--;
|
||||
simple_unlock(&filelist_slock);
|
||||
|
@ -1043,6 +1069,7 @@ fdfree(struct proc *p)
|
|||
fp = *fpp;
|
||||
if (fp != NULL) {
|
||||
*fpp = NULL;
|
||||
simple_lock(&fp->f_slock);
|
||||
FILE_USE(fp);
|
||||
if (i < fdp->fd_knlistsize)
|
||||
knote_fdclose(p, fdp->fd_lastfile - i);
|
||||
|
@ -1101,6 +1128,7 @@ closef(struct file *fp, struct proc *p)
|
|||
* happen if a filedesc structure is shared by multiple
|
||||
* processes.
|
||||
*/
|
||||
simple_lock(&fp->f_slock);
|
||||
if (fp->f_iflags & FIF_WANTCLOSE) {
|
||||
/*
|
||||
* Another user of the file is already closing, and is
|
||||
|
@ -1116,6 +1144,7 @@ closef(struct file *fp, struct proc *p)
|
|||
#endif
|
||||
if (--fp->f_usecount == 1)
|
||||
wakeup(&fp->f_usecount);
|
||||
simple_unlock(&fp->f_slock);
|
||||
return (0);
|
||||
} else {
|
||||
/*
|
||||
|
@ -1129,6 +1158,7 @@ closef(struct file *fp, struct proc *p)
|
|||
panic("closef: no wantclose and usecount < 1");
|
||||
#endif
|
||||
fp->f_usecount--;
|
||||
simple_unlock(&fp->f_slock);
|
||||
return (0);
|
||||
}
|
||||
}
|
||||
|
@ -1156,12 +1186,14 @@ closef(struct file *fp, struct proc *p)
|
|||
panic("closef: usecount < 1");
|
||||
#endif
|
||||
while (fp->f_usecount > 1)
|
||||
(void) tsleep(&fp->f_usecount, PRIBIO, "closef", 0);
|
||||
(void) ltsleep(&fp->f_usecount, PRIBIO, "closef", 0,
|
||||
&fp->f_slock);
|
||||
#ifdef DIAGNOSTIC
|
||||
if (fp->f_usecount != 1)
|
||||
panic("closef: usecount != 1");
|
||||
#endif
|
||||
|
||||
simple_unlock(&fp->f_slock);
|
||||
if ((fp->f_flag & FHASLOCK) && fp->f_type == DTYPE_VNODE) {
|
||||
lf.l_whence = SEEK_SET;
|
||||
lf.l_start = 0;
|
||||
|
@ -1295,8 +1327,10 @@ dupfdopen(struct proc *p, int indx, int dfd, int mode, int error)
|
|||
if ((wfp = fd_getfile(fdp, dfd)) == NULL)
|
||||
return (EBADF);
|
||||
|
||||
if (fp == wfp)
|
||||
if (fp == wfp) {
|
||||
simple_unlock(&fp->f_slock);
|
||||
return (EBADF);
|
||||
}
|
||||
|
||||
FILE_USE(wfp);
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: kern_event.c,v 1.9 2003/02/21 20:57:09 jdolecek Exp $ */
|
||||
/* $NetBSD: kern_event.c,v 1.10 2003/02/23 14:37:34 pk Exp $ */
|
||||
/*-
|
||||
* Copyright (c) 1999,2000,2001 Jonathan Lemon <jlemon@FreeBSD.org>
|
||||
* All rights reserved.
|
||||
|
@ -662,9 +662,14 @@ sys_kevent(struct lwp *l, void *v, register_t *retval)
|
|||
p = l->l_proc;
|
||||
/* check that we're dealing with a kq */
|
||||
fp = fd_getfile(p->p_fd, SCARG(uap, fd));
|
||||
if (!fp || fp->f_type != DTYPE_KQUEUE)
|
||||
if (fp == NULL)
|
||||
return (EBADF);
|
||||
|
||||
if (fp->f_type != DTYPE_KQUEUE) {
|
||||
simple_unlock(&fp->f_slock);
|
||||
return (EBADF);
|
||||
}
|
||||
|
||||
FILE_USE(fp);
|
||||
|
||||
if (SCARG(uap, timeout) != NULL) {
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: kern_ktrace.c,v 1.67 2003/01/18 10:06:27 thorpej Exp $ */
|
||||
/* $NetBSD: kern_ktrace.c,v 1.68 2003/02/23 14:37:34 pk Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1989, 1993
|
||||
|
@ -36,7 +36,7 @@
|
|||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: kern_ktrace.c,v 1.67 2003/01/18 10:06:27 thorpej Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: kern_ktrace.c,v 1.68 2003/02/23 14:37:34 pk Exp $");
|
||||
|
||||
#include "opt_ktrace.h"
|
||||
#include "opt_compat_mach.h"
|
||||
|
@ -93,6 +93,7 @@ ktrderef(p)
|
|||
p->p_traceflag = 0;
|
||||
if (fp == NULL)
|
||||
return;
|
||||
simple_lock(&fp->f_slock);
|
||||
FILE_USE(fp);
|
||||
|
||||
/*
|
||||
|
@ -692,6 +693,7 @@ ktrwrite(p, kth)
|
|||
auio.uio_resid += kth->ktr_len;
|
||||
}
|
||||
|
||||
simple_lock(&fp->f_slock);
|
||||
FILE_USE(fp);
|
||||
|
||||
tries = 0;
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: sys_generic.c,v 1.69 2003/01/18 10:06:33 thorpej Exp $ */
|
||||
/* $NetBSD: sys_generic.c,v 1.70 2003/02/23 14:37:34 pk Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1982, 1986, 1989, 1993
|
||||
|
@ -41,7 +41,7 @@
|
|||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: sys_generic.c,v 1.69 2003/01/18 10:06:33 thorpej Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: sys_generic.c,v 1.70 2003/02/23 14:37:34 pk Exp $");
|
||||
|
||||
#include "opt_ktrace.h"
|
||||
|
||||
|
@ -93,8 +93,10 @@ sys_read(struct lwp *l, void *v, register_t *retval)
|
|||
if ((fp = fd_getfile(fdp, fd)) == NULL)
|
||||
return (EBADF);
|
||||
|
||||
if ((fp->f_flag & FREAD) == 0)
|
||||
if ((fp->f_flag & FREAD) == 0) {
|
||||
simple_unlock(&fp->f_slock);
|
||||
return (EBADF);
|
||||
}
|
||||
|
||||
FILE_USE(fp);
|
||||
|
||||
|
@ -182,8 +184,10 @@ sys_readv(struct lwp *l, void *v, register_t *retval)
|
|||
if ((fp = fd_getfile(fdp, fd)) == NULL)
|
||||
return (EBADF);
|
||||
|
||||
if ((fp->f_flag & FREAD) == 0)
|
||||
if ((fp->f_flag & FREAD) == 0) {
|
||||
simple_unlock(&fp->f_slock);
|
||||
return (EBADF);
|
||||
}
|
||||
|
||||
FILE_USE(fp);
|
||||
|
||||
|
@ -303,8 +307,10 @@ sys_write(struct lwp *l, void *v, register_t *retval)
|
|||
if ((fp = fd_getfile(fdp, fd)) == NULL)
|
||||
return (EBADF);
|
||||
|
||||
if ((fp->f_flag & FWRITE) == 0)
|
||||
if ((fp->f_flag & FWRITE) == 0) {
|
||||
simple_unlock(&fp->f_slock);
|
||||
return (EBADF);
|
||||
}
|
||||
|
||||
FILE_USE(fp);
|
||||
|
||||
|
@ -395,8 +401,10 @@ sys_writev(struct lwp *l, void *v, register_t *retval)
|
|||
if ((fp = fd_getfile(fdp, fd)) == NULL)
|
||||
return (EBADF);
|
||||
|
||||
if ((fp->f_flag & FWRITE) == 0)
|
||||
if ((fp->f_flag & FWRITE) == 0) {
|
||||
simple_unlock(&fp->f_slock);
|
||||
return (EBADF);
|
||||
}
|
||||
|
||||
FILE_USE(fp);
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: uipc_usrreq.c,v 1.56 2002/11/25 08:32:00 itojun Exp $ */
|
||||
/* $NetBSD: uipc_usrreq.c,v 1.57 2003/02/23 14:37:34 pk Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1998, 2000 The NetBSD Foundation, Inc.
|
||||
|
@ -74,7 +74,7 @@
|
|||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: uipc_usrreq.c,v 1.56 2002/11/25 08:32:00 itojun Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: uipc_usrreq.c,v 1.57 2003/02/23 14:37:34 pk Exp $");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
|
@ -973,11 +973,15 @@ unp_internalize(control, p)
|
|||
rp = ((struct file **)CMSG_DATA(cm)) + nfds - 1;
|
||||
for (i = 0; i < nfds; i++) {
|
||||
fp = fdescp->fd_ofiles[*fdp--];
|
||||
FILE_USE(fp);
|
||||
simple_lock(&fp->f_slock);
|
||||
#ifdef DIAGNOSTIC
|
||||
if (fp->f_iflags & FIF_WANTCLOSE)
|
||||
panic("unp_internalize: file already closed");
|
||||
#endif
|
||||
*rp-- = fp;
|
||||
fp->f_count++;
|
||||
fp->f_msgcount++;
|
||||
FILE_UNUSE(fp, NULL);
|
||||
simple_unlock(&fp->f_slock);
|
||||
unp_rights++;
|
||||
}
|
||||
return (0);
|
||||
|
@ -1150,7 +1154,7 @@ unp_gc()
|
|||
* that are not otherwise accessible and then free the rights
|
||||
* that are stored in messages on them.
|
||||
*
|
||||
* The bug in the orginal code is a little tricky, so I'll describe
|
||||
* The bug in the original code is a little tricky, so I'll describe
|
||||
* what's wrong with it here.
|
||||
*
|
||||
* It is incorrect to simply unp_discard each entry for f_msgcount
|
||||
|
@ -1189,16 +1193,18 @@ unp_gc()
|
|||
for (nunref = 0, fp = LIST_FIRST(&filehead), fpp = extra_ref; fp != 0;
|
||||
fp = nextfp) {
|
||||
nextfp = LIST_NEXT(fp, f_list);
|
||||
if (fp->f_count == 0)
|
||||
continue;
|
||||
if (fp->f_count == fp->f_msgcount && !(fp->f_flag & FMARK)) {
|
||||
simple_lock(&fp->f_slock);
|
||||
if (fp->f_count != 0 &&
|
||||
fp->f_count == fp->f_msgcount && !(fp->f_flag & FMARK)) {
|
||||
*fpp++ = fp;
|
||||
nunref++;
|
||||
fp->f_count++;
|
||||
}
|
||||
simple_unlock(&fp->f_slock);
|
||||
}
|
||||
for (i = nunref, fpp = extra_ref; --i >= 0; ++fpp) {
|
||||
fp = *fpp;
|
||||
simple_lock(&fp->f_slock);
|
||||
FILE_USE(fp);
|
||||
if (fp->f_type == DTYPE_SOCKET)
|
||||
sorflush((struct socket *)fp->f_data);
|
||||
|
@ -1206,6 +1212,7 @@ unp_gc()
|
|||
}
|
||||
for (i = nunref, fpp = extra_ref; --i >= 0; ++fpp) {
|
||||
fp = *fpp;
|
||||
simple_lock(&fp->f_slock);
|
||||
FILE_USE(fp);
|
||||
(void) closef(fp, (struct proc *)0);
|
||||
}
|
||||
|
@ -1296,8 +1303,10 @@ unp_discard(fp)
|
|||
{
|
||||
if (fp == NULL)
|
||||
return;
|
||||
FILE_USE(fp);
|
||||
simple_lock(&fp->f_slock);
|
||||
fp->f_usecount++; /* i.e. FILE_USE(fp) sans locking */
|
||||
fp->f_msgcount--;
|
||||
simple_unlock(&fp->f_slock);
|
||||
unp_rights--;
|
||||
(void) closef(fp, (struct proc *)0);
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: vfs_syscalls.c,v 1.182 2003/02/14 18:25:34 drochner Exp $ */
|
||||
/* $NetBSD: vfs_syscalls.c,v 1.183 2003/02/23 14:37:34 pk Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1989, 1993
|
||||
|
@ -41,7 +41,7 @@
|
|||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: vfs_syscalls.c,v 1.182 2003/02/14 18:25:34 drochner Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: vfs_syscalls.c,v 1.183 2003/02/23 14:37:34 pk Exp $");
|
||||
|
||||
#include "opt_compat_netbsd.h"
|
||||
#include "opt_compat_43.h"
|
||||
|
@ -1726,8 +1726,10 @@ sys_pread(l, v, retval)
|
|||
if ((fp = fd_getfile(fdp, fd)) == NULL)
|
||||
return (EBADF);
|
||||
|
||||
if ((fp->f_flag & FREAD) == 0)
|
||||
if ((fp->f_flag & FREAD) == 0) {
|
||||
simple_unlock(&fp->f_slock);
|
||||
return (EBADF);
|
||||
}
|
||||
|
||||
FILE_USE(fp);
|
||||
|
||||
|
@ -1780,8 +1782,10 @@ sys_preadv(l, v, retval)
|
|||
if ((fp = fd_getfile(fdp, fd)) == NULL)
|
||||
return (EBADF);
|
||||
|
||||
if ((fp->f_flag & FREAD) == 0)
|
||||
if ((fp->f_flag & FREAD) == 0) {
|
||||
simple_unlock(&fp->f_slock);
|
||||
return (EBADF);
|
||||
}
|
||||
|
||||
FILE_USE(fp);
|
||||
|
||||
|
@ -1834,8 +1838,10 @@ sys_pwrite(l, v, retval)
|
|||
if ((fp = fd_getfile(fdp, fd)) == NULL)
|
||||
return (EBADF);
|
||||
|
||||
if ((fp->f_flag & FWRITE) == 0)
|
||||
if ((fp->f_flag & FWRITE) == 0) {
|
||||
simple_unlock(&fp->f_slock);
|
||||
return (EBADF);
|
||||
}
|
||||
|
||||
FILE_USE(fp);
|
||||
|
||||
|
@ -1888,8 +1894,10 @@ sys_pwritev(l, v, retval)
|
|||
if ((fp = fd_getfile(fdp, fd)) == NULL)
|
||||
return (EBADF);
|
||||
|
||||
if ((fp->f_flag & FWRITE) == 0)
|
||||
if ((fp->f_flag & FWRITE) == 0) {
|
||||
simple_unlock(&fp->f_slock);
|
||||
return (EBADF);
|
||||
}
|
||||
|
||||
FILE_USE(fp);
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: fdesc_vnops.c,v 1.72 2003/02/23 04:25:59 simonb Exp $ */
|
||||
/* $NetBSD: fdesc_vnops.c,v 1.73 2003/02/23 14:37:35 pk Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1992, 1993
|
||||
|
@ -45,7 +45,7 @@
|
|||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: fdesc_vnops.c,v 1.72 2003/02/23 04:25:59 simonb Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: fdesc_vnops.c,v 1.73 2003/02/23 14:37:35 pk Exp $");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
|
@ -484,6 +484,7 @@ fdesc_attr(fd, vap, cred, p)
|
|||
|
||||
switch (fp->f_type) {
|
||||
case DTYPE_VNODE:
|
||||
simple_unlock(&fp->f_slock);
|
||||
error = VOP_GETATTR((struct vnode *) fp->f_data, vap, cred, p);
|
||||
if (error == 0 && vap->va_type == VDIR) {
|
||||
/*
|
||||
|
@ -628,6 +629,7 @@ fdesc_setattr(v)
|
|||
struct proc *a_p;
|
||||
} */ *ap = v;
|
||||
struct filedesc *fdp = ap->a_p->p_fd;
|
||||
struct file *fp;
|
||||
unsigned fd;
|
||||
|
||||
/*
|
||||
|
@ -645,7 +647,7 @@ fdesc_setattr(v)
|
|||
}
|
||||
|
||||
fd = VTOFDESC(ap->a_vp)->fd_fd;
|
||||
if (fd_getfile(fdp, fd) == NULL)
|
||||
if ((fp = fd_getfile(fdp, fd)) == NULL)
|
||||
return (EBADF);
|
||||
|
||||
/*
|
||||
|
@ -653,6 +655,7 @@ fdesc_setattr(v)
|
|||
* On vnode's this will cause truncation and socket/pipes make
|
||||
* no sense.
|
||||
*/
|
||||
simple_unlock(&fp->f_slock);
|
||||
return (0);
|
||||
}
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: portal_vfsops.c,v 1.31 2002/09/21 18:09:30 christos Exp $ */
|
||||
/* $NetBSD: portal_vfsops.c,v 1.32 2003/02/23 14:37:37 pk Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1992, 1993, 1995
|
||||
|
@ -44,7 +44,7 @@
|
|||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: portal_vfsops.c,v 1.31 2002/09/21 18:09:30 christos Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: portal_vfsops.c,v 1.32 2003/02/23 14:37:37 pk Exp $");
|
||||
|
||||
#if defined(_KERNEL_OPT)
|
||||
#include "opt_compat_netbsd.h"
|
||||
|
@ -156,7 +156,10 @@ portal_mount(mp, path, data, ndp, p)
|
|||
VTOPORTAL(rvp)->pt_size = 0;
|
||||
VTOPORTAL(rvp)->pt_fileid = PORTAL_ROOTFILEID;
|
||||
fmp->pm_root = rvp;
|
||||
fmp->pm_server = fp; fp->f_count++;
|
||||
fmp->pm_server = fp;
|
||||
simple_lock(&fp->f_slock);
|
||||
fp->f_count++;
|
||||
simple_unlock(&fp->f_slock);
|
||||
|
||||
mp->mnt_flag |= MNT_LOCAL;
|
||||
mp->mnt_data = fmp;
|
||||
|
@ -220,6 +223,7 @@ portal_unmount(mp, mntflags, p)
|
|||
* daemon to wake up, and then the accept will get ECONNABORTED
|
||||
* which it interprets as a request to go and bury itself.
|
||||
*/
|
||||
simple_lock(&VFSTOPORTAL(mp)->pm_server->f_slock);
|
||||
FILE_USE(VFSTOPORTAL(mp)->pm_server);
|
||||
soshutdown((struct socket *) VFSTOPORTAL(mp)->pm_server->f_data, 2);
|
||||
/*
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: file.h,v 1.35 2003/02/01 06:23:50 thorpej Exp $ */
|
||||
/* $NetBSD: file.h,v 1.36 2003/02/23 14:37:38 pk Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1982, 1986, 1989, 1993
|
||||
|
@ -92,6 +92,7 @@ struct file {
|
|||
} *f_ops;
|
||||
off_t f_offset;
|
||||
caddr_t f_data; /* descriptor data, e.g. vnode/socket */
|
||||
struct simplelock f_slock;
|
||||
};
|
||||
|
||||
#define FIF_WANTCLOSE 0x01 /* a close is waiting for usecount */
|
||||
|
@ -115,21 +116,31 @@ do { \
|
|||
#define FILE_USE_CHECK(fp, str) /* nothing */
|
||||
#endif
|
||||
|
||||
/*
|
||||
* FILE_USE() must be called with the file lock held.
|
||||
* (Typical usage is: `fp = fd_getfile(..); FILE_USE(fp);'
|
||||
* and fd_getfile() returns the file locked)
|
||||
*/
|
||||
#define FILE_USE(fp) \
|
||||
do { \
|
||||
(fp)->f_usecount++; \
|
||||
FILE_USE_CHECK((fp), "f_usecount overflow"); \
|
||||
simple_unlock(&(fp)->f_slock); \
|
||||
} while (/* CONSTCOND */ 0)
|
||||
|
||||
#define FILE_UNUSE(fp, p) \
|
||||
do { \
|
||||
simple_lock(&(fp)->f_slock); \
|
||||
if ((fp)->f_iflags & FIF_WANTCLOSE) { \
|
||||
simple_unlock(&(fp)->f_slock); \
|
||||
/* Will drop usecount */ \
|
||||
(void) closef((fp), (p)); \
|
||||
break; \
|
||||
} else { \
|
||||
(fp)->f_usecount--; \
|
||||
FILE_USE_CHECK((fp), "f_usecount underflow"); \
|
||||
} \
|
||||
simple_unlock(&(fp)->f_slock); \
|
||||
} while (/* CONSTCOND */ 0)
|
||||
|
||||
/*
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: uvm_mmap.c,v 1.68 2003/02/20 22:16:08 atatat Exp $ */
|
||||
/* $NetBSD: uvm_mmap.c,v 1.69 2003/02/23 14:37:38 pk Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1997 Charles D. Cranor and Washington University.
|
||||
|
@ -51,7 +51,7 @@
|
|||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: uvm_mmap.c,v 1.68 2003/02/20 22:16:08 atatat Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: uvm_mmap.c,v 1.69 2003/02/23 14:37:38 pk Exp $");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
|
@ -376,6 +376,8 @@ sys_mmap(l, v, retval)
|
|||
if ((fp = fd_getfile(fdp, fd)) == NULL)
|
||||
return (EBADF);
|
||||
|
||||
simple_unlock(&fp->f_slock);
|
||||
|
||||
if (fp->f_type != DTYPE_VNODE)
|
||||
return (ENODEV); /* only mmap vnodes! */
|
||||
vp = (struct vnode *)fp->f_data; /* convert to vnode */
|
||||
|
|
Loading…
Reference in New Issue