Make updating a file's reference and use count MP-safe.

This commit is contained in:
pk 2003-02-23 14:37:32 +00:00
parent 558032443d
commit 2931081a79
15 changed files with 151 additions and 53 deletions

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -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) {

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -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);
/*

View File

@ -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)
/*

View File

@ -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 */