From 2931081a799ceb937789333135a02117c9e6f1ca Mon Sep 17 00:00:00 2001 From: pk Date: Sun, 23 Feb 2003 14:37:32 +0000 Subject: [PATCH] Make updating a file's reference and use count MP-safe. --- sys/compat/sunos/sunos_ioctl.c | 8 +++-- sys/compat/sunos/sunos_misc.c | 5 ++-- sys/compat/svr4/svr4_fcntl.c | 7 +++-- sys/compat/svr4/svr4_ioctl.c | 6 ++-- sys/compat/svr4/svr4_stream.c | 8 +++-- sys/kern/kern_descrip.c | 50 ++++++++++++++++++++++++++----- sys/kern/kern_event.c | 9 ++++-- sys/kern/kern_ktrace.c | 6 ++-- sys/kern/sys_generic.c | 20 +++++++++---- sys/kern/uipc_usrreq.c | 27 +++++++++++------ sys/kern/vfs_syscalls.c | 20 +++++++++---- sys/miscfs/fdesc/fdesc_vnops.c | 9 ++++-- sys/miscfs/portal/portal_vfsops.c | 10 +++++-- sys/sys/file.h | 13 +++++++- sys/uvm/uvm_mmap.c | 6 ++-- 15 files changed, 151 insertions(+), 53 deletions(-) diff --git a/sys/compat/sunos/sunos_ioctl.c b/sys/compat/sunos/sunos_ioctl.c index 29ffedc0e038..09aa662ad6bc 100644 --- a/sys/compat/sunos/sunos_ioctl.c +++ b/sys/compat/sunos/sunos_ioctl.c @@ -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 -__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; diff --git a/sys/compat/sunos/sunos_misc.c b/sys/compat/sunos/sunos_misc.c index 118d0e2c6a33..62119db538d0 100644 --- a/sys/compat/sunos/sunos_misc.c +++ b/sys/compat/sunos/sunos_misc.c @@ -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 -__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) diff --git a/sys/compat/svr4/svr4_fcntl.c b/sys/compat/svr4/svr4_fcntl.c index eb881d8e9f9d..d032c2245be0 100644 --- a/sys/compat/svr4/svr4_fcntl.c +++ b/sys/compat/svr4/svr4_fcntl.c @@ -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 -__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 #include @@ -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) diff --git a/sys/compat/svr4/svr4_ioctl.c b/sys/compat/svr4/svr4_ioctl.c index fd72d174feca..b4cbe33efff5 100644 --- a/sys/compat/svr4/svr4_ioctl.c +++ b/sys/compat/svr4/svr4_ioctl.c @@ -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 -__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 #include @@ -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; diff --git a/sys/compat/svr4/svr4_stream.c b/sys/compat/svr4/svr4_stream.c index 68bc0f2502ec..461f4809a8c2 100644 --- a/sys/compat/svr4/svr4_stream.c +++ b/sys/compat/svr4/svr4_stream.c @@ -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 -__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 #include @@ -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; diff --git a/sys/kern/kern_descrip.c b/sys/kern/kern_descrip.c index 35ad05195020..d6aaf8c83b95 100644 --- a/sys/kern/kern_descrip.c +++ b/sys/kern/kern_descrip.c @@ -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 -__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 #include @@ -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); diff --git a/sys/kern/kern_event.c b/sys/kern/kern_event.c index 8993de6023a4..f9cf91438b12 100644 --- a/sys/kern/kern_event.c +++ b/sys/kern/kern_event.c @@ -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 * 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) { diff --git a/sys/kern/kern_ktrace.c b/sys/kern/kern_ktrace.c index 064d5e744f71..962c43a4f545 100644 --- a/sys/kern/kern_ktrace.c +++ b/sys/kern/kern_ktrace.c @@ -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 -__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; diff --git a/sys/kern/sys_generic.c b/sys/kern/sys_generic.c index 5b20adc574c6..025655f49cf7 100644 --- a/sys/kern/sys_generic.c +++ b/sys/kern/sys_generic.c @@ -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 -__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); diff --git a/sys/kern/uipc_usrreq.c b/sys/kern/uipc_usrreq.c index 7865ee709fb9..b0cba689dfc9 100644 --- a/sys/kern/uipc_usrreq.c +++ b/sys/kern/uipc_usrreq.c @@ -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 -__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 #include @@ -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); } diff --git a/sys/kern/vfs_syscalls.c b/sys/kern/vfs_syscalls.c index 304d415dd6fc..7dc2399d691c 100644 --- a/sys/kern/vfs_syscalls.c +++ b/sys/kern/vfs_syscalls.c @@ -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 -__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); diff --git a/sys/miscfs/fdesc/fdesc_vnops.c b/sys/miscfs/fdesc/fdesc_vnops.c index d7fec03fafff..19a7472c8177 100644 --- a/sys/miscfs/fdesc/fdesc_vnops.c +++ b/sys/miscfs/fdesc/fdesc_vnops.c @@ -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 -__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 #include @@ -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); } diff --git a/sys/miscfs/portal/portal_vfsops.c b/sys/miscfs/portal/portal_vfsops.c index ef7e68b19cb7..4d72aec3b008 100644 --- a/sys/miscfs/portal/portal_vfsops.c +++ b/sys/miscfs/portal/portal_vfsops.c @@ -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 -__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); /* diff --git a/sys/sys/file.h b/sys/sys/file.h index dcb1560fcd92..3a68c1ee17a7 100644 --- a/sys/sys/file.h +++ b/sys/sys/file.h @@ -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) /* diff --git a/sys/uvm/uvm_mmap.c b/sys/uvm/uvm_mmap.c index 81f9d34620b9..cdfc855e912a 100644 --- a/sys/uvm/uvm_mmap.c +++ b/sys/uvm/uvm_mmap.c @@ -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 -__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 #include @@ -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 */